Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(500)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/network/NetworkLogView.js

Issue 2466123002: DevTools: reformat front-end code to match chromium style. (Closed)
Patch Set: all done Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org> 3 * Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org>
4 * Copyright (C) 2011 Google Inc. All rights reserved. 4 * Copyright (C) 2011 Google Inc. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 9 *
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 15 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
16 * its contributors may be used to endorse or promote products derived 16 * its contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission. 17 * from this software without specific prior written permission.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30
31 /** 30 /**
32 * @constructor
33 * @extends {WebInspector.VBox}
34 * @implements {WebInspector.Searchable} 31 * @implements {WebInspector.Searchable}
35 * @implements {WebInspector.TargetManager.Observer} 32 * @implements {WebInspector.TargetManager.Observer}
36 * @param {!WebInspector.FilterBar} filterBar 33 * @unrestricted
37 * @param {!Element} progressBarContainer
38 * @param {!WebInspector.Setting} networkLogLargeRowsSetting
39 */ 34 */
40 WebInspector.NetworkLogView = function(filterBar, progressBarContainer, networkL ogLargeRowsSetting) 35 WebInspector.NetworkLogView = class extends WebInspector.VBox {
41 { 36 /**
42 WebInspector.VBox.call(this); 37 * @param {!WebInspector.FilterBar} filterBar
38 * @param {!Element} progressBarContainer
39 * @param {!WebInspector.Setting} networkLogLargeRowsSetting
40 */
41 constructor(filterBar, progressBarContainer, networkLogLargeRowsSetting) {
42 super();
43 this.setMinimumSize(50, 64); 43 this.setMinimumSize(50, 64);
44 this.registerRequiredCSS("network/networkLogView.css"); 44 this.registerRequiredCSS('network/networkLogView.css');
45 45
46 this._networkHideDataURLSetting = WebInspector.settings.createSetting("netwo rkHideDataURL", false); 46 this._networkHideDataURLSetting = WebInspector.settings.createSetting('netwo rkHideDataURL', false);
47 this._networkResourceTypeFiltersSetting = WebInspector.settings.createSettin g("networkResourceTypeFilters", {}); 47 this._networkResourceTypeFiltersSetting = WebInspector.settings.createSettin g('networkResourceTypeFilters', {});
48 this._networkShowPrimaryLoadWaterfallSetting = WebInspector.settings.createS etting("networkShowPrimaryLoadWaterfall", false); 48 this._networkShowPrimaryLoadWaterfallSetting =
49 WebInspector.settings.createSetting('networkShowPrimaryLoadWaterfall', f alse);
49 50
50 this._filterBar = filterBar; 51 this._filterBar = filterBar;
51 this._progressBarContainer = progressBarContainer; 52 this._progressBarContainer = progressBarContainer;
52 this._networkLogLargeRowsSetting = networkLogLargeRowsSetting; 53 this._networkLogLargeRowsSetting = networkLogLargeRowsSetting;
53 this._networkLogLargeRowsSetting.addChangeListener(updateRowHeight.bind(this ), this); 54 this._networkLogLargeRowsSetting.addChangeListener(updateRowHeight.bind(this ), this);
54 55
55 /** @type {!WebInspector.NetworkTransferTimeCalculator} */ 56 /** @type {!WebInspector.NetworkTransferTimeCalculator} */
56 this._timeCalculator = new WebInspector.NetworkTransferTimeCalculator(); 57 this._timeCalculator = new WebInspector.NetworkTransferTimeCalculator();
57 /** @type {!WebInspector.NetworkTransferDurationCalculator} */ 58 /** @type {!WebInspector.NetworkTransferDurationCalculator} */
58 this._durationCalculator = new WebInspector.NetworkTransferDurationCalculato r(); 59 this._durationCalculator = new WebInspector.NetworkTransferDurationCalculato r();
59 this._calculator = this._timeCalculator; 60 this._calculator = this._timeCalculator;
60 61
61 /** 62 /**
62 * @this {WebInspector.NetworkLogView} 63 * @this {WebInspector.NetworkLogView}
63 */ 64 */
64 function updateRowHeight() 65 function updateRowHeight() {
65 { 66 /** @type {number} */
66 /** @type {number} */ 67 this._rowHeight = !!this._networkLogLargeRowsSetting.get() ? 41 : 21;
67 this._rowHeight = !!this._networkLogLargeRowsSetting.get() ? 41 : 21;
68 } 68 }
69 updateRowHeight.call(this); 69 updateRowHeight.call(this);
70 70
71 this._columns = new WebInspector.NetworkLogViewColumns(this, this._timeCalcu lator, this._durationCalculator, networkLogLargeRowsSetting); 71 this._columns = new WebInspector.NetworkLogViewColumns(
72 this, this._timeCalculator, this._durationCalculator, networkLogLargeRow sSetting);
72 73
73 /** @type {!Map.<string, !WebInspector.NetworkDataGridNode>} */ 74 /** @type {!Map.<string, !WebInspector.NetworkDataGridNode>} */
74 this._nodesByRequestId = new Map(); 75 this._nodesByRequestId = new Map();
75 /** @type {!Object.<string, boolean>} */ 76 /** @type {!Object.<string, boolean>} */
76 this._staleRequestIds = {}; 77 this._staleRequestIds = {};
77 /** @type {number} */ 78 /** @type {number} */
78 this._mainRequestLoadTime = -1; 79 this._mainRequestLoadTime = -1;
79 /** @type {number} */ 80 /** @type {number} */
80 this._mainRequestDOMContentLoadedTime = -1; 81 this._mainRequestDOMContentLoadedTime = -1;
81 this._matchedRequestCount = 0; 82 this._matchedRequestCount = 0;
(...skipping 12 matching lines...) Expand all
94 95
95 this._recording = false; 96 this._recording = false;
96 this._preserveLog = false; 97 this._preserveLog = false;
97 98
98 this._headerHeight = 0; 99 this._headerHeight = 0;
99 100
100 this._addFilters(); 101 this._addFilters();
101 this._resetSuggestionBuilder(); 102 this._resetSuggestionBuilder();
102 this._initializeView(); 103 this._initializeView();
103 104
104 WebInspector.moduleSetting("networkColorCodeResourceTypes").addChangeListene r(this._invalidateAllItems, this); 105 WebInspector.moduleSetting('networkColorCodeResourceTypes').addChangeListene r(this._invalidateAllItems, this);
105 106
106 WebInspector.targetManager.observeTargets(this); 107 WebInspector.targetManager.observeTargets(this);
107 WebInspector.targetManager.addModelListener(WebInspector.NetworkManager, Web Inspector.NetworkManager.Events.RequestStarted, this._onRequestStarted, this); 108 WebInspector.targetManager.addModelListener(
108 WebInspector.targetManager.addModelListener(WebInspector.NetworkManager, Web Inspector.NetworkManager.Events.RequestUpdated, this._onRequestUpdated, this); 109 WebInspector.NetworkManager, WebInspector.NetworkManager.Events.RequestS tarted, this._onRequestStarted, this);
109 WebInspector.targetManager.addModelListener(WebInspector.NetworkManager, Web Inspector.NetworkManager.Events.RequestFinished, this._onRequestUpdated, this); 110 WebInspector.targetManager.addModelListener(
110 }; 111 WebInspector.NetworkManager, WebInspector.NetworkManager.Events.RequestU pdated, this._onRequestUpdated, this);
111 112 WebInspector.targetManager.addModelListener(
112 WebInspector.NetworkLogView._isFilteredOutSymbol = Symbol("isFilteredOut"); 113 WebInspector.NetworkManager, WebInspector.NetworkManager.Events.RequestF inished, this._onRequestUpdated, this);
113 WebInspector.NetworkLogView._isMatchingSearchQuerySymbol = Symbol("isMatchingSea rchQuery"); 114 }
114 115
115 WebInspector.NetworkLogView.HTTPSchemas = {"http": true, "https": true, "ws": tr ue, "wss": true}; 116 /**
116 117 * @param {!WebInspector.NetworkLogView.Filter} filter
117 WebInspector.NetworkLogView._waterfallMinOvertime = 1; 118 * @param {!WebInspector.NetworkRequest} request
118 WebInspector.NetworkLogView._waterfallMaxOvertime = 3; 119 * @return {boolean}
119 120 */
120 /** @enum {symbol} */ 121 static _negativeFilter(filter, request) {
121 WebInspector.NetworkLogView.Events = { 122 return !filter(request);
122 RequestSelected: Symbol("RequestSelected"), 123 }
123 SearchCountUpdated: Symbol("SearchCountUpdated"), 124
124 SearchIndexUpdated: Symbol("SearchIndexUpdated"), 125 /**
125 UpdateRequest: Symbol("UpdateRequest") 126 * @param {?RegExp} regex
126 }; 127 * @param {!WebInspector.NetworkRequest} request
127 128 * @return {boolean}
128 /** @enum {string} */ 129 */
129 WebInspector.NetworkLogView.FilterType = { 130 static _requestPathFilter(regex, request) {
130 Domain: "domain", 131 if (!regex)
131 HasResponseHeader: "has-response-header", 132 return false;
132 Is: "is", 133
133 LargerThan: "larger-than", 134 return regex.test(request.path() + '/' + request.name());
134 Method: "method", 135 }
135 MimeType: "mime-type", 136
136 MixedContent: "mixed-content", 137 /**
137 Scheme: "scheme", 138 * @param {string} domain
138 SetCookieDomain: "set-cookie-domain", 139 * @return {!Array.<string>}
139 SetCookieName: "set-cookie-name", 140 */
140 SetCookieValue: "set-cookie-value", 141 static _subdomains(domain) {
141 StatusCode: "status-code" 142 var result = [domain];
142 }; 143 var indexOfPeriod = domain.indexOf('.');
143 144 while (indexOfPeriod !== -1) {
144 /** @enum {string} */ 145 result.push('*' + domain.substring(indexOfPeriod));
145 WebInspector.NetworkLogView.MixedContentFilterValues = { 146 indexOfPeriod = domain.indexOf('.', indexOfPeriod + 1);
146 All: "all", 147 }
147 Displayed: "displayed", 148 return result;
148 Blocked: "blocked", 149 }
149 BlockOverridden: "block-overridden" 150
150 }; 151 /**
151 152 * @param {string} value
152 /** @enum {string} */ 153 * @return {!WebInspector.NetworkLogView.Filter}
153 WebInspector.NetworkLogView.IsFilterType = { 154 */
154 Running: "running" 155 static _createRequestDomainFilter(value) {
155 };
156
157 /** @type {!Array<string>} */
158 WebInspector.NetworkLogView._searchKeys = Object.keys(WebInspector.NetworkLogVie w.FilterType).map(key => WebInspector.NetworkLogView.FilterType[key]);
159
160 WebInspector.NetworkLogView.prototype = {
161 /** 156 /**
162 * @return {number} 157 * @param {string} string
163 */
164 headerHeight: function()
165 {
166 return this._headerHeight;
167 },
168
169 /**
170 * @param {boolean} recording
171 */
172 setRecording: function(recording)
173 {
174 this._recording = recording;
175 this._updateSummaryBar();
176 },
177
178 /**
179 * @param {boolean} preserveLog
180 */
181 setPreserveLog: function(preserveLog)
182 {
183 this._preserveLog = preserveLog;
184 },
185
186 /**
187 * @override
188 * @param {!WebInspector.Target} target
189 */
190 targetAdded: function(target)
191 {
192 if (!target.parentTarget()) {
193 var resourceTreeModel = WebInspector.ResourceTreeModel.fromTarget(ta rget);
194 if (resourceTreeModel) {
195 resourceTreeModel.addEventListener(WebInspector.ResourceTreeMode l.Events.MainFrameNavigated, this._mainFrameNavigated, this);
196 resourceTreeModel.addEventListener(WebInspector.ResourceTreeMode l.Events.Load, this._loadEventFired, this);
197 resourceTreeModel.addEventListener(WebInspector.ResourceTreeMode l.Events.DOMContentLoaded, this._domContentLoadedEventFired, this);
198 }
199 }
200 var networkLog = WebInspector.NetworkLog.fromTarget(target);
201 if (networkLog)
202 networkLog.requests().forEach(this._appendRequest.bind(this));
203 },
204
205 /**
206 * @override
207 * @param {!WebInspector.Target} target
208 */
209 targetRemoved: function(target)
210 {
211 if (!target.parentTarget()) {
212 var resourceTreeModel = WebInspector.ResourceTreeModel.fromTarget(ta rget);
213 if (resourceTreeModel) {
214 resourceTreeModel.removeEventListener(WebInspector.ResourceTreeM odel.Events.MainFrameNavigated, this._mainFrameNavigated, this);
215 resourceTreeModel.removeEventListener(WebInspector.ResourceTreeM odel.Events.Load, this._loadEventFired, this);
216 resourceTreeModel.removeEventListener(WebInspector.ResourceTreeM odel.Events.DOMContentLoaded, this._domContentLoadedEventFired, this);
217 }
218 }
219 },
220
221 /**
222 * @param {number} start
223 * @param {number} end
224 */
225 setWindow: function(start, end)
226 {
227 if (!start && !end) {
228 this._timeFilter = null;
229 this._timeCalculator.setWindow(null);
230 } else {
231 this._timeFilter = WebInspector.NetworkLogView._requestTimeFilter.bi nd(null, start, end);
232 this._timeCalculator.setWindow(new WebInspector.NetworkTimeBoundary( start, end));
233 }
234 this._columns.updateDividersIfNeeded();
235 this._filterRequests();
236 },
237
238 clearSelection: function()
239 {
240 if (this._dataGrid.selectedNode)
241 this._dataGrid.selectedNode.deselect();
242 },
243
244 _addFilters: function()
245 {
246 this._textFilterUI = new WebInspector.TextFilterUI(true);
247 this._textFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterC hanged, this._filterChanged, this);
248 this._filterBar.addFilter(this._textFilterUI);
249
250 var dataURLSetting = this._networkHideDataURLSetting;
251 this._dataURLFilterUI = new WebInspector.CheckboxFilterUI("hide-data-url ", WebInspector.UIString("Hide data URLs"), true, dataURLSetting);
252 this._dataURLFilterUI.addEventListener(WebInspector.FilterUI.Events.Filt erChanged, this._filterChanged.bind(this), this);
253 this._filterBar.addFilter(this._dataURLFilterUI);
254
255 var filterItems = [];
256 for (var categoryId in WebInspector.resourceCategories) {
257 var category = WebInspector.resourceCategories[categoryId];
258 filterItems.push({name: category.title, label: category.shortTitle, title: category.title});
259 }
260 this._resourceCategoryFilterUI = new WebInspector.NamedBitSetFilterUI(fi lterItems, this._networkResourceTypeFiltersSetting);
261 this._resourceCategoryFilterUI.addEventListener(WebInspector.FilterUI.Ev ents.FilterChanged, this._filterChanged.bind(this), this);
262 this._filterBar.addFilter(this._resourceCategoryFilterUI);
263 },
264
265 _resetSuggestionBuilder: function()
266 {
267 this._suggestionBuilder = new WebInspector.FilterSuggestionBuilder(WebIn spector.NetworkLogView._searchKeys);
268 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.I s, WebInspector.NetworkLogView.IsFilterType.Running);
269 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.L argerThan, "100");
270 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.L argerThan, "10k");
271 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.L argerThan, "1M");
272 this._textFilterUI.setSuggestionBuilder(this._suggestionBuilder);
273 },
274
275 /**
276 * @param {!WebInspector.Event} event
277 */
278 _filterChanged: function(event)
279 {
280 this.removeAllNodeHighlights();
281 this._parseFilterQuery(this._textFilterUI.value());
282 this._filterRequests();
283 },
284
285 _initializeView: function()
286 {
287 this.element.id = "network-container";
288 this._setupDataGrid();
289
290 this._columns.show(this.element);
291
292 this._summaryBarElement = this.element.createChild("div", "network-summa ry-bar");
293
294 this._columns.sortByCurrentColumn();
295 },
296
297 _showRecordingHint: function()
298 {
299 this._hideRecordingHint();
300 this._recordingHint = this.element.createChild("div", "network-status-pa ne fill");
301 var hintText = this._recordingHint.createChild("div", "recording-hint");
302 var reloadShortcutNode = this._recordingHint.createChild("b");
303 reloadShortcutNode.textContent = WebInspector.shortcutRegistry.shortcutD escriptorsForAction("main.reload")[0].name;
304
305 if (this._recording) {
306 var recordingText = hintText.createChild("span");
307 recordingText.textContent = WebInspector.UIString("Recording network activity\u2026");
308 hintText.createChild("br");
309 hintText.appendChild(WebInspector.formatLocalized("Perform a request or hit %s to record the reload.", [reloadShortcutNode]));
310 } else {
311 var recordNode = hintText.createChild("b");
312 recordNode.textContent = WebInspector.shortcutRegistry.shortcutTitle ForAction("network.toggle-recording");
313 hintText.appendChild(WebInspector.formatLocalized("Record (%s) or re load (%s) to display network activity.", [recordNode, reloadShortcutNode]));
314 }
315 },
316
317 _hideRecordingHint: function()
318 {
319 if (this._recordingHint)
320 this._recordingHint.remove();
321 delete this._recordingHint;
322 },
323
324 /**
325 * @override
326 * @return {!Array.<!Element>}
327 */
328 elementsToRestoreScrollPositionsFor: function()
329 {
330 if (!this._dataGrid) // Not initialized yet.
331 return [];
332 return [this._dataGrid.scrollContainer];
333 },
334
335 _setupDataGrid: function()
336 {
337 this._dataGrid = this._columns.dataGrid();
338 this._dataGrid.setRowContextMenuCallback((contextMenu, node) => this.han dleContextMenuForRequest(contextMenu, node.request()));
339 this._dataGrid.setStickToBottom(true);
340 this._dataGrid.setName("networkLog");
341 this._dataGrid.setResizeMethod(WebInspector.DataGrid.ResizeMethod.Last);
342 this._dataGrid.element.classList.add("network-log-grid");
343 this._dataGrid.element.addEventListener("mousedown", this._dataGridMouse Down.bind(this), true);
344 this._dataGrid.element.addEventListener("mousemove", this._dataGridMouse Move.bind(this), true);
345 this._dataGrid.element.addEventListener("mouseleave", this._dataGridMous eLeave.bind(this), true);
346 },
347
348 /**
349 * @param {!Event} event
350 */
351 _dataGridMouseMove: function(event)
352 {
353 var node = this._dataGrid.dataGridNodeFromNode(event.target);
354 var highlightInitiatorChain = event.shiftKey;
355 this._setHoveredNode(node, highlightInitiatorChain);
356 this._highlightInitiatorChain((highlightInitiatorChain && node) ? node.r equest() : null);
357 },
358
359 _dataGridMouseLeave: function()
360 {
361 this._setHoveredNode(null);
362 this._highlightInitiatorChain(null);
363 },
364
365 /**
366 * @param {?WebInspector.NetworkRequest} request
367 * @param {boolean} highlightInitiatorChain
368 */
369 setHoveredRequest: function(request, highlightInitiatorChain)
370 {
371 this._setHoveredNode(request ? this._nodesByRequestId.get(request.reques tId) : null, highlightInitiatorChain);
372 this._highlightInitiatorChain((request && highlightInitiatorChain) ? req uest : null);
373 },
374
375 /**
376 * @param {?WebInspector.NetworkDataGridNode} node
377 * @param {boolean=} highlightInitiatorChain
378 */
379 _setHoveredNode: function(node, highlightInitiatorChain)
380 {
381 if (this._hoveredNode)
382 this._hoveredNode.element().classList.remove("hover");
383 this._hoveredNode = node;
384 if (this._hoveredNode)
385 this._hoveredNode.element().classList.add("hover");
386 this._columns.setHoveredRequest(this._hoveredNode ? this._hoveredNode.re quest() : null, !!highlightInitiatorChain);
387 },
388
389 /**
390 * @param {!Event} event
391 */
392 _dataGridMouseDown: function(event)
393 {
394 if ((!this._dataGrid.selectedNode && event.button) || event.target.enclo singNodeOrSelfWithNodeName("a"))
395 event.consume();
396 },
397
398 /**
399 * @param {?WebInspector.NetworkRequest} request
400 */
401 _highlightInitiatorChain: function(request)
402 {
403 if (this._requestWithHighlightedInitiators === request)
404 return;
405 this._requestWithHighlightedInitiators = request;
406
407 if (!request) {
408 for (var node of this._nodesByRequestId.values()) {
409 if (!node.dataGrid)
410 continue;
411 node.element().classList.remove("network-node-on-initiator-path" , "network-node-on-initiated-path");
412 }
413 return;
414 }
415
416 var initiatorGraph = request.initiatorGraph();
417 for (var node of this._nodesByRequestId.values()) {
418 if (!node.dataGrid)
419 continue;
420 node.element().classList.toggle("network-node-on-initiator-path", no de.request() !== request && initiatorGraph.initiators.has(node.request()));
421 node.element().classList.toggle("network-node-on-initiated-path", no de.request() !== request && initiatorGraph.initiated.has(node.request()));
422 }
423 },
424
425 _updateSummaryBar: function()
426 {
427 var requestsNumber = this._nodesByRequestId.size;
428
429 if (!requestsNumber) {
430 this._showRecordingHint();
431 return;
432 }
433 this._hideRecordingHint();
434
435 var transferSize = 0;
436 var selectedRequestsNumber = 0;
437 var selectedTransferSize = 0;
438 var baseTime = -1;
439 var maxTime = -1;
440 var nodes = this._nodesByRequestId.valuesArray();
441 for (var i = 0; i < nodes.length; ++i) {
442 var request = nodes[i].request();
443 var requestTransferSize = request.transferSize;
444 transferSize += requestTransferSize;
445 if (!nodes[i][WebInspector.NetworkLogView._isFilteredOutSymbol]) {
446 selectedRequestsNumber++;
447 selectedTransferSize += requestTransferSize;
448 }
449 if (request.url === request.target().inspectedURL() && request.resou rceType() === WebInspector.resourceTypes.Document)
450 baseTime = request.startTime;
451 if (request.endTime > maxTime)
452 maxTime = request.endTime;
453 }
454
455 var summaryBar = this._summaryBarElement;
456 summaryBar.removeChildren();
457 var separator = "\u2002\u2758\u2002";
458 var text = "";
459 /**
460 * @param {string} chunk
461 * @return {!Element}
462 */
463 function appendChunk(chunk)
464 {
465 var span = summaryBar.createChild("span");
466 span.textContent = chunk;
467 text += chunk;
468 return span;
469 }
470
471 if (selectedRequestsNumber !== requestsNumber) {
472 appendChunk(WebInspector.UIString("%d / %d requests", selectedReques tsNumber, requestsNumber));
473 appendChunk(separator);
474 appendChunk(WebInspector.UIString("%s / %s transferred", Number.byte sToString(selectedTransferSize), Number.bytesToString(transferSize)));
475 } else {
476 appendChunk(WebInspector.UIString("%d requests", requestsNumber));
477 appendChunk(separator);
478 appendChunk(WebInspector.UIString("%s transferred", Number.bytesToSt ring(transferSize)));
479 }
480 if (baseTime !== -1 && maxTime !== -1) {
481 appendChunk(separator);
482 appendChunk(WebInspector.UIString("Finish: %s", Number.secondsToStri ng(maxTime - baseTime)));
483 if (this._mainRequestDOMContentLoadedTime !== -1 && this._mainReques tDOMContentLoadedTime > baseTime) {
484 appendChunk(separator);
485 var domContentLoadedText = WebInspector.UIString("DOMContentLoad ed: %s", Number.secondsToString(this._mainRequestDOMContentLoadedTime - baseTime ));
486 appendChunk(domContentLoadedText).classList.add("summary-blue");
487 }
488 if (this._mainRequestLoadTime !== -1) {
489 appendChunk(separator);
490 var loadText = WebInspector.UIString("Load: %s", Number.secondsT oString(this._mainRequestLoadTime - baseTime));
491 appendChunk(loadText).classList.add("summary-red");
492 }
493 }
494 summaryBar.title = text;
495 },
496
497 scheduleRefresh: function()
498 {
499 if (this._needsRefresh)
500 return;
501
502 this._needsRefresh = true;
503
504 if (this.isShowing() && !this._refreshRequestId)
505 this._refreshRequestId = this.element.window().requestAnimationFrame (this._refresh.bind(this));
506 },
507
508 /**
509 * @param {!Array<number>} times
510 */
511 addFilmStripFrames: function(times)
512 {
513 this._columns.addEventDividers(times, "network-frame-divider");
514 },
515
516 /**
517 * @param {number} time
518 */
519 selectFilmStripFrame: function(time)
520 {
521 this._columns.selectFilmStripFrame(time);
522 },
523
524 clearFilmStripFrame: function()
525 {
526 this._columns.clearFilmStripFrame();
527 },
528
529 _refreshIfNeeded: function()
530 {
531 if (this._needsRefresh)
532 this._refresh();
533 },
534
535 _invalidateAllItems: function()
536 {
537 var requestIds = this._nodesByRequestId.keysArray();
538 for (var i = 0; i < requestIds.length; ++i)
539 this._staleRequestIds[requestIds[i]] = true;
540 this._refresh();
541 },
542
543 /**
544 * @return {!WebInspector.NetworkTimeCalculator}
545 */
546 timeCalculator: function()
547 {
548 return this._timeCalculator;
549 },
550
551 /**
552 * @return {!WebInspector.NetworkTimeCalculator}
553 */
554 calculator: function()
555 {
556 return this._calculator;
557 },
558
559 /**
560 * @param {!WebInspector.NetworkTimeCalculator} x
561 */
562 setCalculator: function(x)
563 {
564 if (!x || this._calculator === x)
565 return;
566
567 if (this._calculator !== x) {
568 this._calculator = x;
569 this._columns.setCalculator(this._calculator);
570 }
571 this._calculator.reset();
572
573 if (this._calculator.startAtZero)
574 this._columns.hideEventDividers();
575 else
576 this._columns.showEventDividers();
577
578 this._invalidateAllItems();
579 },
580
581 /**
582 * @param {!WebInspector.Event} event
583 */
584 _loadEventFired: function(event)
585 {
586 if (!this._recording)
587 return;
588
589 var data = /** @type {number} */ (event.data);
590 if (data) {
591 this._mainRequestLoadTime = data;
592 this._columns.addEventDividers([data], "network-red-divider");
593 }
594 },
595
596 /**
597 * @param {!WebInspector.Event} event
598 */
599 _domContentLoadedEventFired: function(event)
600 {
601 if (!this._recording)
602 return;
603 var data = /** @type {number} */ (event.data);
604 if (data) {
605 this._mainRequestDOMContentLoadedTime = data;
606 this._columns.addEventDividers([data], "network-blue-divider");
607 }
608 },
609
610 wasShown: function()
611 {
612 this._refreshIfNeeded();
613 this._columns.wasShown();
614 },
615
616 willHide: function()
617 {
618 this._columns.willHide();
619 },
620
621 _refresh: function()
622 {
623 this._needsRefresh = false;
624
625 if (this._refreshRequestId) {
626 this.element.window().cancelAnimationFrame(this._refreshRequestId);
627 delete this._refreshRequestId;
628 }
629
630 this.removeAllNodeHighlights();
631
632 var oldBoundary = this.calculator().boundary();
633 this._timeCalculator.updateBoundariesForEventTime(this._mainRequestLoadT ime);
634 this._durationCalculator.updateBoundariesForEventTime(this._mainRequestL oadTime);
635 this._timeCalculator.updateBoundariesForEventTime(this._mainRequestDOMCo ntentLoadedTime);
636 this._durationCalculator.updateBoundariesForEventTime(this._mainRequestD OMContentLoadedTime);
637
638 var dataGrid = this._dataGrid;
639 var rootNode = dataGrid.rootNode();
640 /** @type {!Array<!WebInspector.NetworkDataGridNode> } */
641 var nodesToInsert = [];
642 /** @type {!Array<!WebInspector.NetworkDataGridNode> } */
643 var nodesToRefresh = [];
644 for (var requestId in this._staleRequestIds) {
645 var node = this._nodesByRequestId.get(requestId);
646 if (!node)
647 continue;
648 var isFilteredOut = !this._applyFilter(node);
649 if (isFilteredOut && node === this._hoveredNode)
650 this._setHoveredNode(null);
651 if (node[WebInspector.NetworkLogView._isFilteredOutSymbol] !== isFil teredOut) {
652 if (!node[WebInspector.NetworkLogView._isFilteredOutSymbol])
653 rootNode.removeChild(node);
654
655 node[WebInspector.NetworkLogView._isFilteredOutSymbol] = isFilte redOut;
656
657 if (!node[WebInspector.NetworkLogView._isFilteredOutSymbol])
658 nodesToInsert.push(node);
659 }
660 if (!isFilteredOut)
661 nodesToRefresh.push(node);
662 var request = node.request();
663 this._timeCalculator.updateBoundaries(request);
664 this._durationCalculator.updateBoundaries(request);
665 }
666
667 for (var i = 0; i < nodesToInsert.length; ++i) {
668 var node = nodesToInsert[i];
669 var request = node.request();
670 dataGrid.insertChild(node);
671 node[WebInspector.NetworkLogView._isMatchingSearchQuerySymbol] = thi s._matchRequest(request);
672 }
673
674 for (var node of nodesToRefresh)
675 node.refresh();
676
677 this._highlightNthMatchedRequestForSearch(this._updateMatchCountAndFindM atchIndex(this._currentMatchedRequestNode), false);
678
679 if (!this.calculator().boundary().equals(oldBoundary)) {
680 // The boundaries changed, so all item graphs are stale.
681 this._columns.updateDividersIfNeeded();
682 var nodes = this._nodesByRequestId.valuesArray();
683 for (var i = 0; i < nodes.length; ++i)
684 nodes[i].refreshGraph();
685 }
686
687 this._staleRequestIds = {};
688 this._updateSummaryBar();
689
690 this._columns.dataChanged();
691 },
692
693 reset: function()
694 {
695 this._requestWithHighlightedInitiators = null;
696 this.dispatchEventToListeners(WebInspector.NetworkLogView.Events.Request Selected, null);
697
698 this._clearSearchMatchedList();
699
700 this._setHoveredNode(null);
701 this._columns.reset();
702
703 this._timeFilter = null;
704 this._calculator.reset();
705
706 this._timeCalculator.setWindow(null);
707
708 var nodes = this._nodesByRequestId.valuesArray();
709 for (var i = 0; i < nodes.length; ++i)
710 nodes[i].dispose();
711
712 this._nodesByRequestId.clear();
713 this._staleRequestIds = {};
714 this._resetSuggestionBuilder();
715
716 this._mainRequestLoadTime = -1;
717 this._mainRequestDOMContentLoadedTime = -1;
718
719 if (this._dataGrid) {
720 this._dataGrid.rootNode().removeChildren();
721 this._updateSummaryBar();
722 }
723 },
724
725 /**
726 * @param {string} filterString
727 */
728 setTextFilterValue: function(filterString)
729 {
730 this._textFilterUI.setValue(filterString);
731 this._textFilterUI.setRegexChecked(false);
732 this._dataURLFilterUI.setChecked(false);
733 this._resourceCategoryFilterUI.reset();
734 },
735
736 /**
737 * @param {!WebInspector.Event} event
738 */
739 _onRequestStarted: function(event)
740 {
741 if (!this._recording)
742 return;
743 var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
744 this._appendRequest(request);
745 },
746
747 /**
748 * @param {!WebInspector.NetworkRequest} request
749 */
750 _appendRequest: function(request)
751 {
752 var node = new WebInspector.NetworkDataGridNode(this, request);
753 node[WebInspector.NetworkLogView._isFilteredOutSymbol] = true;
754 node[WebInspector.NetworkLogView._isMatchingSearchQuerySymbol] = false;
755
756 // In case of redirect request id is reassigned to a redirected
757 // request and we need to update _nodesByRequestId and search results.
758 var originalRequestNode = this._nodesByRequestId.get(request.requestId);
759 if (originalRequestNode)
760 this._nodesByRequestId.set(originalRequestNode.request().requestId, originalRequestNode);
761 this._nodesByRequestId.set(request.requestId, node);
762
763 // Pull all the redirects of the main request upon commit load.
764 if (request.redirects) {
765 for (var i = 0; i < request.redirects.length; ++i)
766 this._refreshRequest(request.redirects[i]);
767 }
768
769 this._refreshRequest(request);
770 },
771
772 /**
773 * @param {!WebInspector.Event} event
774 */
775 _onRequestUpdated: function(event)
776 {
777 var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
778 this._refreshRequest(request);
779 },
780
781 /**
782 * @param {!WebInspector.NetworkRequest} request
783 */
784 _refreshRequest: function(request)
785 {
786 if (!this._nodesByRequestId.get(request.requestId))
787 return;
788
789 WebInspector.NetworkLogView._subdomains(request.domain).forEach(this._su ggestionBuilder.addItem.bind(this._suggestionBuilder, WebInspector.NetworkLogVie w.FilterType.Domain));
790 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.M ethod, request.requestMethod);
791 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.M imeType, request.mimeType);
792 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.S cheme, "" + request.scheme);
793 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.S tatusCode, "" + request.statusCode);
794
795 if (request.mixedContentType !== "none") {
796 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterTy pe.MixedContent, WebInspector.NetworkLogView.MixedContentFilterValues.All);
797 }
798
799 if (request.mixedContentType === "optionally-blockable") {
800 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterTy pe.MixedContent, WebInspector.NetworkLogView.MixedContentFilterValues.Displayed) ;
801 }
802
803 if (request.mixedContentType === "blockable") {
804 var suggestion = request.wasBlocked() ? WebInspector.NetworkLogView. MixedContentFilterValues.Blocked : WebInspector.NetworkLogView.MixedContentFilte rValues.BlockOverridden;
805 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterTy pe.MixedContent, suggestion);
806 }
807
808 var responseHeaders = request.responseHeaders;
809 for (var i = 0, l = responseHeaders.length; i < l; ++i)
810 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterTy pe.HasResponseHeader, responseHeaders[i].name);
811 var cookies = request.responseCookies;
812 for (var i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
813 var cookie = cookies[i];
814 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterTy pe.SetCookieDomain, cookie.domain());
815 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterTy pe.SetCookieName, cookie.name());
816 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterTy pe.SetCookieValue, cookie.value());
817 }
818
819 this._staleRequestIds[request.requestId] = true;
820 this.dispatchEventToListeners(WebInspector.NetworkLogView.Events.UpdateR equest, request);
821 this.scheduleRefresh();
822 },
823
824 /**
825 * @param {!WebInspector.Event} event
826 */
827 _mainFrameNavigated: function(event)
828 {
829 if (!this._recording)
830 return;
831
832 var frame = /** @type {!WebInspector.ResourceTreeFrame} */ (event.data);
833 var loaderId = frame.loaderId;
834
835 // Pick provisional load requests.
836 var requestsToPick = [];
837 var networkLog = WebInspector.NetworkLog.fromTarget(frame.target());
838 var requests = networkLog ? networkLog.requests() : [];
839 for (var i = 0; i < requests.length; ++i) {
840 var request = requests[i];
841 if (request.loaderId === loaderId)
842 requestsToPick.push(request);
843 }
844
845 if (!this._preserveLog) {
846 this.reset();
847 for (var i = 0; i < requestsToPick.length; ++i)
848 this._appendRequest(requestsToPick[i]);
849 }
850 for (var i = 0; i < requestsToPick.length; ++i) {
851 var request = requestsToPick[i];
852 var node = this._nodesByRequestId.get(request.requestId);
853 if (node) {
854 node.markAsNavigationRequest();
855 break;
856 }
857 }
858 },
859
860 /**
861 * @return {number}
862 */
863 rowHeight: function()
864 {
865 return this._rowHeight;
866 },
867
868 /**
869 * @param {boolean} gridMode
870 */
871 switchViewMode: function(gridMode)
872 {
873 this._columns.switchViewMode(gridMode);
874 },
875
876 /**
877 * @param {!WebInspector.ContextMenu} contextMenu
878 * @param {!WebInspector.NetworkRequest} request
879 */
880 handleContextMenuForRequest: function(contextMenu, request)
881 {
882 contextMenu.appendApplicableItems(request);
883 var copyMenu = contextMenu.appendSubMenuItem(WebInspector.UIString("Copy "));
884 if (request) {
885 copyMenu.appendItem(WebInspector.copyLinkAddressLabel(), InspectorFr ontendHost.copyText.bind(InspectorFrontendHost, request.contentURL()));
886 copyMenu.appendSeparator();
887
888 if (request.requestHeadersText())
889 copyMenu.appendItem(WebInspector.UIString.capitalize("Copy ^requ est ^headers"), this._copyRequestHeaders.bind(this, request));
890 if (request.responseHeadersText)
891 copyMenu.appendItem(WebInspector.UIString.capitalize("Copy ^resp onse ^headers"), this._copyResponseHeaders.bind(this, request));
892 if (request.finished)
893 copyMenu.appendItem(WebInspector.UIString.capitalize("Copy ^resp onse"), this._copyResponse.bind(this, request));
894
895 if (WebInspector.isWin()) {
896 copyMenu.appendItem(WebInspector.UIString("Copy as cURL (cmd)"), this._copyCurlCommand.bind(this, request, "win"));
897 copyMenu.appendItem(WebInspector.UIString("Copy as cURL (bash)") , this._copyCurlCommand.bind(this, request, "unix"));
898 copyMenu.appendItem(WebInspector.UIString("Copy All as cURL (cmd )"), this._copyAllCurlCommand.bind(this, "win"));
899 copyMenu.appendItem(WebInspector.UIString("Copy All as cURL (bas h)"), this._copyAllCurlCommand.bind(this, "unix"));
900 } else {
901 copyMenu.appendItem(WebInspector.UIString("Copy as cURL"), this. _copyCurlCommand.bind(this, request, "unix"));
902 copyMenu.appendItem(WebInspector.UIString("Copy All as cURL"), t his._copyAllCurlCommand.bind(this, "unix"));
903 }
904 } else {
905 copyMenu = contextMenu.appendSubMenuItem(WebInspector.UIString("Copy "));
906 }
907 copyMenu.appendItem(WebInspector.UIString.capitalize("Copy ^all as HAR") , this._copyAll.bind(this));
908
909 contextMenu.appendSeparator();
910 contextMenu.appendItem(WebInspector.UIString.capitalize("Save as HAR wit h ^content"), this._exportAll.bind(this));
911
912 contextMenu.appendSeparator();
913 contextMenu.appendItem(WebInspector.UIString.capitalize("Clear ^browser ^cache"), this._clearBrowserCache.bind(this));
914 contextMenu.appendItem(WebInspector.UIString.capitalize("Clear ^browser ^cookies"), this._clearBrowserCookies.bind(this));
915
916 var blockedSetting = WebInspector.moduleSetting("blockedURLs");
917 if (request && Runtime.experiments.isEnabled("requestBlocking")) { // D isabled until ready.
918 contextMenu.appendSeparator();
919
920 var urlWithoutScheme = request.parsedURL.urlWithoutScheme();
921 if (urlWithoutScheme && blockedSetting.get().indexOf(urlWithoutSchem e) === -1)
922 contextMenu.appendItem(WebInspector.UIString.capitalize("Block ^ request URL"), addBlockedURL.bind(null, urlWithoutScheme));
923
924 var domain = request.parsedURL.domain();
925 if (domain && blockedSetting.get().indexOf(domain) === -1)
926 contextMenu.appendItem(WebInspector.UIString.capitalize("Block ^ request ^domain"), addBlockedURL.bind(null, domain));
927
928 function addBlockedURL(url)
929 {
930 var list = blockedSetting.get();
931 list.push(url);
932 blockedSetting.set(list);
933 WebInspector.viewManager.showView("network.blocked-urls");
934 }
935 }
936
937 if (request && request.resourceType() === WebInspector.resourceTypes.XHR ) {
938 contextMenu.appendSeparator();
939 contextMenu.appendItem(WebInspector.UIString("Replay XHR"), request. replayXHR.bind(request));
940 contextMenu.appendSeparator();
941 }
942 },
943
944 _harRequests: function()
945 {
946 var requests = this._nodesByRequestId.valuesArray().map(function(node) { return node.request(); });
947 var httpRequests = requests.filter(WebInspector.NetworkLogView.HTTPReque stsFilter);
948 return httpRequests.filter(WebInspector.NetworkLogView.FinishedRequestsF ilter);
949 },
950
951 _copyAll: function()
952 {
953 var harArchive = {
954 log: (new WebInspector.HARLog(this._harRequests())).build()
955 };
956 InspectorFrontendHost.copyText(JSON.stringify(harArchive, null, 2));
957 },
958
959 /**
960 * @param {!WebInspector.NetworkRequest} request
961 */
962 _copyRequestHeaders: function(request)
963 {
964 InspectorFrontendHost.copyText(request.requestHeadersText());
965 },
966
967 /**
968 * @param {!WebInspector.NetworkRequest} request
969 */
970 _copyResponse: function(request)
971 {
972 /**
973 * @param {?string} content
974 */
975 function callback(content)
976 {
977 if (request.contentEncoded)
978 content = request.asDataURL();
979 InspectorFrontendHost.copyText(content || "");
980 }
981 request.requestContent().then(callback);
982 },
983
984 /**
985 * @param {!WebInspector.NetworkRequest} request
986 */
987 _copyResponseHeaders: function(request)
988 {
989 InspectorFrontendHost.copyText(request.responseHeadersText);
990 },
991
992 /**
993 * @param {!WebInspector.NetworkRequest} request
994 * @param {string} platform
995 */
996 _copyCurlCommand: function(request, platform)
997 {
998 InspectorFrontendHost.copyText(this._generateCurlCommand(request, platfo rm));
999 },
1000
1001 /**
1002 * @param {string} platform
1003 */
1004 _copyAllCurlCommand: function(platform)
1005 {
1006 var requests = this._nodesByRequestId.valuesArray().map(node => node.req uest());
1007 var commands = [];
1008 for (var request of requests)
1009 commands.push(this._generateCurlCommand(request, platform));
1010 if (platform === "win")
1011 InspectorFrontendHost.copyText(commands.join(" &\r\n"));
1012 else
1013 InspectorFrontendHost.copyText(commands.join(" ;\n"));
1014 },
1015
1016 _exportAll: function()
1017 {
1018 var url = WebInspector.targetManager.mainTarget().inspectedURL();
1019 var parsedURL = url.asParsedURL();
1020 var filename = parsedURL ? parsedURL.host : "network-log";
1021 var stream = new WebInspector.FileOutputStream();
1022 stream.open(filename + ".har", openCallback.bind(this));
1023
1024 /**
1025 * @param {boolean} accepted
1026 * @this {WebInspector.NetworkLogView}
1027 */
1028 function openCallback(accepted)
1029 {
1030 if (!accepted)
1031 return;
1032 var progressIndicator = new WebInspector.ProgressIndicator();
1033 this._progressBarContainer.appendChild(progressIndicator.element);
1034 var harWriter = new WebInspector.HARWriter();
1035 harWriter.write(stream, this._harRequests(), progressIndicator);
1036 }
1037 },
1038
1039 _clearBrowserCache: function()
1040 {
1041 if (confirm(WebInspector.UIString("Are you sure you want to clear browse r cache?")))
1042 WebInspector.multitargetNetworkManager.clearBrowserCache();
1043 },
1044
1045 _clearBrowserCookies: function()
1046 {
1047 if (confirm(WebInspector.UIString("Are you sure you want to clear browse r cookies?")))
1048 WebInspector.multitargetNetworkManager.clearBrowserCookies();
1049 },
1050
1051 /**
1052 * @param {!WebInspector.NetworkRequest} request
1053 * @return {boolean}
1054 */
1055 _matchRequest: function(request)
1056 {
1057 var re = this._searchRegex;
1058 if (!re)
1059 return false;
1060
1061 var text = this._networkLogLargeRowsSetting.get() ? request.path() + "/" + request.name() : request.name();
1062 return re.test(text);
1063 },
1064
1065 _clearSearchMatchedList: function()
1066 {
1067 this._matchedRequestCount = -1;
1068 this._currentMatchedRequestNode = null;
1069 this._removeAllHighlights();
1070 },
1071
1072 _removeAllHighlights: function()
1073 {
1074 this.removeAllNodeHighlights();
1075 for (var i = 0; i < this._highlightedSubstringChanges.length; ++i)
1076 WebInspector.revertDomChanges(this._highlightedSubstringChanges[i]);
1077 this._highlightedSubstringChanges = [];
1078 },
1079
1080 dataGridSorted: function()
1081 {
1082 this._highlightNthMatchedRequestForSearch(this._updateMatchCountAndFindM atchIndex(this._currentMatchedRequestNode), false);
1083 },
1084
1085 /**
1086 * @param {number} n
1087 * @param {boolean} reveal
1088 */
1089 _highlightNthMatchedRequestForSearch: function(n, reveal)
1090 {
1091 this._removeAllHighlights();
1092
1093 /** @type {!Array.<!WebInspector.NetworkDataGridNode>} */
1094 var nodes = this._dataGrid.rootNode().children;
1095 var matchCount = 0;
1096 var node = null;
1097 for (var i = 0; i < nodes.length; ++i) {
1098 if (nodes[i][WebInspector.NetworkLogView._isMatchingSearchQuerySymbo l]) {
1099 if (matchCount === n) {
1100 node = nodes[i];
1101 break;
1102 }
1103 matchCount++;
1104 }
1105 }
1106 if (!node) {
1107 this._currentMatchedRequestNode = null;
1108 return;
1109 }
1110
1111 var request = node.request();
1112 if (reveal)
1113 WebInspector.Revealer.reveal(request);
1114 var highlightedSubstringChanges = node.highlightMatchedSubstring(this._s earchRegex);
1115 this._highlightedSubstringChanges.push(highlightedSubstringChanges);
1116
1117 this._currentMatchedRequestNode = node;
1118 this._currentMatchedRequestIndex = n;
1119 this.dispatchEventToListeners(WebInspector.NetworkLogView.Events.SearchI ndexUpdated, n);
1120 },
1121
1122 /**
1123 * @override
1124 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig
1125 * @param {boolean} shouldJump
1126 * @param {boolean=} jumpBackwards
1127 */
1128 performSearch: function(searchConfig, shouldJump, jumpBackwards)
1129 {
1130 var query = searchConfig.query;
1131 var currentMatchedRequestNode = this._currentMatchedRequestNode;
1132 this._clearSearchMatchedList();
1133 this._searchRegex = createPlainTextSearchRegex(query, "i");
1134
1135 /** @type {!Array.<!WebInspector.NetworkDataGridNode>} */
1136 var nodes = this._dataGrid.rootNode().children;
1137 for (var i = 0; i < nodes.length; ++i)
1138 nodes[i][WebInspector.NetworkLogView._isMatchingSearchQuerySymbol] = this._matchRequest(nodes[i].request());
1139 var newMatchedRequestIndex = this._updateMatchCountAndFindMatchIndex(cur rentMatchedRequestNode);
1140 if (!newMatchedRequestIndex && jumpBackwards)
1141 newMatchedRequestIndex = this._matchedRequestCount - 1;
1142 this._highlightNthMatchedRequestForSearch(newMatchedRequestIndex, should Jump);
1143 },
1144
1145 /**
1146 * @override
1147 * @return {boolean}
1148 */
1149 supportsCaseSensitiveSearch: function()
1150 {
1151 return false;
1152 },
1153
1154 /**
1155 * @override
1156 * @return {boolean}
1157 */
1158 supportsRegexSearch: function()
1159 {
1160 return true;
1161 },
1162
1163 /**
1164 * @param {?WebInspector.NetworkDataGridNode} node
1165 * @return {number}
1166 */
1167 _updateMatchCountAndFindMatchIndex: function(node)
1168 {
1169 /** @type {!Array.<!WebInspector.NetworkDataGridNode>} */
1170 var nodes = this._dataGrid.rootNode().children;
1171 var matchCount = 0;
1172 var matchIndex = 0;
1173 for (var i = 0; i < nodes.length; ++i) {
1174 if (!nodes[i][WebInspector.NetworkLogView._isMatchingSearchQuerySymb ol])
1175 continue;
1176 if (node === nodes[i])
1177 matchIndex = matchCount;
1178 matchCount++;
1179 }
1180 if (this._matchedRequestCount !== matchCount) {
1181 this._matchedRequestCount = matchCount;
1182 this.dispatchEventToListeners(WebInspector.NetworkLogView.Events.Sea rchCountUpdated, matchCount);
1183 }
1184 return matchIndex;
1185 },
1186
1187 /**
1188 * @param {number} index
1189 * @return {number}
1190 */
1191 _normalizeSearchResultIndex: function(index)
1192 {
1193 return (index + this._matchedRequestCount) % this._matchedRequestCount;
1194 },
1195
1196 /**
1197 * @param {!WebInspector.NetworkDataGridNode} node
1198 * @return {boolean}
1199 */
1200 _applyFilter: function(node)
1201 {
1202 var request = node.request();
1203 if (this._timeFilter && !this._timeFilter(request))
1204 return false;
1205 var categoryName = request.resourceType().category().title;
1206 if (!this._resourceCategoryFilterUI.accept(categoryName))
1207 return false;
1208 if (this._dataURLFilterUI.checked() && request.parsedURL.isDataURL())
1209 return false;
1210 if (request.statusText === "Service Worker Fallback Required")
1211 return false;
1212 for (var i = 0; i < this._filters.length; ++i) {
1213 if (!this._filters[i](request))
1214 return false;
1215 }
1216 return true;
1217 },
1218
1219 /**
1220 * @param {string} query
1221 */
1222 _parseFilterQuery: function(query)
1223 {
1224 var parsedQuery;
1225 if (this._textFilterUI.isRegexChecked() && query !== "")
1226 parsedQuery = {text: [query], filters: []};
1227 else
1228 parsedQuery = this._suggestionBuilder.parseQuery(query);
1229
1230 this._filters = parsedQuery.text.map(this._createTextFilter, this);
1231
1232 var n = parsedQuery.filters.length;
1233 for (var i = 0; i < n; ++i) {
1234 var filter = parsedQuery.filters[i];
1235 var filterType = /** @type {!WebInspector.NetworkLogView.FilterType} */ (filter.type.toLowerCase());
1236 this._filters.push(this._createFilter(filterType, filter.data, filte r.negative));
1237 }
1238 },
1239
1240 /**
1241 * @param {string} text
1242 * @return {!WebInspector.NetworkLogView.Filter}
1243 */
1244 _createTextFilter: function(text)
1245 {
1246 var negative = false;
1247 /** @type {?RegExp} */
1248 var regex;
1249 if (!this._textFilterUI.isRegexChecked() && text[0] === "-" && text.leng th > 1) {
1250 negative = true;
1251 text = text.substring(1);
1252 regex = new RegExp(text.escapeForRegExp(), "i");
1253 } else {
1254 regex = this._textFilterUI.regex();
1255 }
1256
1257 var filter = WebInspector.NetworkLogView._requestPathFilter.bind(null, r egex);
1258 if (negative)
1259 filter = WebInspector.NetworkLogView._negativeFilter.bind(null, filt er);
1260 return filter;
1261 },
1262
1263 /**
1264 * @param {!WebInspector.NetworkLogView.FilterType} type
1265 * @param {string} value
1266 * @param {boolean} negative
1267 * @return {!WebInspector.NetworkLogView.Filter}
1268 */
1269 _createFilter: function(type, value, negative)
1270 {
1271 var filter = this._createSpecialFilter(type, value);
1272 if (!filter)
1273 return this._createTextFilter((negative ? "-" : "") + type + ":" + v alue);
1274 if (negative)
1275 return WebInspector.NetworkLogView._negativeFilter.bind(null, filter );
1276 return filter;
1277 },
1278
1279 /**
1280 * @param {!WebInspector.NetworkLogView.FilterType} type
1281 * @param {string} value
1282 * @return {?WebInspector.NetworkLogView.Filter}
1283 */
1284 _createSpecialFilter: function(type, value)
1285 {
1286 switch (type) {
1287 case WebInspector.NetworkLogView.FilterType.Domain:
1288 return WebInspector.NetworkLogView._createRequestDomainFilter(value) ;
1289
1290 case WebInspector.NetworkLogView.FilterType.HasResponseHeader:
1291 return WebInspector.NetworkLogView._requestResponseHeaderFilter.bind (null, value);
1292
1293 case WebInspector.NetworkLogView.FilterType.Is:
1294 if (value.toLowerCase() === WebInspector.NetworkLogView.IsFilterType .Running)
1295 return WebInspector.NetworkLogView._runningRequestFilter;
1296 break;
1297
1298 case WebInspector.NetworkLogView.FilterType.LargerThan:
1299 return this._createSizeFilter(value.toLowerCase());
1300
1301 case WebInspector.NetworkLogView.FilterType.Method:
1302 return WebInspector.NetworkLogView._requestMethodFilter.bind(null, v alue);
1303
1304 case WebInspector.NetworkLogView.FilterType.MimeType:
1305 return WebInspector.NetworkLogView._requestMimeTypeFilter.bind(null, value);
1306
1307 case WebInspector.NetworkLogView.FilterType.MixedContent:
1308 return WebInspector.NetworkLogView._requestMixedContentFilter.bind(n ull, /** @type {!WebInspector.NetworkLogView.MixedContentFilterValues} */ (value ));
1309
1310 case WebInspector.NetworkLogView.FilterType.Scheme:
1311 return WebInspector.NetworkLogView._requestSchemeFilter.bind(null, v alue);
1312
1313 case WebInspector.NetworkLogView.FilterType.SetCookieDomain:
1314 return WebInspector.NetworkLogView._requestSetCookieDomainFilter.bin d(null, value);
1315
1316 case WebInspector.NetworkLogView.FilterType.SetCookieName:
1317 return WebInspector.NetworkLogView._requestSetCookieNameFilter.bind( null, value);
1318
1319 case WebInspector.NetworkLogView.FilterType.SetCookieValue:
1320 return WebInspector.NetworkLogView._requestSetCookieValueFilter.bind (null, value);
1321
1322 case WebInspector.NetworkLogView.FilterType.StatusCode:
1323 return WebInspector.NetworkLogView._statusCodeFilter.bind(null, valu e);
1324 }
1325 return null;
1326 },
1327
1328 /**
1329 * @param {string} value
1330 * @return {?WebInspector.NetworkLogView.Filter}
1331 */
1332 _createSizeFilter: function(value)
1333 {
1334 var multiplier = 1;
1335 if (value.endsWith("k")) {
1336 multiplier = 1024;
1337 value = value.substring(0, value.length - 1);
1338 } else if (value.endsWith("m")) {
1339 multiplier = 1024 * 1024;
1340 value = value.substring(0, value.length - 1);
1341 }
1342 var quantity = Number(value);
1343 if (isNaN(quantity))
1344 return null;
1345 return WebInspector.NetworkLogView._requestSizeLargerThanFilter.bind(nul l, quantity * multiplier);
1346 },
1347
1348 _filterRequests: function()
1349 {
1350 this._removeAllHighlights();
1351 this._invalidateAllItems();
1352 },
1353
1354 /**
1355 * @override
1356 */
1357 jumpToPreviousSearchResult: function()
1358 {
1359 if (!this._matchedRequestCount)
1360 return;
1361 var index = this._normalizeSearchResultIndex(this._currentMatchedRequest Index - 1);
1362 this._highlightNthMatchedRequestForSearch(index, true);
1363 },
1364
1365 /**
1366 * @override
1367 */
1368 jumpToNextSearchResult: function()
1369 {
1370 if (!this._matchedRequestCount)
1371 return;
1372 var index = this._normalizeSearchResultIndex(this._currentMatchedRequest Index + 1);
1373 this._highlightNthMatchedRequestForSearch(index, true);
1374 },
1375
1376 /**
1377 * @override
1378 */
1379 searchCanceled: function()
1380 {
1381 delete this._searchRegex;
1382 this._clearSearchMatchedList();
1383 this.dispatchEventToListeners(WebInspector.NetworkLogView.Events.SearchC ountUpdated, 0);
1384 },
1385
1386 /**
1387 * @param {!WebInspector.NetworkRequest} request
1388 */
1389 revealAndHighlightRequest: function(request)
1390 {
1391 this.removeAllNodeHighlights();
1392
1393 var node = this._nodesByRequestId.get(request.requestId);
1394 if (node) {
1395 node.reveal();
1396 this._highlightNode(node);
1397 }
1398 },
1399
1400 removeAllNodeHighlights: function()
1401 {
1402 if (this._highlightedNode) {
1403 this._highlightedNode.element().classList.remove("highlighted-row");
1404 delete this._highlightedNode;
1405 }
1406 },
1407
1408 /**
1409 * @param {!WebInspector.NetworkDataGridNode} node
1410 */
1411 _highlightNode: function(node)
1412 {
1413 WebInspector.runCSSAnimationOnce(node.element(), "highlighted-row");
1414 this._highlightedNode = node;
1415 },
1416
1417 /**
1418 * @param {!WebInspector.NetworkRequest} request
1419 * @param {string} platform
1420 * @return {string} 158 * @return {string}
1421 */ 159 */
1422 _generateCurlCommand: function(request, platform) 160 function escapeForRegExp(string) {
1423 { 161 return string.escapeForRegExp();
1424 var command = ["curl"]; 162 }
1425 // These headers are derived from URL (except "version") and would be ad ded by cURL anyway. 163 var escapedPattern = value.split('*').map(escapeForRegExp).join('.*');
1426 var ignoredHeaders = {"host": 1, "method": 1, "path": 1, "scheme": 1, "v ersion": 1}; 164 return WebInspector.NetworkLogView._requestDomainFilter.bind(null, new RegEx p('^' + escapedPattern + '$', 'i'));
1427 165 }
1428 function escapeStringWin(str) 166
1429 { 167 /**
1430 /* If there are no new line characters do not escape the " character s 168 * @param {!RegExp} regex
169 * @param {!WebInspector.NetworkRequest} request
170 * @return {boolean}
171 */
172 static _requestDomainFilter(regex, request) {
173 return regex.test(request.domain);
174 }
175
176 /**
177 * @param {!WebInspector.NetworkRequest} request
178 * @return {boolean}
179 */
180 static _runningRequestFilter(request) {
181 return !request.finished;
182 }
183
184 /**
185 * @param {string} value
186 * @param {!WebInspector.NetworkRequest} request
187 * @return {boolean}
188 */
189 static _requestResponseHeaderFilter(value, request) {
190 return request.responseHeaderValue(value) !== undefined;
191 }
192
193 /**
194 * @param {string} value
195 * @param {!WebInspector.NetworkRequest} request
196 * @return {boolean}
197 */
198 static _requestMethodFilter(value, request) {
199 return request.requestMethod === value;
200 }
201
202 /**
203 * @param {string} value
204 * @param {!WebInspector.NetworkRequest} request
205 * @return {boolean}
206 */
207 static _requestMimeTypeFilter(value, request) {
208 return request.mimeType === value;
209 }
210
211 /**
212 * @param {!WebInspector.NetworkLogView.MixedContentFilterValues} value
213 * @param {!WebInspector.NetworkRequest} request
214 * @return {boolean}
215 */
216 static _requestMixedContentFilter(value, request) {
217 if (value === WebInspector.NetworkLogView.MixedContentFilterValues.Displayed ) {
218 return request.mixedContentType === 'optionally-blockable';
219 } else if (value === WebInspector.NetworkLogView.MixedContentFilterValues.Bl ocked) {
220 return request.mixedContentType === 'blockable' && request.wasBlocked();
221 } else if (value === WebInspector.NetworkLogView.MixedContentFilterValues.Bl ockOverridden) {
222 return request.mixedContentType === 'blockable' && !request.wasBlocked();
223 } else if (value === WebInspector.NetworkLogView.MixedContentFilterValues.Al l) {
224 return request.mixedContentType !== 'none';
225 }
226 return false;
227 }
228
229 /**
230 * @param {string} value
231 * @param {!WebInspector.NetworkRequest} request
232 * @return {boolean}
233 */
234 static _requestSchemeFilter(value, request) {
235 return request.scheme === value;
236 }
237
238 /**
239 * @param {string} value
240 * @param {!WebInspector.NetworkRequest} request
241 * @return {boolean}
242 */
243 static _requestSetCookieDomainFilter(value, request) {
244 var cookies = request.responseCookies;
245 for (var i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
246 if (cookies[i].domain() === value)
247 return true;
248 }
249 return false;
250 }
251
252 /**
253 * @param {string} value
254 * @param {!WebInspector.NetworkRequest} request
255 * @return {boolean}
256 */
257 static _requestSetCookieNameFilter(value, request) {
258 var cookies = request.responseCookies;
259 for (var i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
260 if (cookies[i].name() === value)
261 return true;
262 }
263 return false;
264 }
265
266 /**
267 * @param {string} value
268 * @param {!WebInspector.NetworkRequest} request
269 * @return {boolean}
270 */
271 static _requestSetCookieValueFilter(value, request) {
272 var cookies = request.responseCookies;
273 for (var i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
274 if (cookies[i].value() === value)
275 return true;
276 }
277 return false;
278 }
279
280 /**
281 * @param {number} value
282 * @param {!WebInspector.NetworkRequest} request
283 * @return {boolean}
284 */
285 static _requestSizeLargerThanFilter(value, request) {
286 return request.transferSize >= value;
287 }
288
289 /**
290 * @param {string} value
291 * @param {!WebInspector.NetworkRequest} request
292 * @return {boolean}
293 */
294 static _statusCodeFilter(value, request) {
295 return ('' + request.statusCode) === value;
296 }
297
298 /**
299 * @param {!WebInspector.NetworkRequest} request
300 * @return {boolean}
301 */
302 static HTTPRequestsFilter(request) {
303 return request.parsedURL.isValid && (request.scheme in WebInspector.NetworkL ogView.HTTPSchemas);
304 }
305
306 /**
307 * @param {!WebInspector.NetworkRequest} request
308 * @return {boolean}
309 */
310 static FinishedRequestsFilter(request) {
311 return request.finished;
312 }
313
314 /**
315 * @param {number} windowStart
316 * @param {number} windowEnd
317 * @param {!WebInspector.NetworkRequest} request
318 * @return {boolean}
319 */
320 static _requestTimeFilter(windowStart, windowEnd, request) {
321 if (request.issueTime() > windowEnd)
322 return false;
323 if (request.endTime !== -1 && request.endTime < windowStart)
324 return false;
325 return true;
326 }
327
328 /**
329 * @return {number}
330 */
331 headerHeight() {
332 return this._headerHeight;
333 }
334
335 /**
336 * @param {boolean} recording
337 */
338 setRecording(recording) {
339 this._recording = recording;
340 this._updateSummaryBar();
341 }
342
343 /**
344 * @param {boolean} preserveLog
345 */
346 setPreserveLog(preserveLog) {
347 this._preserveLog = preserveLog;
348 }
349
350 /**
351 * @override
352 * @param {!WebInspector.Target} target
353 */
354 targetAdded(target) {
355 if (!target.parentTarget()) {
356 var resourceTreeModel = WebInspector.ResourceTreeModel.fromTarget(target);
357 if (resourceTreeModel) {
358 resourceTreeModel.addEventListener(
359 WebInspector.ResourceTreeModel.Events.MainFrameNavigated, this._main FrameNavigated, this);
360 resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.Events .Load, this._loadEventFired, this);
361 resourceTreeModel.addEventListener(
362 WebInspector.ResourceTreeModel.Events.DOMContentLoaded, this._domCon tentLoadedEventFired, this);
363 }
364 }
365 var networkLog = WebInspector.NetworkLog.fromTarget(target);
366 if (networkLog)
367 networkLog.requests().forEach(this._appendRequest.bind(this));
368 }
369
370 /**
371 * @override
372 * @param {!WebInspector.Target} target
373 */
374 targetRemoved(target) {
375 if (!target.parentTarget()) {
376 var resourceTreeModel = WebInspector.ResourceTreeModel.fromTarget(target);
377 if (resourceTreeModel) {
378 resourceTreeModel.removeEventListener(
379 WebInspector.ResourceTreeModel.Events.MainFrameNavigated, this._main FrameNavigated, this);
380 resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.Eve nts.Load, this._loadEventFired, this);
381 resourceTreeModel.removeEventListener(
382 WebInspector.ResourceTreeModel.Events.DOMContentLoaded, this._domCon tentLoadedEventFired, this);
383 }
384 }
385 }
386
387 /**
388 * @param {number} start
389 * @param {number} end
390 */
391 setWindow(start, end) {
392 if (!start && !end) {
393 this._timeFilter = null;
394 this._timeCalculator.setWindow(null);
395 } else {
396 this._timeFilter = WebInspector.NetworkLogView._requestTimeFilter.bind(nul l, start, end);
397 this._timeCalculator.setWindow(new WebInspector.NetworkTimeBoundary(start, end));
398 }
399 this._columns.updateDividersIfNeeded();
400 this._filterRequests();
401 }
402
403 clearSelection() {
404 if (this._dataGrid.selectedNode)
405 this._dataGrid.selectedNode.deselect();
406 }
407
408 _addFilters() {
409 this._textFilterUI = new WebInspector.TextFilterUI(true);
410 this._textFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChang ed, this._filterChanged, this);
411 this._filterBar.addFilter(this._textFilterUI);
412
413 var dataURLSetting = this._networkHideDataURLSetting;
414 this._dataURLFilterUI = new WebInspector.CheckboxFilterUI(
415 'hide-data-url', WebInspector.UIString('Hide data URLs'), true, dataURLS etting);
416 this._dataURLFilterUI.addEventListener(
417 WebInspector.FilterUI.Events.FilterChanged, this._filterChanged.bind(thi s), this);
418 this._filterBar.addFilter(this._dataURLFilterUI);
419
420 var filterItems = [];
421 for (var categoryId in WebInspector.resourceCategories) {
422 var category = WebInspector.resourceCategories[categoryId];
423 filterItems.push({name: category.title, label: category.shortTitle, title: category.title});
424 }
425 this._resourceCategoryFilterUI =
426 new WebInspector.NamedBitSetFilterUI(filterItems, this._networkResourceT ypeFiltersSetting);
427 this._resourceCategoryFilterUI.addEventListener(
428 WebInspector.FilterUI.Events.FilterChanged, this._filterChanged.bind(thi s), this);
429 this._filterBar.addFilter(this._resourceCategoryFilterUI);
430 }
431
432 _resetSuggestionBuilder() {
433 this._suggestionBuilder = new WebInspector.FilterSuggestionBuilder(WebInspec tor.NetworkLogView._searchKeys);
434 this._suggestionBuilder.addItem(
435 WebInspector.NetworkLogView.FilterType.Is, WebInspector.NetworkLogView.I sFilterType.Running);
436 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.Large rThan, '100');
437 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.Large rThan, '10k');
438 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.Large rThan, '1M');
439 this._textFilterUI.setSuggestionBuilder(this._suggestionBuilder);
440 }
441
442 /**
443 * @param {!WebInspector.Event} event
444 */
445 _filterChanged(event) {
446 this.removeAllNodeHighlights();
447 this._parseFilterQuery(this._textFilterUI.value());
448 this._filterRequests();
449 }
450
451 _initializeView() {
452 this.element.id = 'network-container';
453 this._setupDataGrid();
454
455 this._columns.show(this.element);
456
457 this._summaryBarElement = this.element.createChild('div', 'network-summary-b ar');
458
459 this._columns.sortByCurrentColumn();
460 }
461
462 _showRecordingHint() {
463 this._hideRecordingHint();
464 this._recordingHint = this.element.createChild('div', 'network-status-pane f ill');
465 var hintText = this._recordingHint.createChild('div', 'recording-hint');
466 var reloadShortcutNode = this._recordingHint.createChild('b');
467 reloadShortcutNode.textContent = WebInspector.shortcutRegistry.shortcutDescr iptorsForAction('main.reload')[0].name;
468
469 if (this._recording) {
470 var recordingText = hintText.createChild('span');
471 recordingText.textContent = WebInspector.UIString('Recording network activ ity\u2026');
472 hintText.createChild('br');
473 hintText.appendChild(
474 WebInspector.formatLocalized('Perform a request or hit %s to record th e reload.', [reloadShortcutNode]));
475 } else {
476 var recordNode = hintText.createChild('b');
477 recordNode.textContent = WebInspector.shortcutRegistry.shortcutTitleForAct ion('network.toggle-recording');
478 hintText.appendChild(WebInspector.formatLocalized(
479 'Record (%s) or reload (%s) to display network activity.', [recordNode , reloadShortcutNode]));
480 }
481 }
482
483 _hideRecordingHint() {
484 if (this._recordingHint)
485 this._recordingHint.remove();
486 delete this._recordingHint;
487 }
488
489 /**
490 * @override
491 * @return {!Array.<!Element>}
492 */
493 elementsToRestoreScrollPositionsFor() {
494 if (!this._dataGrid) // Not initialized yet.
495 return [];
496 return [this._dataGrid.scrollContainer];
497 }
498
499 _setupDataGrid() {
500 this._dataGrid = this._columns.dataGrid();
501 this._dataGrid.setRowContextMenuCallback(
502 (contextMenu, node) => this.handleContextMenuForRequest(contextMenu, nod e.request()));
503 this._dataGrid.setStickToBottom(true);
504 this._dataGrid.setName('networkLog');
505 this._dataGrid.setResizeMethod(WebInspector.DataGrid.ResizeMethod.Last);
506 this._dataGrid.element.classList.add('network-log-grid');
507 this._dataGrid.element.addEventListener('mousedown', this._dataGridMouseDown .bind(this), true);
508 this._dataGrid.element.addEventListener('mousemove', this._dataGridMouseMove .bind(this), true);
509 this._dataGrid.element.addEventListener('mouseleave', this._dataGridMouseLea ve.bind(this), true);
510 }
511
512 /**
513 * @param {!Event} event
514 */
515 _dataGridMouseMove(event) {
516 var node = this._dataGrid.dataGridNodeFromNode(event.target);
517 var highlightInitiatorChain = event.shiftKey;
518 this._setHoveredNode(node, highlightInitiatorChain);
519 this._highlightInitiatorChain((highlightInitiatorChain && node) ? node.reque st() : null);
520 }
521
522 _dataGridMouseLeave() {
523 this._setHoveredNode(null);
524 this._highlightInitiatorChain(null);
525 }
526
527 /**
528 * @param {?WebInspector.NetworkRequest} request
529 * @param {boolean} highlightInitiatorChain
530 */
531 setHoveredRequest(request, highlightInitiatorChain) {
532 this._setHoveredNode(request ? this._nodesByRequestId.get(request.requestId) : null, highlightInitiatorChain);
533 this._highlightInitiatorChain((request && highlightInitiatorChain) ? request : null);
534 }
535
536 /**
537 * @param {?WebInspector.NetworkDataGridNode} node
538 * @param {boolean=} highlightInitiatorChain
539 */
540 _setHoveredNode(node, highlightInitiatorChain) {
541 if (this._hoveredNode)
542 this._hoveredNode.element().classList.remove('hover');
543 this._hoveredNode = node;
544 if (this._hoveredNode)
545 this._hoveredNode.element().classList.add('hover');
546 this._columns.setHoveredRequest(this._hoveredNode ? this._hoveredNode.reques t() : null, !!highlightInitiatorChain);
547 }
548
549 /**
550 * @param {!Event} event
551 */
552 _dataGridMouseDown(event) {
553 if ((!this._dataGrid.selectedNode && event.button) || event.target.enclosing NodeOrSelfWithNodeName('a'))
554 event.consume();
555 }
556
557 /**
558 * @param {?WebInspector.NetworkRequest} request
559 */
560 _highlightInitiatorChain(request) {
561 if (this._requestWithHighlightedInitiators === request)
562 return;
563 this._requestWithHighlightedInitiators = request;
564
565 if (!request) {
566 for (var node of this._nodesByRequestId.values()) {
567 if (!node.dataGrid)
568 continue;
569 node.element().classList.remove('network-node-on-initiator-path', 'netwo rk-node-on-initiated-path');
570 }
571 return;
572 }
573
574 var initiatorGraph = request.initiatorGraph();
575 for (var node of this._nodesByRequestId.values()) {
576 if (!node.dataGrid)
577 continue;
578 node.element().classList.toggle(
579 'network-node-on-initiator-path',
580 node.request() !== request && initiatorGraph.initiators.has(node.reque st()));
581 node.element().classList.toggle(
582 'network-node-on-initiated-path', node.request() !== request && initia torGraph.initiated.has(node.request()));
583 }
584 }
585
586 _updateSummaryBar() {
587 var requestsNumber = this._nodesByRequestId.size;
588
589 if (!requestsNumber) {
590 this._showRecordingHint();
591 return;
592 }
593 this._hideRecordingHint();
594
595 var transferSize = 0;
596 var selectedRequestsNumber = 0;
597 var selectedTransferSize = 0;
598 var baseTime = -1;
599 var maxTime = -1;
600 var nodes = this._nodesByRequestId.valuesArray();
601 for (var i = 0; i < nodes.length; ++i) {
602 var request = nodes[i].request();
603 var requestTransferSize = request.transferSize;
604 transferSize += requestTransferSize;
605 if (!nodes[i][WebInspector.NetworkLogView._isFilteredOutSymbol]) {
606 selectedRequestsNumber++;
607 selectedTransferSize += requestTransferSize;
608 }
609 if (request.url === request.target().inspectedURL() &&
610 request.resourceType() === WebInspector.resourceTypes.Document)
611 baseTime = request.startTime;
612 if (request.endTime > maxTime)
613 maxTime = request.endTime;
614 }
615
616 var summaryBar = this._summaryBarElement;
617 summaryBar.removeChildren();
618 var separator = '\u2002\u2758\u2002';
619 var text = '';
620 /**
621 * @param {string} chunk
622 * @return {!Element}
623 */
624 function appendChunk(chunk) {
625 var span = summaryBar.createChild('span');
626 span.textContent = chunk;
627 text += chunk;
628 return span;
629 }
630
631 if (selectedRequestsNumber !== requestsNumber) {
632 appendChunk(WebInspector.UIString('%d / %d requests', selectedRequestsNumb er, requestsNumber));
633 appendChunk(separator);
634 appendChunk(WebInspector.UIString(
635 '%s / %s transferred', Number.bytesToString(selectedTransferSize), Num ber.bytesToString(transferSize)));
636 } else {
637 appendChunk(WebInspector.UIString('%d requests', requestsNumber));
638 appendChunk(separator);
639 appendChunk(WebInspector.UIString('%s transferred', Number.bytesToString(t ransferSize)));
640 }
641 if (baseTime !== -1 && maxTime !== -1) {
642 appendChunk(separator);
643 appendChunk(WebInspector.UIString('Finish: %s', Number.secondsToString(max Time - baseTime)));
644 if (this._mainRequestDOMContentLoadedTime !== -1 && this._mainRequestDOMCo ntentLoadedTime > baseTime) {
645 appendChunk(separator);
646 var domContentLoadedText = WebInspector.UIString(
647 'DOMContentLoaded: %s', Number.secondsToString(this._mainRequestDOMC ontentLoadedTime - baseTime));
648 appendChunk(domContentLoadedText).classList.add('summary-blue');
649 }
650 if (this._mainRequestLoadTime !== -1) {
651 appendChunk(separator);
652 var loadText = WebInspector.UIString('Load: %s', Number.secondsToString( this._mainRequestLoadTime - baseTime));
653 appendChunk(loadText).classList.add('summary-red');
654 }
655 }
656 summaryBar.title = text;
657 }
658
659 scheduleRefresh() {
660 if (this._needsRefresh)
661 return;
662
663 this._needsRefresh = true;
664
665 if (this.isShowing() && !this._refreshRequestId)
666 this._refreshRequestId = this.element.window().requestAnimationFrame(this. _refresh.bind(this));
667 }
668
669 /**
670 * @param {!Array<number>} times
671 */
672 addFilmStripFrames(times) {
673 this._columns.addEventDividers(times, 'network-frame-divider');
674 }
675
676 /**
677 * @param {number} time
678 */
679 selectFilmStripFrame(time) {
680 this._columns.selectFilmStripFrame(time);
681 }
682
683 clearFilmStripFrame() {
684 this._columns.clearFilmStripFrame();
685 }
686
687 _refreshIfNeeded() {
688 if (this._needsRefresh)
689 this._refresh();
690 }
691
692 _invalidateAllItems() {
693 var requestIds = this._nodesByRequestId.keysArray();
694 for (var i = 0; i < requestIds.length; ++i)
695 this._staleRequestIds[requestIds[i]] = true;
696 this._refresh();
697 }
698
699 /**
700 * @return {!WebInspector.NetworkTimeCalculator}
701 */
702 timeCalculator() {
703 return this._timeCalculator;
704 }
705
706 /**
707 * @return {!WebInspector.NetworkTimeCalculator}
708 */
709 calculator() {
710 return this._calculator;
711 }
712
713 /**
714 * @param {!WebInspector.NetworkTimeCalculator} x
715 */
716 setCalculator(x) {
717 if (!x || this._calculator === x)
718 return;
719
720 if (this._calculator !== x) {
721 this._calculator = x;
722 this._columns.setCalculator(this._calculator);
723 }
724 this._calculator.reset();
725
726 if (this._calculator.startAtZero)
727 this._columns.hideEventDividers();
728 else
729 this._columns.showEventDividers();
730
731 this._invalidateAllItems();
732 }
733
734 /**
735 * @param {!WebInspector.Event} event
736 */
737 _loadEventFired(event) {
738 if (!this._recording)
739 return;
740
741 var data = /** @type {number} */ (event.data);
742 if (data) {
743 this._mainRequestLoadTime = data;
744 this._columns.addEventDividers([data], 'network-red-divider');
745 }
746 }
747
748 /**
749 * @param {!WebInspector.Event} event
750 */
751 _domContentLoadedEventFired(event) {
752 if (!this._recording)
753 return;
754 var data = /** @type {number} */ (event.data);
755 if (data) {
756 this._mainRequestDOMContentLoadedTime = data;
757 this._columns.addEventDividers([data], 'network-blue-divider');
758 }
759 }
760
761 /**
762 * @override
763 */
764 wasShown() {
765 this._refreshIfNeeded();
766 this._columns.wasShown();
767 }
768
769 /**
770 * @override
771 */
772 willHide() {
773 this._columns.willHide();
774 }
775
776 _refresh() {
777 this._needsRefresh = false;
778
779 if (this._refreshRequestId) {
780 this.element.window().cancelAnimationFrame(this._refreshRequestId);
781 delete this._refreshRequestId;
782 }
783
784 this.removeAllNodeHighlights();
785
786 var oldBoundary = this.calculator().boundary();
787 this._timeCalculator.updateBoundariesForEventTime(this._mainRequestLoadTime) ;
788 this._durationCalculator.updateBoundariesForEventTime(this._mainRequestLoadT ime);
789 this._timeCalculator.updateBoundariesForEventTime(this._mainRequestDOMConten tLoadedTime);
790 this._durationCalculator.updateBoundariesForEventTime(this._mainRequestDOMCo ntentLoadedTime);
791
792 var dataGrid = this._dataGrid;
793 var rootNode = dataGrid.rootNode();
794 /** @type {!Array<!WebInspector.NetworkDataGridNode> } */
795 var nodesToInsert = [];
796 /** @type {!Array<!WebInspector.NetworkDataGridNode> } */
797 var nodesToRefresh = [];
798 for (var requestId in this._staleRequestIds) {
799 var node = this._nodesByRequestId.get(requestId);
800 if (!node)
801 continue;
802 var isFilteredOut = !this._applyFilter(node);
803 if (isFilteredOut && node === this._hoveredNode)
804 this._setHoveredNode(null);
805 if (node[WebInspector.NetworkLogView._isFilteredOutSymbol] !== isFilteredO ut) {
806 if (!node[WebInspector.NetworkLogView._isFilteredOutSymbol])
807 rootNode.removeChild(node);
808
809 node[WebInspector.NetworkLogView._isFilteredOutSymbol] = isFilteredOut;
810
811 if (!node[WebInspector.NetworkLogView._isFilteredOutSymbol])
812 nodesToInsert.push(node);
813 }
814 if (!isFilteredOut)
815 nodesToRefresh.push(node);
816 var request = node.request();
817 this._timeCalculator.updateBoundaries(request);
818 this._durationCalculator.updateBoundaries(request);
819 }
820
821 for (var i = 0; i < nodesToInsert.length; ++i) {
822 var node = nodesToInsert[i];
823 var request = node.request();
824 dataGrid.insertChild(node);
825 node[WebInspector.NetworkLogView._isMatchingSearchQuerySymbol] = this._mat chRequest(request);
826 }
827
828 for (var node of nodesToRefresh)
829 node.refresh();
830
831 this._highlightNthMatchedRequestForSearch(
832 this._updateMatchCountAndFindMatchIndex(this._currentMatchedRequestNode) , false);
833
834 if (!this.calculator().boundary().equals(oldBoundary)) {
835 // The boundaries changed, so all item graphs are stale.
836 this._columns.updateDividersIfNeeded();
837 var nodes = this._nodesByRequestId.valuesArray();
838 for (var i = 0; i < nodes.length; ++i)
839 nodes[i].refreshGraph();
840 }
841
842 this._staleRequestIds = {};
843 this._updateSummaryBar();
844
845 this._columns.dataChanged();
846 }
847
848 reset() {
849 this._requestWithHighlightedInitiators = null;
850 this.dispatchEventToListeners(WebInspector.NetworkLogView.Events.RequestSele cted, null);
851
852 this._clearSearchMatchedList();
853
854 this._setHoveredNode(null);
855 this._columns.reset();
856
857 this._timeFilter = null;
858 this._calculator.reset();
859
860 this._timeCalculator.setWindow(null);
861
862 var nodes = this._nodesByRequestId.valuesArray();
863 for (var i = 0; i < nodes.length; ++i)
864 nodes[i].dispose();
865
866 this._nodesByRequestId.clear();
867 this._staleRequestIds = {};
868 this._resetSuggestionBuilder();
869
870 this._mainRequestLoadTime = -1;
871 this._mainRequestDOMContentLoadedTime = -1;
872
873 if (this._dataGrid) {
874 this._dataGrid.rootNode().removeChildren();
875 this._updateSummaryBar();
876 }
877 }
878
879 /**
880 * @param {string} filterString
881 */
882 setTextFilterValue(filterString) {
883 this._textFilterUI.setValue(filterString);
884 this._textFilterUI.setRegexChecked(false);
885 this._dataURLFilterUI.setChecked(false);
886 this._resourceCategoryFilterUI.reset();
887 }
888
889 /**
890 * @param {!WebInspector.Event} event
891 */
892 _onRequestStarted(event) {
893 if (!this._recording)
894 return;
895 var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
896 this._appendRequest(request);
897 }
898
899 /**
900 * @param {!WebInspector.NetworkRequest} request
901 */
902 _appendRequest(request) {
903 var node = new WebInspector.NetworkDataGridNode(this, request);
904 node[WebInspector.NetworkLogView._isFilteredOutSymbol] = true;
905 node[WebInspector.NetworkLogView._isMatchingSearchQuerySymbol] = false;
906
907 // In case of redirect request id is reassigned to a redirected
908 // request and we need to update _nodesByRequestId and search results.
909 var originalRequestNode = this._nodesByRequestId.get(request.requestId);
910 if (originalRequestNode)
911 this._nodesByRequestId.set(originalRequestNode.request().requestId, origin alRequestNode);
912 this._nodesByRequestId.set(request.requestId, node);
913
914 // Pull all the redirects of the main request upon commit load.
915 if (request.redirects) {
916 for (var i = 0; i < request.redirects.length; ++i)
917 this._refreshRequest(request.redirects[i]);
918 }
919
920 this._refreshRequest(request);
921 }
922
923 /**
924 * @param {!WebInspector.Event} event
925 */
926 _onRequestUpdated(event) {
927 var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
928 this._refreshRequest(request);
929 }
930
931 /**
932 * @param {!WebInspector.NetworkRequest} request
933 */
934 _refreshRequest(request) {
935 if (!this._nodesByRequestId.get(request.requestId))
936 return;
937
938 WebInspector.NetworkLogView._subdomains(request.domain)
939 .forEach(this._suggestionBuilder.addItem.bind(
940 this._suggestionBuilder, WebInspector.NetworkLogView.FilterType.Doma in));
941 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.Metho d, request.requestMethod);
942 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.MimeT ype, request.mimeType);
943 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.Schem e, '' + request.scheme);
944 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.Statu sCode, '' + request.statusCode);
945
946 if (request.mixedContentType !== 'none') {
947 this._suggestionBuilder.addItem(
948 WebInspector.NetworkLogView.FilterType.MixedContent,
949 WebInspector.NetworkLogView.MixedContentFilterValues.All);
950 }
951
952 if (request.mixedContentType === 'optionally-blockable') {
953 this._suggestionBuilder.addItem(
954 WebInspector.NetworkLogView.FilterType.MixedContent,
955 WebInspector.NetworkLogView.MixedContentFilterValues.Displayed);
956 }
957
958 if (request.mixedContentType === 'blockable') {
959 var suggestion = request.wasBlocked() ? WebInspector.NetworkLogView.MixedC ontentFilterValues.Blocked :
960 WebInspector.NetworkLogView.MixedC ontentFilterValues.BlockOverridden;
961 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.Mix edContent, suggestion);
962 }
963
964 var responseHeaders = request.responseHeaders;
965 for (var i = 0, l = responseHeaders.length; i < l; ++i)
966 this._suggestionBuilder.addItem(
967 WebInspector.NetworkLogView.FilterType.HasResponseHeader, responseHead ers[i].name);
968 var cookies = request.responseCookies;
969 for (var i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
970 var cookie = cookies[i];
971 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.Set CookieDomain, cookie.domain());
972 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.Set CookieName, cookie.name());
973 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.Set CookieValue, cookie.value());
974 }
975
976 this._staleRequestIds[request.requestId] = true;
977 this.dispatchEventToListeners(WebInspector.NetworkLogView.Events.UpdateReque st, request);
978 this.scheduleRefresh();
979 }
980
981 /**
982 * @param {!WebInspector.Event} event
983 */
984 _mainFrameNavigated(event) {
985 if (!this._recording)
986 return;
987
988 var frame = /** @type {!WebInspector.ResourceTreeFrame} */ (event.data);
989 var loaderId = frame.loaderId;
990
991 // Pick provisional load requests.
992 var requestsToPick = [];
993 var networkLog = WebInspector.NetworkLog.fromTarget(frame.target());
994 var requests = networkLog ? networkLog.requests() : [];
995 for (var i = 0; i < requests.length; ++i) {
996 var request = requests[i];
997 if (request.loaderId === loaderId)
998 requestsToPick.push(request);
999 }
1000
1001 if (!this._preserveLog) {
1002 this.reset();
1003 for (var i = 0; i < requestsToPick.length; ++i)
1004 this._appendRequest(requestsToPick[i]);
1005 }
1006 for (var i = 0; i < requestsToPick.length; ++i) {
1007 var request = requestsToPick[i];
1008 var node = this._nodesByRequestId.get(request.requestId);
1009 if (node) {
1010 node.markAsNavigationRequest();
1011 break;
1012 }
1013 }
1014 }
1015
1016 /**
1017 * @return {number}
1018 */
1019 rowHeight() {
1020 return this._rowHeight;
1021 }
1022
1023 /**
1024 * @param {boolean} gridMode
1025 */
1026 switchViewMode(gridMode) {
1027 this._columns.switchViewMode(gridMode);
1028 }
1029
1030 /**
1031 * @param {!WebInspector.ContextMenu} contextMenu
1032 * @param {!WebInspector.NetworkRequest} request
1033 */
1034 handleContextMenuForRequest(contextMenu, request) {
1035 contextMenu.appendApplicableItems(request);
1036 var copyMenu = contextMenu.appendSubMenuItem(WebInspector.UIString('Copy'));
1037 if (request) {
1038 copyMenu.appendItem(
1039 WebInspector.copyLinkAddressLabel(),
1040 InspectorFrontendHost.copyText.bind(InspectorFrontendHost, request.con tentURL()));
1041 copyMenu.appendSeparator();
1042
1043 if (request.requestHeadersText())
1044 copyMenu.appendItem(
1045 WebInspector.UIString.capitalize('Copy ^request ^headers'), this._co pyRequestHeaders.bind(this, request));
1046 if (request.responseHeadersText)
1047 copyMenu.appendItem(
1048 WebInspector.UIString.capitalize('Copy ^response ^headers'), this._c opyResponseHeaders.bind(this, request));
1049 if (request.finished)
1050 copyMenu.appendItem(WebInspector.UIString.capitalize('Copy ^response'), this._copyResponse.bind(this, request));
1051
1052 if (WebInspector.isWin()) {
1053 copyMenu.appendItem(
1054 WebInspector.UIString('Copy as cURL (cmd)'), this._copyCurlCommand.b ind(this, request, 'win'));
1055 copyMenu.appendItem(
1056 WebInspector.UIString('Copy as cURL (bash)'), this._copyCurlCommand. bind(this, request, 'unix'));
1057 copyMenu.appendItem(
1058 WebInspector.UIString('Copy All as cURL (cmd)'), this._copyAllCurlCo mmand.bind(this, 'win'));
1059 copyMenu.appendItem(
1060 WebInspector.UIString('Copy All as cURL (bash)'), this._copyAllCurlC ommand.bind(this, 'unix'));
1061 } else {
1062 copyMenu.appendItem(WebInspector.UIString('Copy as cURL'), this._copyCur lCommand.bind(this, request, 'unix'));
1063 copyMenu.appendItem(WebInspector.UIString('Copy All as cURL'), this._cop yAllCurlCommand.bind(this, 'unix'));
1064 }
1065 } else {
1066 copyMenu = contextMenu.appendSubMenuItem(WebInspector.UIString('Copy'));
1067 }
1068 copyMenu.appendItem(WebInspector.UIString.capitalize('Copy ^all as HAR'), th is._copyAll.bind(this));
1069
1070 contextMenu.appendSeparator();
1071 contextMenu.appendItem(WebInspector.UIString.capitalize('Save as HAR with ^c ontent'), this._exportAll.bind(this));
1072
1073 contextMenu.appendSeparator();
1074 contextMenu.appendItem(
1075 WebInspector.UIString.capitalize('Clear ^browser ^cache'), this._clearBr owserCache.bind(this));
1076 contextMenu.appendItem(
1077 WebInspector.UIString.capitalize('Clear ^browser ^cookies'), this._clear BrowserCookies.bind(this));
1078
1079 var blockedSetting = WebInspector.moduleSetting('blockedURLs');
1080 if (request && Runtime.experiments.isEnabled('requestBlocking')) { // Disab led until ready.
1081 contextMenu.appendSeparator();
1082
1083 var urlWithoutScheme = request.parsedURL.urlWithoutScheme();
1084 if (urlWithoutScheme && blockedSetting.get().indexOf(urlWithoutScheme) === -1)
1085 contextMenu.appendItem(
1086 WebInspector.UIString.capitalize('Block ^request URL'), addBlockedUR L.bind(null, urlWithoutScheme));
1087
1088 var domain = request.parsedURL.domain();
1089 if (domain && blockedSetting.get().indexOf(domain) === -1)
1090 contextMenu.appendItem(
1091 WebInspector.UIString.capitalize('Block ^request ^domain'), addBlock edURL.bind(null, domain));
1092
1093 function addBlockedURL(url) {
1094 var list = blockedSetting.get();
1095 list.push(url);
1096 blockedSetting.set(list);
1097 WebInspector.viewManager.showView('network.blocked-urls');
1098 }
1099 }
1100
1101 if (request && request.resourceType() === WebInspector.resourceTypes.XHR) {
1102 contextMenu.appendSeparator();
1103 contextMenu.appendItem(WebInspector.UIString('Replay XHR'), request.replay XHR.bind(request));
1104 contextMenu.appendSeparator();
1105 }
1106 }
1107
1108 _harRequests() {
1109 var requests = this._nodesByRequestId.valuesArray().map(function(node) {
1110 return node.request();
1111 });
1112 var httpRequests = requests.filter(WebInspector.NetworkLogView.HTTPRequestsF ilter);
1113 return httpRequests.filter(WebInspector.NetworkLogView.FinishedRequestsFilte r);
1114 }
1115
1116 _copyAll() {
1117 var harArchive = {log: (new WebInspector.HARLog(this._harRequests())).build( )};
1118 InspectorFrontendHost.copyText(JSON.stringify(harArchive, null, 2));
1119 }
1120
1121 /**
1122 * @param {!WebInspector.NetworkRequest} request
1123 */
1124 _copyRequestHeaders(request) {
1125 InspectorFrontendHost.copyText(request.requestHeadersText());
1126 }
1127
1128 /**
1129 * @param {!WebInspector.NetworkRequest} request
1130 */
1131 _copyResponse(request) {
1132 /**
1133 * @param {?string} content
1134 */
1135 function callback(content) {
1136 if (request.contentEncoded)
1137 content = request.asDataURL();
1138 InspectorFrontendHost.copyText(content || '');
1139 }
1140 request.requestContent().then(callback);
1141 }
1142
1143 /**
1144 * @param {!WebInspector.NetworkRequest} request
1145 */
1146 _copyResponseHeaders(request) {
1147 InspectorFrontendHost.copyText(request.responseHeadersText);
1148 }
1149
1150 /**
1151 * @param {!WebInspector.NetworkRequest} request
1152 * @param {string} platform
1153 */
1154 _copyCurlCommand(request, platform) {
1155 InspectorFrontendHost.copyText(this._generateCurlCommand(request, platform)) ;
1156 }
1157
1158 /**
1159 * @param {string} platform
1160 */
1161 _copyAllCurlCommand(platform) {
1162 var requests = this._nodesByRequestId.valuesArray().map(node => node.request ());
1163 var commands = [];
1164 for (var request of requests)
1165 commands.push(this._generateCurlCommand(request, platform));
1166 if (platform === 'win')
1167 InspectorFrontendHost.copyText(commands.join(' &\r\n'));
1168 else
1169 InspectorFrontendHost.copyText(commands.join(' ;\n'));
1170 }
1171
1172 _exportAll() {
1173 var url = WebInspector.targetManager.mainTarget().inspectedURL();
1174 var parsedURL = url.asParsedURL();
1175 var filename = parsedURL ? parsedURL.host : 'network-log';
1176 var stream = new WebInspector.FileOutputStream();
1177 stream.open(filename + '.har', openCallback.bind(this));
1178
1179 /**
1180 * @param {boolean} accepted
1181 * @this {WebInspector.NetworkLogView}
1182 */
1183 function openCallback(accepted) {
1184 if (!accepted)
1185 return;
1186 var progressIndicator = new WebInspector.ProgressIndicator();
1187 this._progressBarContainer.appendChild(progressIndicator.element);
1188 var harWriter = new WebInspector.HARWriter();
1189 harWriter.write(stream, this._harRequests(), progressIndicator);
1190 }
1191 }
1192
1193 _clearBrowserCache() {
1194 if (confirm(WebInspector.UIString('Are you sure you want to clear browser ca che?')))
1195 WebInspector.multitargetNetworkManager.clearBrowserCache();
1196 }
1197
1198 _clearBrowserCookies() {
1199 if (confirm(WebInspector.UIString('Are you sure you want to clear browser co okies?')))
1200 WebInspector.multitargetNetworkManager.clearBrowserCookies();
1201 }
1202
1203 /**
1204 * @param {!WebInspector.NetworkRequest} request
1205 * @return {boolean}
1206 */
1207 _matchRequest(request) {
1208 var re = this._searchRegex;
1209 if (!re)
1210 return false;
1211
1212 var text = this._networkLogLargeRowsSetting.get() ? request.path() + '/' + r equest.name() : request.name();
1213 return re.test(text);
1214 }
1215
1216 _clearSearchMatchedList() {
1217 this._matchedRequestCount = -1;
1218 this._currentMatchedRequestNode = null;
1219 this._removeAllHighlights();
1220 }
1221
1222 _removeAllHighlights() {
1223 this.removeAllNodeHighlights();
1224 for (var i = 0; i < this._highlightedSubstringChanges.length; ++i)
1225 WebInspector.revertDomChanges(this._highlightedSubstringChanges[i]);
1226 this._highlightedSubstringChanges = [];
1227 }
1228
1229 dataGridSorted() {
1230 this._highlightNthMatchedRequestForSearch(
1231 this._updateMatchCountAndFindMatchIndex(this._currentMatchedRequestNode) , false);
1232 }
1233
1234 /**
1235 * @param {number} n
1236 * @param {boolean} reveal
1237 */
1238 _highlightNthMatchedRequestForSearch(n, reveal) {
1239 this._removeAllHighlights();
1240
1241 /** @type {!Array.<!WebInspector.NetworkDataGridNode>} */
1242 var nodes = this._dataGrid.rootNode().children;
1243 var matchCount = 0;
1244 var node = null;
1245 for (var i = 0; i < nodes.length; ++i) {
1246 if (nodes[i][WebInspector.NetworkLogView._isMatchingSearchQuerySymbol]) {
1247 if (matchCount === n) {
1248 node = nodes[i];
1249 break;
1250 }
1251 matchCount++;
1252 }
1253 }
1254 if (!node) {
1255 this._currentMatchedRequestNode = null;
1256 return;
1257 }
1258
1259 var request = node.request();
1260 if (reveal)
1261 WebInspector.Revealer.reveal(request);
1262 var highlightedSubstringChanges = node.highlightMatchedSubstring(this._searc hRegex);
1263 this._highlightedSubstringChanges.push(highlightedSubstringChanges);
1264
1265 this._currentMatchedRequestNode = node;
1266 this._currentMatchedRequestIndex = n;
1267 this.dispatchEventToListeners(WebInspector.NetworkLogView.Events.SearchIndex Updated, n);
1268 }
1269
1270 /**
1271 * @override
1272 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig
1273 * @param {boolean} shouldJump
1274 * @param {boolean=} jumpBackwards
1275 */
1276 performSearch(searchConfig, shouldJump, jumpBackwards) {
1277 var query = searchConfig.query;
1278 var currentMatchedRequestNode = this._currentMatchedRequestNode;
1279 this._clearSearchMatchedList();
1280 this._searchRegex = createPlainTextSearchRegex(query, 'i');
1281
1282 /** @type {!Array.<!WebInspector.NetworkDataGridNode>} */
1283 var nodes = this._dataGrid.rootNode().children;
1284 for (var i = 0; i < nodes.length; ++i)
1285 nodes[i][WebInspector.NetworkLogView._isMatchingSearchQuerySymbol] = this. _matchRequest(nodes[i].request());
1286 var newMatchedRequestIndex = this._updateMatchCountAndFindMatchIndex(current MatchedRequestNode);
1287 if (!newMatchedRequestIndex && jumpBackwards)
1288 newMatchedRequestIndex = this._matchedRequestCount - 1;
1289 this._highlightNthMatchedRequestForSearch(newMatchedRequestIndex, shouldJump );
1290 }
1291
1292 /**
1293 * @override
1294 * @return {boolean}
1295 */
1296 supportsCaseSensitiveSearch() {
1297 return false;
1298 }
1299
1300 /**
1301 * @override
1302 * @return {boolean}
1303 */
1304 supportsRegexSearch() {
1305 return true;
1306 }
1307
1308 /**
1309 * @param {?WebInspector.NetworkDataGridNode} node
1310 * @return {number}
1311 */
1312 _updateMatchCountAndFindMatchIndex(node) {
1313 /** @type {!Array.<!WebInspector.NetworkDataGridNode>} */
1314 var nodes = this._dataGrid.rootNode().children;
1315 var matchCount = 0;
1316 var matchIndex = 0;
1317 for (var i = 0; i < nodes.length; ++i) {
1318 if (!nodes[i][WebInspector.NetworkLogView._isMatchingSearchQuerySymbol])
1319 continue;
1320 if (node === nodes[i])
1321 matchIndex = matchCount;
1322 matchCount++;
1323 }
1324 if (this._matchedRequestCount !== matchCount) {
1325 this._matchedRequestCount = matchCount;
1326 this.dispatchEventToListeners(WebInspector.NetworkLogView.Events.SearchCou ntUpdated, matchCount);
1327 }
1328 return matchIndex;
1329 }
1330
1331 /**
1332 * @param {number} index
1333 * @return {number}
1334 */
1335 _normalizeSearchResultIndex(index) {
1336 return (index + this._matchedRequestCount) % this._matchedRequestCount;
1337 }
1338
1339 /**
1340 * @param {!WebInspector.NetworkDataGridNode} node
1341 * @return {boolean}
1342 */
1343 _applyFilter(node) {
1344 var request = node.request();
1345 if (this._timeFilter && !this._timeFilter(request))
1346 return false;
1347 var categoryName = request.resourceType().category().title;
1348 if (!this._resourceCategoryFilterUI.accept(categoryName))
1349 return false;
1350 if (this._dataURLFilterUI.checked() && request.parsedURL.isDataURL())
1351 return false;
1352 if (request.statusText === 'Service Worker Fallback Required')
1353 return false;
1354 for (var i = 0; i < this._filters.length; ++i) {
1355 if (!this._filters[i](request))
1356 return false;
1357 }
1358 return true;
1359 }
1360
1361 /**
1362 * @param {string} query
1363 */
1364 _parseFilterQuery(query) {
1365 var parsedQuery;
1366 if (this._textFilterUI.isRegexChecked() && query !== '')
1367 parsedQuery = {text: [query], filters: []};
1368 else
1369 parsedQuery = this._suggestionBuilder.parseQuery(query);
1370
1371 this._filters = parsedQuery.text.map(this._createTextFilter, this);
1372
1373 var n = parsedQuery.filters.length;
1374 for (var i = 0; i < n; ++i) {
1375 var filter = parsedQuery.filters[i];
1376 var filterType = /** @type {!WebInspector.NetworkLogView.FilterType} */ (f ilter.type.toLowerCase());
1377 this._filters.push(this._createFilter(filterType, filter.data, filter.nega tive));
1378 }
1379 }
1380
1381 /**
1382 * @param {string} text
1383 * @return {!WebInspector.NetworkLogView.Filter}
1384 */
1385 _createTextFilter(text) {
1386 var negative = false;
1387 /** @type {?RegExp} */
1388 var regex;
1389 if (!this._textFilterUI.isRegexChecked() && text[0] === '-' && text.length > 1) {
1390 negative = true;
1391 text = text.substring(1);
1392 regex = new RegExp(text.escapeForRegExp(), 'i');
1393 } else {
1394 regex = this._textFilterUI.regex();
1395 }
1396
1397 var filter = WebInspector.NetworkLogView._requestPathFilter.bind(null, regex );
1398 if (negative)
1399 filter = WebInspector.NetworkLogView._negativeFilter.bind(null, filter);
1400 return filter;
1401 }
1402
1403 /**
1404 * @param {!WebInspector.NetworkLogView.FilterType} type
1405 * @param {string} value
1406 * @param {boolean} negative
1407 * @return {!WebInspector.NetworkLogView.Filter}
1408 */
1409 _createFilter(type, value, negative) {
1410 var filter = this._createSpecialFilter(type, value);
1411 if (!filter)
1412 return this._createTextFilter((negative ? '-' : '') + type + ':' + value);
1413 if (negative)
1414 return WebInspector.NetworkLogView._negativeFilter.bind(null, filter);
1415 return filter;
1416 }
1417
1418 /**
1419 * @param {!WebInspector.NetworkLogView.FilterType} type
1420 * @param {string} value
1421 * @return {?WebInspector.NetworkLogView.Filter}
1422 */
1423 _createSpecialFilter(type, value) {
1424 switch (type) {
1425 case WebInspector.NetworkLogView.FilterType.Domain:
1426 return WebInspector.NetworkLogView._createRequestDomainFilter(value);
1427
1428 case WebInspector.NetworkLogView.FilterType.HasResponseHeader:
1429 return WebInspector.NetworkLogView._requestResponseHeaderFilter.bind(nul l, value);
1430
1431 case WebInspector.NetworkLogView.FilterType.Is:
1432 if (value.toLowerCase() === WebInspector.NetworkLogView.IsFilterType.Run ning)
1433 return WebInspector.NetworkLogView._runningRequestFilter;
1434 break;
1435
1436 case WebInspector.NetworkLogView.FilterType.LargerThan:
1437 return this._createSizeFilter(value.toLowerCase());
1438
1439 case WebInspector.NetworkLogView.FilterType.Method:
1440 return WebInspector.NetworkLogView._requestMethodFilter.bind(null, value );
1441
1442 case WebInspector.NetworkLogView.FilterType.MimeType:
1443 return WebInspector.NetworkLogView._requestMimeTypeFilter.bind(null, val ue);
1444
1445 case WebInspector.NetworkLogView.FilterType.MixedContent:
1446 return WebInspector.NetworkLogView._requestMixedContentFilter.bind(
1447 null, /** @type {!WebInspector.NetworkLogView.MixedContentFilterValu es} */ (value));
1448
1449 case WebInspector.NetworkLogView.FilterType.Scheme:
1450 return WebInspector.NetworkLogView._requestSchemeFilter.bind(null, value );
1451
1452 case WebInspector.NetworkLogView.FilterType.SetCookieDomain:
1453 return WebInspector.NetworkLogView._requestSetCookieDomainFilter.bind(nu ll, value);
1454
1455 case WebInspector.NetworkLogView.FilterType.SetCookieName:
1456 return WebInspector.NetworkLogView._requestSetCookieNameFilter.bind(null , value);
1457
1458 case WebInspector.NetworkLogView.FilterType.SetCookieValue:
1459 return WebInspector.NetworkLogView._requestSetCookieValueFilter.bind(nul l, value);
1460
1461 case WebInspector.NetworkLogView.FilterType.StatusCode:
1462 return WebInspector.NetworkLogView._statusCodeFilter.bind(null, value);
1463 }
1464 return null;
1465 }
1466
1467 /**
1468 * @param {string} value
1469 * @return {?WebInspector.NetworkLogView.Filter}
1470 */
1471 _createSizeFilter(value) {
1472 var multiplier = 1;
1473 if (value.endsWith('k')) {
1474 multiplier = 1024;
1475 value = value.substring(0, value.length - 1);
1476 } else if (value.endsWith('m')) {
1477 multiplier = 1024 * 1024;
1478 value = value.substring(0, value.length - 1);
1479 }
1480 var quantity = Number(value);
1481 if (isNaN(quantity))
1482 return null;
1483 return WebInspector.NetworkLogView._requestSizeLargerThanFilter.bind(null, q uantity * multiplier);
1484 }
1485
1486 _filterRequests() {
1487 this._removeAllHighlights();
1488 this._invalidateAllItems();
1489 }
1490
1491 /**
1492 * @override
1493 */
1494 jumpToPreviousSearchResult() {
1495 if (!this._matchedRequestCount)
1496 return;
1497 var index = this._normalizeSearchResultIndex(this._currentMatchedRequestInde x - 1);
1498 this._highlightNthMatchedRequestForSearch(index, true);
1499 }
1500
1501 /**
1502 * @override
1503 */
1504 jumpToNextSearchResult() {
1505 if (!this._matchedRequestCount)
1506 return;
1507 var index = this._normalizeSearchResultIndex(this._currentMatchedRequestInde x + 1);
1508 this._highlightNthMatchedRequestForSearch(index, true);
1509 }
1510
1511 /**
1512 * @override
1513 */
1514 searchCanceled() {
1515 delete this._searchRegex;
1516 this._clearSearchMatchedList();
1517 this.dispatchEventToListeners(WebInspector.NetworkLogView.Events.SearchCount Updated, 0);
1518 }
1519
1520 /**
1521 * @param {!WebInspector.NetworkRequest} request
1522 */
1523 revealAndHighlightRequest(request) {
1524 this.removeAllNodeHighlights();
1525
1526 var node = this._nodesByRequestId.get(request.requestId);
1527 if (node) {
1528 node.reveal();
1529 this._highlightNode(node);
1530 }
1531 }
1532
1533 removeAllNodeHighlights() {
1534 if (this._highlightedNode) {
1535 this._highlightedNode.element().classList.remove('highlighted-row');
1536 delete this._highlightedNode;
1537 }
1538 }
1539
1540 /**
1541 * @param {!WebInspector.NetworkDataGridNode} node
1542 */
1543 _highlightNode(node) {
1544 WebInspector.runCSSAnimationOnce(node.element(), 'highlighted-row');
1545 this._highlightedNode = node;
1546 }
1547
1548 /**
1549 * @param {!WebInspector.NetworkRequest} request
1550 * @param {string} platform
1551 * @return {string}
1552 */
1553 _generateCurlCommand(request, platform) {
1554 var command = ['curl'];
1555 // These headers are derived from URL (except "version") and would be added by cURL anyway.
1556 var ignoredHeaders = {'host': 1, 'method': 1, 'path': 1, 'scheme': 1, 'versi on': 1};
1557
1558 function escapeStringWin(str) {
1559 /* If there are no new line characters do not escape the " characters
1431 since it only uglifies the command. 1560 since it only uglifies the command.
1432 1561
1433 Because cmd.exe parser and MS Crt arguments parsers use some of t he 1562 Because cmd.exe parser and MS Crt arguments parsers use some of t he
1434 same escape characters, they can interact with each other in 1563 same escape characters, they can interact with each other in
1435 horrible ways, the order of operations is critical. 1564 horrible ways, the order of operations is critical.
1436 1565
1437 Replace \ with \\ first because it is an escape character for cer tain 1566 Replace \ with \\ first because it is an escape character for cer tain
1438 conditions in both parsers. 1567 conditions in both parsers.
1439 1568
1440 Replace all " with \" to ensure the first parser does not remove it. 1569 Replace all " with \" to ensure the first parser does not remove it.
1441 1570
1442 Then escape all characters we are not sure about with ^ to ensure it 1571 Then escape all characters we are not sure about with ^ to ensure it
1443 gets to MS Crt parser safely. 1572 gets to MS Crt parser safely.
1444 1573
1445 The % character is special because MS Crt parser will try and loo k for 1574 The % character is special because MS Crt parser will try and loo k for
1446 ENV variables and fill them in it's place. We cannot escape them with % 1575 ENV variables and fill them in it's place. We cannot escape them with %
1447 and cannot escape them with ^ (because it's cmd.exe's escape not MS Crt 1576 and cannot escape them with ^ (because it's cmd.exe's escape not MS Crt
1448 parser); So we can get cmd.exe parser to escape the character aft er it, 1577 parser); So we can get cmd.exe parser to escape the character aft er it,
1449 if it is followed by a valid beginning character of an ENV variab le. 1578 if it is followed by a valid beginning character of an ENV variab le.
1450 This ensures we do not try and double escape another ^ if it was placed 1579 This ensures we do not try and double escape another ^ if it was placed
1451 by the previous replace. 1580 by the previous replace.
1452 1581
1453 Lastly we replace new lines with ^ and TWO new lines because the first 1582 Lastly we replace new lines with ^ and TWO new lines because the first
1454 new line is there to enact the escape command the second is the c haracter 1583 new line is there to enact the escape command the second is the c haracter
1455 to escape (in this case new line). 1584 to escape (in this case new line).
1456 */ 1585 */
1457 var encapsChars = /[\r\n]/.test(str) ? "^\"" : "\""; 1586 var encapsChars = /[\r\n]/.test(str) ? '^"' : '"';
1458 return encapsChars + str.replace(/\\/g, "\\\\") 1587 return encapsChars +
1459 .replace(/"/g, "\\\"") 1588 str.replace(/\\/g, '\\\\')
1460 .replace(/[^a-zA-Z0-9\s_\-:=+~'\/.',?;()*`]/g, "^$& ") 1589 .replace(/"/g, '\\"')
1461 .replace(/%(?=[a-zA-Z0-9_])/g, "%^") 1590 .replace(/[^a-zA-Z0-9\s_\-:=+~'\/.',?;()*`]/g, '^$&')
1462 .replace(/\r\n|[\n\r]/g, "^\n\n") + encapsChars; 1591 .replace(/%(?=[a-zA-Z0-9_])/g, '%^')
1592 .replace(/\r\n|[\n\r]/g, '^\n\n') +
1593 encapsChars;
1594 }
1595
1596 function escapeStringPosix(str) {
1597 function escapeCharacter(x) {
1598 var code = x.charCodeAt(0);
1599 if (code < 256) {
1600 // Add leading zero when needed to not care about the next character.
1601 return code < 16 ? '\\x0' + code.toString(16) : '\\x' + code.toString( 16);
1463 } 1602 }
1603 code = code.toString(16);
1604 return '\\u' + ('0000' + code).substr(code.length, 4);
1605 }
1464 1606
1465 function escapeStringPosix(str) 1607 if (/[^\x20-\x7E]|\'/.test(str)) {
1466 { 1608 // Use ANSI-C quoting syntax.
1467 function escapeCharacter(x) 1609 return '$\'' +
1468 { 1610 str.replace(/\\/g, '\\\\')
1469 var code = x.charCodeAt(0); 1611 .replace(/\'/g, '\\\'')
1470 if (code < 256) { 1612 .replace(/\n/g, '\\n')
1471 // Add leading zero when needed to not care about the next c haracter. 1613 .replace(/\r/g, '\\r')
1472 return code < 16 ? "\\x0" + code.toString(16) : "\\x" + code .toString(16); 1614 .replace(/[^\x20-\x7E]/g, escapeCharacter) +
1473 } 1615 '\'';
1474 code = code.toString(16); 1616 } else {
1475 return "\\u" + ("0000" + code).substr(code.length, 4); 1617 // Use single quote syntax.
1476 } 1618 return '\'' + str + '\'';
1619 }
1620 }
1477 1621
1478 if (/[^\x20-\x7E]|\'/.test(str)) { 1622 // cURL command expected to run on the same platform that DevTools run
1479 // Use ANSI-C quoting syntax. 1623 // (it may be different from the inspected page platform).
1480 return "$\'" + str.replace(/\\/g, "\\\\") 1624 var escapeString = platform === 'win' ? escapeStringWin : escapeStringPosix;
1481 .replace(/\'/g, "\\\'")
1482 .replace(/\n/g, "\\n")
1483 .replace(/\r/g, "\\r")
1484 .replace(/[^\x20-\x7E]/g, escapeCharacter) + " '";
1485 } else {
1486 // Use single quote syntax.
1487 return "'" + str + "'";
1488 }
1489 }
1490 1625
1491 // cURL command expected to run on the same platform that DevTools run 1626 command.push(escapeString(request.url).replace(/[[{}\]]/g, '\\$&'));
1492 // (it may be different from the inspected page platform).
1493 var escapeString = platform === "win" ? escapeStringWin : escapeStringPo six;
1494 1627
1495 command.push(escapeString(request.url).replace(/[[{}\]]/g, "\\$&")); 1628 var inferredMethod = 'GET';
1629 var data = [];
1630 var requestContentType = request.requestContentType();
1631 if (requestContentType && requestContentType.startsWith('application/x-www-f orm-urlencoded') &&
1632 request.requestFormData) {
1633 data.push('--data');
1634 data.push(escapeString(request.requestFormData));
1635 ignoredHeaders['content-length'] = true;
1636 inferredMethod = 'POST';
1637 } else if (request.requestFormData) {
1638 data.push('--data-binary');
1639 data.push(escapeString(request.requestFormData));
1640 ignoredHeaders['content-length'] = true;
1641 inferredMethod = 'POST';
1642 }
1496 1643
1497 var inferredMethod = "GET"; 1644 if (request.requestMethod !== inferredMethod) {
1498 var data = []; 1645 command.push('-X');
1499 var requestContentType = request.requestContentType(); 1646 command.push(request.requestMethod);
1500 if (requestContentType && requestContentType.startsWith("application/x-w ww-form-urlencoded") && request.requestFormData) { 1647 }
1501 data.push("--data");
1502 data.push(escapeString(request.requestFormData));
1503 ignoredHeaders["content-length"] = true;
1504 inferredMethod = "POST";
1505 } else if (request.requestFormData) {
1506 data.push("--data-binary");
1507 data.push(escapeString(request.requestFormData));
1508 ignoredHeaders["content-length"] = true;
1509 inferredMethod = "POST";
1510 }
1511 1648
1512 if (request.requestMethod !== inferredMethod) { 1649 var requestHeaders = request.requestHeaders();
1513 command.push("-X"); 1650 for (var i = 0; i < requestHeaders.length; i++) {
1514 command.push(request.requestMethod); 1651 var header = requestHeaders[i];
1515 } 1652 var name = header.name.replace(/^:/, ''); // Translate SPDY v3 headers to HTTP headers.
1653 if (name.toLowerCase() in ignoredHeaders)
1654 continue;
1655 command.push('-H');
1656 command.push(escapeString(name + ': ' + header.value));
1657 }
1658 command = command.concat(data);
1659 command.push('--compressed');
1516 1660
1517 var requestHeaders = request.requestHeaders(); 1661 if (request.securityState() === SecurityAgent.SecurityState.Insecure)
1518 for (var i = 0; i < requestHeaders.length; i++) { 1662 command.push('--insecure');
1519 var header = requestHeaders[i]; 1663 return command.join(' ');
1520 var name = header.name.replace(/^:/, ""); // Translate SPDY v3 heade rs to HTTP headers. 1664 }
1521 if (name.toLowerCase() in ignoredHeaders) 1665 };
1522 continue;
1523 command.push("-H");
1524 command.push(escapeString(name + ": " + header.value));
1525 }
1526 command = command.concat(data);
1527 command.push("--compressed");
1528 1666
1529 if (request.securityState() === SecurityAgent.SecurityState.Insecure) 1667 WebInspector.NetworkLogView._isFilteredOutSymbol = Symbol('isFilteredOut');
1530 command.push("--insecure"); 1668 WebInspector.NetworkLogView._isMatchingSearchQuerySymbol = Symbol('isMatchingSea rchQuery');
1531 return command.join(" ");
1532 },
1533 1669
1534 __proto__: WebInspector.VBox.prototype 1670 WebInspector.NetworkLogView.HTTPSchemas = {
1671 'http': true,
1672 'https': true,
1673 'ws': true,
1674 'wss': true
1535 }; 1675 };
1536 1676
1677 WebInspector.NetworkLogView._waterfallMinOvertime = 1;
1678 WebInspector.NetworkLogView._waterfallMaxOvertime = 3;
1679
1680 /** @enum {symbol} */
1681 WebInspector.NetworkLogView.Events = {
1682 RequestSelected: Symbol('RequestSelected'),
1683 SearchCountUpdated: Symbol('SearchCountUpdated'),
1684 SearchIndexUpdated: Symbol('SearchIndexUpdated'),
1685 UpdateRequest: Symbol('UpdateRequest')
1686 };
1687
1688 /** @enum {string} */
1689 WebInspector.NetworkLogView.FilterType = {
1690 Domain: 'domain',
1691 HasResponseHeader: 'has-response-header',
1692 Is: 'is',
1693 LargerThan: 'larger-than',
1694 Method: 'method',
1695 MimeType: 'mime-type',
1696 MixedContent: 'mixed-content',
1697 Scheme: 'scheme',
1698 SetCookieDomain: 'set-cookie-domain',
1699 SetCookieName: 'set-cookie-name',
1700 SetCookieValue: 'set-cookie-value',
1701 StatusCode: 'status-code'
1702 };
1703
1704 /** @enum {string} */
1705 WebInspector.NetworkLogView.MixedContentFilterValues = {
1706 All: 'all',
1707 Displayed: 'displayed',
1708 Blocked: 'blocked',
1709 BlockOverridden: 'block-overridden'
1710 };
1711
1712 /** @enum {string} */
1713 WebInspector.NetworkLogView.IsFilterType = {
1714 Running: 'running'
1715 };
1716
1717 /** @type {!Array<string>} */
1718 WebInspector.NetworkLogView._searchKeys =
1719 Object.keys(WebInspector.NetworkLogView.FilterType).map(key => WebInspector. NetworkLogView.FilterType[key]);
1720
1537 /** @typedef {function(!WebInspector.NetworkRequest): boolean} */ 1721 /** @typedef {function(!WebInspector.NetworkRequest): boolean} */
1538 WebInspector.NetworkLogView.Filter; 1722 WebInspector.NetworkLogView.Filter;
1539 1723
1540 /**
1541 * @param {!WebInspector.NetworkLogView.Filter} filter
1542 * @param {!WebInspector.NetworkRequest} request
1543 * @return {boolean}
1544 */
1545 WebInspector.NetworkLogView._negativeFilter = function(filter, request)
1546 {
1547 return !filter(request);
1548 };
1549 1724
1550 /**
1551 * @param {?RegExp} regex
1552 * @param {!WebInspector.NetworkRequest} request
1553 * @return {boolean}
1554 */
1555 WebInspector.NetworkLogView._requestPathFilter = function(regex, request)
1556 {
1557 if (!regex)
1558 return false;
1559
1560 return regex.test(request.path() + "/" + request.name());
1561 };
1562
1563 /**
1564 * @param {string} domain
1565 * @return {!Array.<string>}
1566 */
1567 WebInspector.NetworkLogView._subdomains = function(domain)
1568 {
1569 var result = [domain];
1570 var indexOfPeriod = domain.indexOf(".");
1571 while (indexOfPeriod !== -1) {
1572 result.push("*" + domain.substring(indexOfPeriod));
1573 indexOfPeriod = domain.indexOf(".", indexOfPeriod + 1);
1574 }
1575 return result;
1576 };
1577
1578 /**
1579 * @param {string} value
1580 * @return {!WebInspector.NetworkLogView.Filter}
1581 */
1582 WebInspector.NetworkLogView._createRequestDomainFilter = function(value)
1583 {
1584 /**
1585 * @param {string} string
1586 * @return {string}
1587 */
1588 function escapeForRegExp(string)
1589 {
1590 return string.escapeForRegExp();
1591 }
1592 var escapedPattern = value.split("*").map(escapeForRegExp).join(".*");
1593 return WebInspector.NetworkLogView._requestDomainFilter.bind(null, new RegEx p("^" + escapedPattern + "$", "i"));
1594 };
1595
1596 /**
1597 * @param {!RegExp} regex
1598 * @param {!WebInspector.NetworkRequest} request
1599 * @return {boolean}
1600 */
1601 WebInspector.NetworkLogView._requestDomainFilter = function(regex, request)
1602 {
1603 return regex.test(request.domain);
1604 };
1605
1606 /**
1607 * @param {!WebInspector.NetworkRequest} request
1608 * @return {boolean}
1609 */
1610 WebInspector.NetworkLogView._runningRequestFilter = function(request)
1611 {
1612 return !request.finished;
1613 };
1614
1615 /**
1616 * @param {string} value
1617 * @param {!WebInspector.NetworkRequest} request
1618 * @return {boolean}
1619 */
1620 WebInspector.NetworkLogView._requestResponseHeaderFilter = function(value, reque st)
1621 {
1622 return request.responseHeaderValue(value) !== undefined;
1623 };
1624
1625 /**
1626 * @param {string} value
1627 * @param {!WebInspector.NetworkRequest} request
1628 * @return {boolean}
1629 */
1630 WebInspector.NetworkLogView._requestMethodFilter = function(value, request)
1631 {
1632 return request.requestMethod === value;
1633 };
1634
1635 /**
1636 * @param {string} value
1637 * @param {!WebInspector.NetworkRequest} request
1638 * @return {boolean}
1639 */
1640 WebInspector.NetworkLogView._requestMimeTypeFilter = function(value, request)
1641 {
1642 return request.mimeType === value;
1643 };
1644
1645 /**
1646 * @param {!WebInspector.NetworkLogView.MixedContentFilterValues} value
1647 * @param {!WebInspector.NetworkRequest} request
1648 * @return {boolean}
1649 */
1650 WebInspector.NetworkLogView._requestMixedContentFilter = function(value, request )
1651 {
1652 if (value === WebInspector.NetworkLogView.MixedContentFilterValues.Displayed ) {
1653 return request.mixedContentType === "optionally-blockable";
1654 } else if (value === WebInspector.NetworkLogView.MixedContentFilterValues.Bl ocked) {
1655 return request.mixedContentType === "blockable" && request.wasBlocked();
1656 } else if (value === WebInspector.NetworkLogView.MixedContentFilterValues.Bl ockOverridden) {
1657 return request.mixedContentType === "blockable" && !request.wasBlocked() ;
1658 } else if (value === WebInspector.NetworkLogView.MixedContentFilterValues.Al l) {
1659 return request.mixedContentType !== "none";
1660 }
1661 return false;
1662 };
1663
1664 /**
1665 * @param {string} value
1666 * @param {!WebInspector.NetworkRequest} request
1667 * @return {boolean}
1668 */
1669 WebInspector.NetworkLogView._requestSchemeFilter = function(value, request)
1670 {
1671 return request.scheme === value;
1672 };
1673
1674 /**
1675 * @param {string} value
1676 * @param {!WebInspector.NetworkRequest} request
1677 * @return {boolean}
1678 */
1679 WebInspector.NetworkLogView._requestSetCookieDomainFilter = function(value, requ est)
1680 {
1681 var cookies = request.responseCookies;
1682 for (var i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
1683 if (cookies[i].domain() === value)
1684 return true;
1685 }
1686 return false;
1687 };
1688
1689 /**
1690 * @param {string} value
1691 * @param {!WebInspector.NetworkRequest} request
1692 * @return {boolean}
1693 */
1694 WebInspector.NetworkLogView._requestSetCookieNameFilter = function(value, reques t)
1695 {
1696 var cookies = request.responseCookies;
1697 for (var i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
1698 if (cookies[i].name() === value)
1699 return true;
1700 }
1701 return false;
1702 };
1703
1704 /**
1705 * @param {string} value
1706 * @param {!WebInspector.NetworkRequest} request
1707 * @return {boolean}
1708 */
1709 WebInspector.NetworkLogView._requestSetCookieValueFilter = function(value, reque st)
1710 {
1711 var cookies = request.responseCookies;
1712 for (var i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
1713 if (cookies[i].value() === value)
1714 return true;
1715 }
1716 return false;
1717 };
1718
1719 /**
1720 * @param {number} value
1721 * @param {!WebInspector.NetworkRequest} request
1722 * @return {boolean}
1723 */
1724 WebInspector.NetworkLogView._requestSizeLargerThanFilter = function(value, reque st)
1725 {
1726 return request.transferSize >= value;
1727 };
1728
1729 /**
1730 * @param {string} value
1731 * @param {!WebInspector.NetworkRequest} request
1732 * @return {boolean}
1733 */
1734 WebInspector.NetworkLogView._statusCodeFilter = function(value, request)
1735 {
1736 return ("" + request.statusCode) === value;
1737 };
1738
1739 /**
1740 * @param {!WebInspector.NetworkRequest} request
1741 * @return {boolean}
1742 */
1743 WebInspector.NetworkLogView.HTTPRequestsFilter = function(request)
1744 {
1745 return request.parsedURL.isValid && (request.scheme in WebInspector.NetworkL ogView.HTTPSchemas);
1746 };
1747
1748 /**
1749 * @param {!WebInspector.NetworkRequest} request
1750 * @return {boolean}
1751 */
1752 WebInspector.NetworkLogView.FinishedRequestsFilter = function(request)
1753 {
1754 return request.finished;
1755 };
1756
1757 /**
1758 * @param {number} windowStart
1759 * @param {number} windowEnd
1760 * @param {!WebInspector.NetworkRequest} request
1761 * @return {boolean}
1762 */
1763 WebInspector.NetworkLogView._requestTimeFilter = function(windowStart, windowEnd , request)
1764 {
1765 if (request.issueTime() > windowEnd)
1766 return false;
1767 if (request.endTime !== -1 && request.endTime < windowStart)
1768 return false;
1769 return true;
1770 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698