blob: f228471fc49521e9743707901739fb837184c59c [file] [log] [blame]
Blink Reformat4c46d092018-04-07 15:32:371/*
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2008, 2009 Anthony Ricaud <[email protected]>
4 * Copyright (C) 2011 Google Inc. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
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
17 * from this software without specific prior written permission.
18 *
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
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
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/**
32 * @implements {SDK.SDKModelObserver<!SDK.NetworkManager>}
33 */
34Network.NetworkLogView = class extends UI.VBox {
35 /**
36 * @param {!UI.FilterBar} filterBar
37 * @param {!Element} progressBarContainer
38 * @param {!Common.Setting} networkLogLargeRowsSetting
39 */
40 constructor(filterBar, progressBarContainer, networkLogLargeRowsSetting) {
41 super();
42 this.setMinimumSize(50, 64);
43 this.registerRequiredCSS('network/networkLogView.css');
44
45 this.element.id = 'network-container';
Brandon Goddard88d885a2019-10-31 16:11:0546 this.element.classList.add('no-node-selected');
Blink Reformat4c46d092018-04-07 15:32:3747
48 this._networkHideDataURLSetting = Common.settings.createSetting('networkHideDataURL', false);
49 this._networkResourceTypeFiltersSetting = Common.settings.createSetting('networkResourceTypeFilters', {});
50
51 this._rawRowHeight = 0;
52 this._progressBarContainer = progressBarContainer;
53 this._networkLogLargeRowsSetting = networkLogLargeRowsSetting;
54 this._networkLogLargeRowsSetting.addChangeListener(updateRowHeight.bind(this), this);
55
56 /**
57 * @this {Network.NetworkLogView}
58 */
59 function updateRowHeight() {
60 this._rawRowHeight = !!this._networkLogLargeRowsSetting.get() ? 41 : 21;
61 this._rowHeight = this._computeRowHeight();
62 }
63 this._rawRowHeight = 0;
64 this._rowHeight = 0;
65 updateRowHeight.call(this);
66
67 /** @type {!Network.NetworkTransferTimeCalculator} */
68 this._timeCalculator = new Network.NetworkTransferTimeCalculator();
69 /** @type {!Network.NetworkTransferDurationCalculator} */
70 this._durationCalculator = new Network.NetworkTransferDurationCalculator();
71 this._calculator = this._timeCalculator;
72
73 this._columns = new Network.NetworkLogViewColumns(
74 this, this._timeCalculator, this._durationCalculator, networkLogLargeRowsSetting);
75 this._columns.show(this.element);
76
77 /** @type {!Set<!SDK.NetworkRequest>} */
78 this._staleRequests = new Set();
79 /** @type {number} */
80 this._mainRequestLoadTime = -1;
81 /** @type {number} */
82 this._mainRequestDOMContentLoadedTime = -1;
83 this._highlightedSubstringChanges = [];
84
85 /** @type {!Array.<!Network.NetworkLogView.Filter>} */
86 this._filters = [];
87 /** @type {?Network.NetworkLogView.Filter} */
88 this._timeFilter = null;
89 /** @type {?Network.NetworkNode} */
90 this._hoveredNode = null;
91 /** @type {?Element} */
92 this._recordingHint = null;
93 /** @type {?number} */
94 this._refreshRequestId = null;
95 /** @type {?Network.NetworkRequestNode} */
96 this._highlightedNode = null;
97
98 this.linkifier = new Components.Linkifier();
Blink Reformat4c46d092018-04-07 15:32:3799
100 this._recording = false;
101 this._needsRefresh = false;
102
103 this._headerHeight = 0;
104
105 /** @type {!Map<string, !Network.GroupLookupInterface>} */
106 this._groupLookups = new Map();
107 this._groupLookups.set('Frame', new Network.NetworkFrameGrouper(this));
108
109 /** @type {?Network.GroupLookupInterface} */
110 this._activeGroupLookup = null;
111
112 this._textFilterUI = new UI.TextFilterUI();
113 this._textFilterUI.addEventListener(UI.FilterUI.Events.FilterChanged, this._filterChanged, this);
114 filterBar.addFilter(this._textFilterUI);
115
116 this._dataURLFilterUI = new UI.CheckboxFilterUI(
117 'hide-data-url', Common.UIString('Hide data URLs'), true, this._networkHideDataURLSetting);
118 this._dataURLFilterUI.addEventListener(UI.FilterUI.Events.FilterChanged, this._filterChanged.bind(this), this);
Joey Arharba99d622019-02-01 19:10:48119 this._dataURLFilterUI.element().title = ls`Hides data: and blob: URLs`;
Blink Reformat4c46d092018-04-07 15:32:37120 filterBar.addFilter(this._dataURLFilterUI);
121
122 const filterItems =
123 Object.values(Common.resourceCategories)
124 .map(category => ({name: category.title, label: category.shortTitle, title: category.title}));
125 this._resourceCategoryFilterUI = new UI.NamedBitSetFilterUI(filterItems, this._networkResourceTypeFiltersSetting);
Brandon Goddard568cef12019-06-27 17:18:20126 UI.ARIAUtils.setAccessibleName(this._resourceCategoryFilterUI.element(), ls`Resource types to include`);
Blink Reformat4c46d092018-04-07 15:32:37127 this._resourceCategoryFilterUI.addEventListener(
128 UI.FilterUI.Events.FilterChanged, this._filterChanged.bind(this), this);
129 filterBar.addFilter(this._resourceCategoryFilterUI);
130
131 this._filterParser = new TextUtils.FilterParser(Network.NetworkLogView._searchKeys);
132 this._suggestionBuilder =
133 new UI.FilterSuggestionBuilder(Network.NetworkLogView._searchKeys, Network.NetworkLogView._sortSearchValues);
134 this._resetSuggestionBuilder();
135
136 this._dataGrid = this._columns.dataGrid();
137 this._setupDataGrid();
138 this._columns.sortByCurrentColumn();
Erik Luo0187a022018-05-31 18:35:49139 filterBar.filterButton().addEventListener(
140 UI.ToolbarButton.Events.Click, this._dataGrid.scheduleUpdate.bind(this._dataGrid, true /* isFromUser */));
Blink Reformat4c46d092018-04-07 15:32:37141
Joey Arhara86c14e2019-03-12 03:20:50142 this._summaryToolbar = new UI.Toolbar('network-summary-bar', this.element);
Blink Reformat4c46d092018-04-07 15:32:37143
144 new UI.DropTarget(
145 this.element, [UI.DropTarget.Type.File], Common.UIString('Drop HAR files here'), this._handleDrop.bind(this));
146
147 Common.moduleSetting('networkColorCodeResourceTypes')
148 .addChangeListener(this._invalidateAllItems.bind(this, false), this);
149
150 SDK.targetManager.observeModels(SDK.NetworkManager, this);
Pavel Feldman18d13562018-07-31 03:31:18151 SDK.networkLog.addEventListener(SDK.NetworkLog.Events.RequestAdded, this._onRequestUpdated, this);
152 SDK.networkLog.addEventListener(SDK.NetworkLog.Events.RequestUpdated, this._onRequestUpdated, this);
153 SDK.networkLog.addEventListener(SDK.NetworkLog.Events.Reset, this._reset, this);
Blink Reformat4c46d092018-04-07 15:32:37154
155 this._updateGroupByFrame();
156 Common.moduleSetting('network.group-by-frame').addChangeListener(() => this._updateGroupByFrame());
157
158 this._filterBar = filterBar;
Blink Reformat4c46d092018-04-07 15:32:37159 }
160
Blink Reformat4c46d092018-04-07 15:32:37161 _updateGroupByFrame() {
162 const value = Common.moduleSetting('network.group-by-frame').get();
163 this._setGrouping(value ? 'Frame' : null);
164 }
165
166 /**
167 * @param {string} key
168 * @param {!Array<string>} values
169 */
170 static _sortSearchValues(key, values) {
171 if (key === Network.NetworkLogView.FilterType.Priority) {
172 values.sort((a, b) => {
173 const aPriority = /** @type {!Protocol.Network.ResourcePriority} */ (PerfUI.uiLabelToNetworkPriority(a));
174 const bPriority = /** @type {!Protocol.Network.ResourcePriority} */ (PerfUI.uiLabelToNetworkPriority(b));
175 return PerfUI.networkPriorityWeight(aPriority) - PerfUI.networkPriorityWeight(bPriority);
176 });
177 } else {
178 values.sort();
179 }
180 }
181
182 /**
183 * @param {!Network.NetworkLogView.Filter} filter
184 * @param {!SDK.NetworkRequest} request
185 * @return {boolean}
186 */
187 static _negativeFilter(filter, request) {
188 return !filter(request);
189 }
190
191 /**
192 * @param {?RegExp} regex
193 * @param {!SDK.NetworkRequest} request
194 * @return {boolean}
195 */
196 static _requestPathFilter(regex, request) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34197 if (!regex) {
Blink Reformat4c46d092018-04-07 15:32:37198 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:34199 }
Blink Reformat4c46d092018-04-07 15:32:37200
201 return regex.test(request.path() + '/' + request.name());
202 }
203
204 /**
205 * @param {string} domain
206 * @return {!Array.<string>}
207 */
208 static _subdomains(domain) {
209 const result = [domain];
210 let indexOfPeriod = domain.indexOf('.');
211 while (indexOfPeriod !== -1) {
212 result.push('*' + domain.substring(indexOfPeriod));
213 indexOfPeriod = domain.indexOf('.', indexOfPeriod + 1);
214 }
215 return result;
216 }
217
218 /**
219 * @param {string} value
220 * @return {!Network.NetworkLogView.Filter}
221 */
222 static _createRequestDomainFilter(value) {
223 /**
224 * @param {string} string
225 * @return {string}
226 */
227 function escapeForRegExp(string) {
228 return string.escapeForRegExp();
229 }
230 const escapedPattern = value.split('*').map(escapeForRegExp).join('.*');
231 return Network.NetworkLogView._requestDomainFilter.bind(null, new RegExp('^' + escapedPattern + '$', 'i'));
232 }
233
234 /**
235 * @param {!RegExp} regex
236 * @param {!SDK.NetworkRequest} request
237 * @return {boolean}
238 */
239 static _requestDomainFilter(regex, request) {
240 return regex.test(request.domain);
241 }
242
243 /**
244 * @param {!SDK.NetworkRequest} request
245 * @return {boolean}
246 */
247 static _runningRequestFilter(request) {
248 return !request.finished;
249 }
250
251 /**
252 * @param {!SDK.NetworkRequest} request
253 * @return {boolean}
254 */
255 static _fromCacheRequestFilter(request) {
256 return request.cached();
257 }
258
259 /**
Joey Arhard183e7e2019-02-28 03:37:05260 * @param {!SDK.NetworkRequest} request
261 * @return {boolean}
262 */
263 static _interceptedByServiceWorkerFilter(request) {
264 return request.fetchedViaServiceWorker;
265 }
266
267 /**
268 * @param {!SDK.NetworkRequest} request
269 * @return {boolean}
270 */
271 static _initiatedByServiceWorkerFilter(request) {
272 return request.initiatedByServiceWorker();
273 }
274
275 /**
Blink Reformat4c46d092018-04-07 15:32:37276 * @param {string} value
277 * @param {!SDK.NetworkRequest} request
278 * @return {boolean}
279 */
280 static _requestResponseHeaderFilter(value, request) {
281 return request.responseHeaderValue(value) !== undefined;
282 }
283
284 /**
285 * @param {string} value
286 * @param {!SDK.NetworkRequest} request
287 * @return {boolean}
288 */
289 static _requestMethodFilter(value, request) {
290 return request.requestMethod === value;
291 }
292
293 /**
294 * @param {string} value
295 * @param {!SDK.NetworkRequest} request
296 * @return {boolean}
297 */
298 static _requestPriorityFilter(value, request) {
299 return request.priority() === value;
300 }
301
302 /**
303 * @param {string} value
304 * @param {!SDK.NetworkRequest} request
305 * @return {boolean}
306 */
307 static _requestMimeTypeFilter(value, request) {
308 return request.mimeType === value;
309 }
310
311 /**
312 * @param {!Network.NetworkLogView.MixedContentFilterValues} value
313 * @param {!SDK.NetworkRequest} request
314 * @return {boolean}
315 */
316 static _requestMixedContentFilter(value, request) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34317 if (value === Network.NetworkLogView.MixedContentFilterValues.Displayed) {
Blink Reformat4c46d092018-04-07 15:32:37318 return request.mixedContentType === Protocol.Security.MixedContentType.OptionallyBlockable;
Tim van der Lippe1d6e57a2019-09-30 11:55:34319 } else if (value === Network.NetworkLogView.MixedContentFilterValues.Blocked) {
Blink Reformat4c46d092018-04-07 15:32:37320 return request.mixedContentType === Protocol.Security.MixedContentType.Blockable && request.wasBlocked();
Tim van der Lippe1d6e57a2019-09-30 11:55:34321 } else if (value === Network.NetworkLogView.MixedContentFilterValues.BlockOverridden) {
Blink Reformat4c46d092018-04-07 15:32:37322 return request.mixedContentType === Protocol.Security.MixedContentType.Blockable && !request.wasBlocked();
Tim van der Lippe1d6e57a2019-09-30 11:55:34323 } else if (value === Network.NetworkLogView.MixedContentFilterValues.All) {
Blink Reformat4c46d092018-04-07 15:32:37324 return request.mixedContentType !== Protocol.Security.MixedContentType.None;
Tim van der Lippe1d6e57a2019-09-30 11:55:34325 }
Blink Reformat4c46d092018-04-07 15:32:37326
327 return false;
328 }
329
330 /**
331 * @param {string} value
332 * @param {!SDK.NetworkRequest} request
333 * @return {boolean}
334 */
335 static _requestSchemeFilter(value, request) {
336 return request.scheme === value;
337 }
338
339 /**
340 * @param {string} value
341 * @param {!SDK.NetworkRequest} request
342 * @return {boolean}
343 */
344 static _requestSetCookieDomainFilter(value, request) {
345 const cookies = request.responseCookies;
346 for (let i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34347 if (cookies[i].domain() === value) {
Blink Reformat4c46d092018-04-07 15:32:37348 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:34349 }
Blink Reformat4c46d092018-04-07 15:32:37350 }
351 return false;
352 }
353
354 /**
355 * @param {string} value
356 * @param {!SDK.NetworkRequest} request
357 * @return {boolean}
358 */
359 static _requestSetCookieNameFilter(value, request) {
360 const cookies = request.responseCookies;
361 for (let i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34362 if (cookies[i].name() === value) {
Blink Reformat4c46d092018-04-07 15:32:37363 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:34364 }
Blink Reformat4c46d092018-04-07 15:32:37365 }
366 return false;
367 }
368
369 /**
370 * @param {string} value
371 * @param {!SDK.NetworkRequest} request
372 * @return {boolean}
373 */
374 static _requestSetCookieValueFilter(value, request) {
375 const cookies = request.responseCookies;
376 for (let i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34377 if (cookies[i].value() === value) {
Blink Reformat4c46d092018-04-07 15:32:37378 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:34379 }
Blink Reformat4c46d092018-04-07 15:32:37380 }
381 return false;
382 }
383
384 /**
385 * @param {number} value
386 * @param {!SDK.NetworkRequest} request
387 * @return {boolean}
388 */
389 static _requestSizeLargerThanFilter(value, request) {
390 return request.transferSize >= value;
391 }
392
393 /**
394 * @param {string} value
395 * @param {!SDK.NetworkRequest} request
396 * @return {boolean}
397 */
398 static _statusCodeFilter(value, request) {
399 return ('' + request.statusCode) === value;
400 }
401
402 /**
403 * @param {!SDK.NetworkRequest} request
404 * @return {boolean}
405 */
406 static HTTPRequestsFilter(request) {
407 return request.parsedURL.isValid && (request.scheme in Network.NetworkLogView.HTTPSchemas);
408 }
409
410 /**
Blink Reformat4c46d092018-04-07 15:32:37411 * @param {number} windowStart
412 * @param {number} windowEnd
413 * @param {!SDK.NetworkRequest} request
414 * @return {boolean}
415 */
416 static _requestTimeFilter(windowStart, windowEnd, request) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34417 if (request.issueTime() > windowEnd) {
Blink Reformat4c46d092018-04-07 15:32:37418 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:34419 }
420 if (request.endTime !== -1 && request.endTime < windowStart) {
Blink Reformat4c46d092018-04-07 15:32:37421 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:34422 }
Blink Reformat4c46d092018-04-07 15:32:37423 return true;
424 }
425
426 /**
427 * @param {!SDK.NetworkRequest} request
428 */
429 static _copyRequestHeaders(request) {
Tim van der Lippe50cfa9b2019-10-01 10:40:58430 Host.InspectorFrontendHost.copyText(request.requestHeadersText());
Blink Reformat4c46d092018-04-07 15:32:37431 }
432
433 /**
434 * @param {!SDK.NetworkRequest} request
435 */
436 static _copyResponseHeaders(request) {
Tim van der Lippe50cfa9b2019-10-01 10:40:58437 Host.InspectorFrontendHost.copyText(request.responseHeadersText);
Blink Reformat4c46d092018-04-07 15:32:37438 }
439
440 /**
441 * @param {!SDK.NetworkRequest} request
442 */
443 static async _copyResponse(request) {
444 const contentData = await request.contentData();
Ingvar Stepanyan1c771842018-10-10 14:35:08445 let content = contentData.content || '';
Tim van der Lippe1d6e57a2019-09-30 11:55:34446 if (!request.contentType().isTextType()) {
Ingvar Stepanyan1c771842018-10-10 14:35:08447 content = Common.ContentProvider.contentAsDataURL(content, request.mimeType, contentData.encoded);
Tim van der Lippe1d6e57a2019-09-30 11:55:34448 } else if (contentData.encoded) {
Ingvar Stepanyan1c771842018-10-10 14:35:08449 content = window.atob(content);
Tim van der Lippe1d6e57a2019-09-30 11:55:34450 }
Tim van der Lippe50cfa9b2019-10-01 10:40:58451 Host.InspectorFrontendHost.copyText(content);
Blink Reformat4c46d092018-04-07 15:32:37452 }
453
454 /**
455 * @param {!DataTransfer} dataTransfer
456 */
457 _handleDrop(dataTransfer) {
458 const items = dataTransfer.items;
Tim van der Lippe1d6e57a2019-09-30 11:55:34459 if (!items.length) {
Blink Reformat4c46d092018-04-07 15:32:37460 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34461 }
Blink Reformat4c46d092018-04-07 15:32:37462 const entry = items[0].webkitGetAsEntry();
Tim van der Lippe1d6e57a2019-09-30 11:55:34463 if (entry.isDirectory) {
Blink Reformat4c46d092018-04-07 15:32:37464 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34465 }
Blink Reformat4c46d092018-04-07 15:32:37466
Joey Arhar0e1093c2019-05-21 00:34:22467 entry.file(this.onLoadFromFile.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37468 }
469
470 /**
471 * @param {!File} file
472 */
Joey Arhar0e1093c2019-05-21 00:34:22473 async onLoadFromFile(file) {
Blink Reformat4c46d092018-04-07 15:32:37474 const outputStream = new Common.StringOutputStream();
475 const reader = new Bindings.ChunkedFileReader(file, /* chunkSize */ 10000000);
476 const success = await reader.read(outputStream);
477 if (!success) {
478 this._harLoadFailed(reader.error().message);
479 return;
480 }
481 let harRoot;
482 try {
483 // HARRoot and JSON.parse might throw.
484 harRoot = new HARImporter.HARRoot(JSON.parse(outputStream.data()));
485 } catch (e) {
486 this._harLoadFailed(e);
487 return;
488 }
Pavel Feldman18d13562018-07-31 03:31:18489 SDK.networkLog.importRequests(HARImporter.Importer.requestsFromHARLog(harRoot.log));
Blink Reformat4c46d092018-04-07 15:32:37490 }
491
492 /**
493 * @param {string} message
494 */
495 _harLoadFailed(message) {
496 Common.console.error('Failed to load HAR file with following error: ' + message);
497 }
498
499 /**
500 * @param {?string} groupKey
501 */
502 _setGrouping(groupKey) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34503 if (this._activeGroupLookup) {
Blink Reformat4c46d092018-04-07 15:32:37504 this._activeGroupLookup.reset();
Tim van der Lippe1d6e57a2019-09-30 11:55:34505 }
Blink Reformat4c46d092018-04-07 15:32:37506 const groupLookup = groupKey ? this._groupLookups.get(groupKey) || null : null;
507 this._activeGroupLookup = groupLookup;
508 this._invalidateAllItems();
509 }
510
511 /**
512 * @return {number}
513 */
514 _computeRowHeight() {
515 return Math.round(this._rawRowHeight * window.devicePixelRatio) / window.devicePixelRatio;
516 }
517
518 /**
519 * @param {!SDK.NetworkRequest} request
520 * @return {?Network.NetworkRequestNode}
521 */
522 nodeForRequest(request) {
523 return request[Network.NetworkLogView._networkNodeSymbol] || null;
524 }
525
526 /**
527 * @return {number}
528 */
529 headerHeight() {
530 return this._headerHeight;
531 }
532
533 /**
534 * @param {boolean} recording
535 */
536 setRecording(recording) {
537 this._recording = recording;
538 this._updateSummaryBar();
539 }
540
541 /**
542 * @override
543 * @param {!SDK.NetworkManager} networkManager
544 */
545 modelAdded(networkManager) {
546 // TODO(allada) Remove dependency on networkManager and instead use NetworkLog and PageLoad for needed data.
Tim van der Lippe1d6e57a2019-09-30 11:55:34547 if (networkManager.target().parentTarget()) {
Blink Reformat4c46d092018-04-07 15:32:37548 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34549 }
Blink Reformat4c46d092018-04-07 15:32:37550 const resourceTreeModel = networkManager.target().model(SDK.ResourceTreeModel);
551 if (resourceTreeModel) {
552 resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.Load, this._loadEventFired, this);
553 resourceTreeModel.addEventListener(
554 SDK.ResourceTreeModel.Events.DOMContentLoaded, this._domContentLoadedEventFired, this);
555 }
556 }
557
558 /**
559 * @override
560 * @param {!SDK.NetworkManager} networkManager
561 */
562 modelRemoved(networkManager) {
563 if (!networkManager.target().parentTarget()) {
564 const resourceTreeModel = networkManager.target().model(SDK.ResourceTreeModel);
565 if (resourceTreeModel) {
566 resourceTreeModel.removeEventListener(SDK.ResourceTreeModel.Events.Load, this._loadEventFired, this);
567 resourceTreeModel.removeEventListener(
568 SDK.ResourceTreeModel.Events.DOMContentLoaded, this._domContentLoadedEventFired, this);
569 }
570 }
571 }
572
573 /**
574 * @param {number} start
575 * @param {number} end
576 */
577 setWindow(start, end) {
578 if (!start && !end) {
579 this._timeFilter = null;
580 this._timeCalculator.setWindow(null);
581 } else {
582 this._timeFilter = Network.NetworkLogView._requestTimeFilter.bind(null, start, end);
583 this._timeCalculator.setWindow(new Network.NetworkTimeBoundary(start, end));
584 }
585 this._filterRequests();
586 }
587
Brandon Goddard88d885a2019-10-31 16:11:05588 resetFocus() {
589 this._dataGrid.element.focus();
Blink Reformat4c46d092018-04-07 15:32:37590 }
591
592 _resetSuggestionBuilder() {
593 this._suggestionBuilder.clear();
594 this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.Is, Network.NetworkLogView.IsFilterType.Running);
595 this._suggestionBuilder.addItem(
596 Network.NetworkLogView.FilterType.Is, Network.NetworkLogView.IsFilterType.FromCache);
Joey Arhard183e7e2019-02-28 03:37:05597 this._suggestionBuilder.addItem(
598 Network.NetworkLogView.FilterType.Is, Network.NetworkLogView.IsFilterType.ServiceWorkerIntercepted);
599 this._suggestionBuilder.addItem(
600 Network.NetworkLogView.FilterType.Is, Network.NetworkLogView.IsFilterType.ServiceWorkerInitiated);
Blink Reformat4c46d092018-04-07 15:32:37601 this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.LargerThan, '100');
602 this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.LargerThan, '10k');
603 this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.LargerThan, '1M');
604 this._textFilterUI.setSuggestionProvider(this._suggestionBuilder.completions.bind(this._suggestionBuilder));
605 }
606
607 /**
608 * @param {!Common.Event} event
609 */
610 _filterChanged(event) {
611 this.removeAllNodeHighlights();
612 this._parseFilterQuery(this._textFilterUI.value());
613 this._filterRequests();
Blink Reformat4c46d092018-04-07 15:32:37614 }
615
616 _showRecordingHint() {
617 this._hideRecordingHint();
618 this._recordingHint = this.element.createChild('div', 'network-status-pane fill');
619 const hintText = this._recordingHint.createChild('div', 'recording-hint');
Joey Arhar0585e6f2018-10-30 23:11:18620
621 let reloadShortcutNode = null;
622 const reloadShortcutDescriptor = UI.shortcutRegistry.shortcutDescriptorsForAction('inspector_main.reload')[0];
623 if (reloadShortcutDescriptor) {
624 reloadShortcutNode = this._recordingHint.createChild('b');
625 reloadShortcutNode.textContent = reloadShortcutDescriptor.name;
626 }
Blink Reformat4c46d092018-04-07 15:32:37627
628 if (this._recording) {
629 const recordingText = hintText.createChild('span');
630 recordingText.textContent = Common.UIString('Recording network activity\u2026');
Joey Arhar0585e6f2018-10-30 23:11:18631 if (reloadShortcutNode) {
632 hintText.createChild('br');
633 hintText.appendChild(
634 UI.formatLocalized('Perform a request or hit %s to record the reload.', [reloadShortcutNode]));
635 }
Blink Reformat4c46d092018-04-07 15:32:37636 } else {
637 const recordNode = hintText.createChild('b');
638 recordNode.textContent = UI.shortcutRegistry.shortcutTitleForAction('network.toggle-recording');
Joey Arhar0585e6f2018-10-30 23:11:18639 if (reloadShortcutNode) {
640 hintText.appendChild(UI.formatLocalized(
641 'Record (%s) or reload (%s) to display network activity.', [recordNode, reloadShortcutNode]));
642 } else {
643 hintText.appendChild(UI.formatLocalized('Record (%s) to display network activity.', [recordNode]));
644 }
Blink Reformat4c46d092018-04-07 15:32:37645 }
Kayce Basques5444c1b2019-02-15 20:32:53646 hintText.createChild('br');
647 hintText.appendChild(UI.XLink.create(
648 'https://developers.google.com/web/tools/chrome-devtools/network/?utm_source=devtools&utm_campaign=2019Q1',
649 'Learn more'));
Amanda Baker6761aae2019-11-05 18:59:11650
651 this._setHidden(true);
Blink Reformat4c46d092018-04-07 15:32:37652 }
653
654 _hideRecordingHint() {
Amanda Baker6761aae2019-11-05 18:59:11655 this._setHidden(false);
Tim van der Lippe1d6e57a2019-09-30 11:55:34656 if (this._recordingHint) {
Blink Reformat4c46d092018-04-07 15:32:37657 this._recordingHint.remove();
Tim van der Lippe1d6e57a2019-09-30 11:55:34658 }
Blink Reformat4c46d092018-04-07 15:32:37659 this._recordingHint = null;
660 }
661
662 /**
Amanda Baker6761aae2019-11-05 18:59:11663 * @param {boolean} value
664 */
665 _setHidden(value) {
666 this._columns.setHidden(value);
667 UI.ARIAUtils.setHidden(this._summaryToolbar.element, value);
668 }
669
670 /**
Blink Reformat4c46d092018-04-07 15:32:37671 * @override
672 * @return {!Array.<!Element>}
673 */
674 elementsToRestoreScrollPositionsFor() {
675 if (!this._dataGrid) // Not initialized yet.
Tim van der Lippe1d6e57a2019-09-30 11:55:34676 {
Blink Reformat4c46d092018-04-07 15:32:37677 return [];
Tim van der Lippe1d6e57a2019-09-30 11:55:34678 }
Blink Reformat4c46d092018-04-07 15:32:37679 return [this._dataGrid.scrollContainer];
680 }
681
682 columnExtensionResolved() {
683 this._invalidateAllItems(true);
684 }
685
686 _setupDataGrid() {
687 this._dataGrid.setRowContextMenuCallback((contextMenu, node) => {
688 const request = node.request();
Tim van der Lippe1d6e57a2019-09-30 11:55:34689 if (request) {
Blink Reformat4c46d092018-04-07 15:32:37690 this.handleContextMenuForRequest(contextMenu, request);
Tim van der Lippe1d6e57a2019-09-30 11:55:34691 }
Blink Reformat4c46d092018-04-07 15:32:37692 });
693 this._dataGrid.setStickToBottom(true);
694 this._dataGrid.setName('networkLog');
695 this._dataGrid.setResizeMethod(DataGrid.DataGrid.ResizeMethod.Last);
696 this._dataGrid.element.classList.add('network-log-grid');
697 this._dataGrid.element.addEventListener('mousedown', this._dataGridMouseDown.bind(this), true);
698 this._dataGrid.element.addEventListener('mousemove', this._dataGridMouseMove.bind(this), true);
699 this._dataGrid.element.addEventListener('mouseleave', () => this._setHoveredNode(null), true);
Brandon Goddard88d885a2019-10-31 16:11:05700 this._dataGrid.element.addEventListener('keydown', event => {
701 if (isEnterOrSpaceKey(event)) {
702 this.dispatchEventToListeners(Network.NetworkLogView.Events.RequestActivated, /* showPanel */ true);
703 event.consume(true);
704 }
705 });
706 this._dataGrid.element.addEventListener('focus', this.updateNodeBackground.bind(this), true);
707 this._dataGrid.element.addEventListener('blur', this.updateNodeBackground.bind(this), true);
Blink Reformat4c46d092018-04-07 15:32:37708 return this._dataGrid;
709 }
710
711 /**
712 * @param {!Event} event
713 */
714 _dataGridMouseMove(event) {
715 const node = (this._dataGrid.dataGridNodeFromNode(/** @type {!Node} */ (event.target)));
716 const highlightInitiatorChain = event.shiftKey;
717 this._setHoveredNode(node, highlightInitiatorChain);
718 }
719
720 /**
721 * @return {?Network.NetworkNode}
722 */
723 hoveredNode() {
724 return this._hoveredNode;
725 }
726
727 /**
728 * @param {?Network.NetworkNode} node
729 * @param {boolean=} highlightInitiatorChain
730 */
731 _setHoveredNode(node, highlightInitiatorChain) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34732 if (this._hoveredNode) {
Blink Reformat4c46d092018-04-07 15:32:37733 this._hoveredNode.setHovered(false, false);
Tim van der Lippe1d6e57a2019-09-30 11:55:34734 }
Blink Reformat4c46d092018-04-07 15:32:37735 this._hoveredNode = node;
Tim van der Lippe1d6e57a2019-09-30 11:55:34736 if (this._hoveredNode) {
Blink Reformat4c46d092018-04-07 15:32:37737 this._hoveredNode.setHovered(true, !!highlightInitiatorChain);
Tim van der Lippe1d6e57a2019-09-30 11:55:34738 }
Blink Reformat4c46d092018-04-07 15:32:37739 }
740
741 /**
742 * @param {!Event} event
743 */
744 _dataGridMouseDown(event) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34745 if (!this._dataGrid.selectedNode && event.button) {
Blink Reformat4c46d092018-04-07 15:32:37746 event.consume();
Tim van der Lippe1d6e57a2019-09-30 11:55:34747 }
Blink Reformat4c46d092018-04-07 15:32:37748 }
749
750 _updateSummaryBar() {
751 this._hideRecordingHint();
752
753 let transferSize = 0;
Dan Beam87466b52018-12-01 18:41:20754 let resourceSize = 0;
Blink Reformat4c46d092018-04-07 15:32:37755 let selectedNodeNumber = 0;
756 let selectedTransferSize = 0;
Dan Beam87466b52018-12-01 18:41:20757 let selectedResourceSize = 0;
Blink Reformat4c46d092018-04-07 15:32:37758 let baseTime = -1;
759 let maxTime = -1;
760
761 let nodeCount = 0;
Pavel Feldman18d13562018-07-31 03:31:18762 for (const request of SDK.networkLog.requests()) {
Blink Reformat4c46d092018-04-07 15:32:37763 const node = request[Network.NetworkLogView._networkNodeSymbol];
Tim van der Lippe1d6e57a2019-09-30 11:55:34764 if (!node) {
Blink Reformat4c46d092018-04-07 15:32:37765 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:34766 }
Blink Reformat4c46d092018-04-07 15:32:37767 nodeCount++;
768 const requestTransferSize = request.transferSize;
769 transferSize += requestTransferSize;
Dan Beam87466b52018-12-01 18:41:20770 const requestResourceSize = request.resourceSize;
771 resourceSize += requestResourceSize;
Blink Reformat4c46d092018-04-07 15:32:37772 if (!node[Network.NetworkLogView._isFilteredOutSymbol]) {
773 selectedNodeNumber++;
774 selectedTransferSize += requestTransferSize;
Dan Beam87466b52018-12-01 18:41:20775 selectedResourceSize += requestResourceSize;
Blink Reformat4c46d092018-04-07 15:32:37776 }
777 const networkManager = SDK.NetworkManager.forRequest(request);
778 // TODO(allada) inspectedURL should be stored in PageLoad used instead of target so HAR requests can have an
779 // inspected url.
780 if (networkManager && request.url() === networkManager.target().inspectedURL() &&
Tim van der Lippe1d6e57a2019-09-30 11:55:34781 request.resourceType() === Common.resourceTypes.Document && !networkManager.target().parentTarget()) {
Blink Reformat4c46d092018-04-07 15:32:37782 baseTime = request.startTime;
Tim van der Lippe1d6e57a2019-09-30 11:55:34783 }
784 if (request.endTime > maxTime) {
Blink Reformat4c46d092018-04-07 15:32:37785 maxTime = request.endTime;
Tim van der Lippe1d6e57a2019-09-30 11:55:34786 }
Blink Reformat4c46d092018-04-07 15:32:37787 }
788
789 if (!nodeCount) {
790 this._showRecordingHint();
791 return;
792 }
793
Joey Arhara86c14e2019-03-12 03:20:50794 this._summaryToolbar.removeToolbarItems();
Blink Reformat4c46d092018-04-07 15:32:37795 /**
796 * @param {string} chunk
Joey Arhara86c14e2019-03-12 03:20:50797 * @param {string=} title
Blink Reformat4c46d092018-04-07 15:32:37798 * @return {!Element}
799 */
Joey Arhara86c14e2019-03-12 03:20:50800 const appendChunk = (chunk, title) => {
801 const toolbarText = new UI.ToolbarText(chunk);
802 toolbarText.setTitle(title ? title : chunk);
803 this._summaryToolbar.appendToolbarItem(toolbarText);
804 return toolbarText.element;
805 };
Blink Reformat4c46d092018-04-07 15:32:37806
807 if (selectedNodeNumber !== nodeCount) {
Joey Arhara86c14e2019-03-12 03:20:50808 appendChunk(ls`${selectedNodeNumber} / ${nodeCount} requests`);
809 this._summaryToolbar.appendSeparator();
810 appendChunk(
811 ls`${Number.bytesToString(selectedTransferSize)} / ${Number.bytesToString(transferSize)} transferred`,
812 ls`${selectedTransferSize} B / ${transferSize} B transferred`);
813 this._summaryToolbar.appendSeparator();
814 appendChunk(
815 ls`${Number.bytesToString(selectedResourceSize)} / ${Number.bytesToString(resourceSize)} resources`,
816 ls`${selectedResourceSize} B / ${resourceSize} B resources`);
Blink Reformat4c46d092018-04-07 15:32:37817 } else {
Joey Arhara86c14e2019-03-12 03:20:50818 appendChunk(ls`${nodeCount} requests`);
819 this._summaryToolbar.appendSeparator();
820 appendChunk(ls`${Number.bytesToString(transferSize)} transferred`, ls`${transferSize} B transferred`);
821 this._summaryToolbar.appendSeparator();
822 appendChunk(ls`${Number.bytesToString(resourceSize)} resources`, ls`${resourceSize} B resources`);
Blink Reformat4c46d092018-04-07 15:32:37823 }
Dan Beam87466b52018-12-01 18:41:20824
Blink Reformat4c46d092018-04-07 15:32:37825 if (baseTime !== -1 && maxTime !== -1) {
Joey Arhara86c14e2019-03-12 03:20:50826 this._summaryToolbar.appendSeparator();
827 appendChunk(ls`Finish: ${Number.secondsToString(maxTime - baseTime)}`);
Blink Reformat4c46d092018-04-07 15:32:37828 if (this._mainRequestDOMContentLoadedTime !== -1 && this._mainRequestDOMContentLoadedTime > baseTime) {
Joey Arhara86c14e2019-03-12 03:20:50829 this._summaryToolbar.appendSeparator();
Alexei Filippovfdcd8a62018-12-17 21:32:30830 const domContentLoadedText =
831 ls`DOMContentLoaded: ${Number.secondsToString(this._mainRequestDOMContentLoadedTime - baseTime)}`;
Joey Arhara86c14e2019-03-12 03:20:50832 appendChunk(domContentLoadedText).style.color = Network.NetworkLogView.getDCLEventColor();
Blink Reformat4c46d092018-04-07 15:32:37833 }
834 if (this._mainRequestLoadTime !== -1) {
Joey Arhara86c14e2019-03-12 03:20:50835 this._summaryToolbar.appendSeparator();
Alexei Filippovfdcd8a62018-12-17 21:32:30836 const loadText = ls`Load: ${Number.secondsToString(this._mainRequestLoadTime - baseTime)}`;
Joey Arhara86c14e2019-03-12 03:20:50837 appendChunk(loadText).style.color = Network.NetworkLogView.getLoadEventColor();
Blink Reformat4c46d092018-04-07 15:32:37838 }
839 }
Blink Reformat4c46d092018-04-07 15:32:37840 }
841
842 scheduleRefresh() {
Tim van der Lippe1d6e57a2019-09-30 11:55:34843 if (this._needsRefresh) {
Blink Reformat4c46d092018-04-07 15:32:37844 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34845 }
Blink Reformat4c46d092018-04-07 15:32:37846
847 this._needsRefresh = true;
848
Tim van der Lippe1d6e57a2019-09-30 11:55:34849 if (this.isShowing() && !this._refreshRequestId) {
Blink Reformat4c46d092018-04-07 15:32:37850 this._refreshRequestId = this.element.window().requestAnimationFrame(this._refresh.bind(this));
Tim van der Lippe1d6e57a2019-09-30 11:55:34851 }
Blink Reformat4c46d092018-04-07 15:32:37852 }
853
854 /**
855 * @param {!Array<number>} times
856 */
857 addFilmStripFrames(times) {
858 this._columns.addEventDividers(times, 'network-frame-divider');
859 }
860
861 /**
862 * @param {number} time
863 */
864 selectFilmStripFrame(time) {
865 this._columns.selectFilmStripFrame(time);
866 }
867
868 clearFilmStripFrame() {
869 this._columns.clearFilmStripFrame();
870 }
871
872 _refreshIfNeeded() {
Tim van der Lippe1d6e57a2019-09-30 11:55:34873 if (this._needsRefresh) {
Blink Reformat4c46d092018-04-07 15:32:37874 this._refresh();
Tim van der Lippe1d6e57a2019-09-30 11:55:34875 }
Blink Reformat4c46d092018-04-07 15:32:37876 }
877
878 /**
879 * @param {boolean=} deferUpdate
880 */
881 _invalidateAllItems(deferUpdate) {
Pavel Feldman18d13562018-07-31 03:31:18882 this._staleRequests = new Set(SDK.networkLog.requests());
Tim van der Lippe1d6e57a2019-09-30 11:55:34883 if (deferUpdate) {
Blink Reformat4c46d092018-04-07 15:32:37884 this.scheduleRefresh();
Tim van der Lippe1d6e57a2019-09-30 11:55:34885 } else {
Blink Reformat4c46d092018-04-07 15:32:37886 this._refresh();
Tim van der Lippe1d6e57a2019-09-30 11:55:34887 }
Blink Reformat4c46d092018-04-07 15:32:37888 }
889
890 /**
891 * @return {!Network.NetworkTimeCalculator}
892 */
893 timeCalculator() {
894 return this._timeCalculator;
895 }
896
897 /**
898 * @return {!Network.NetworkTimeCalculator}
899 */
900 calculator() {
901 return this._calculator;
902 }
903
904 /**
905 * @param {!Network.NetworkTimeCalculator} x
906 */
907 setCalculator(x) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34908 if (!x || this._calculator === x) {
Blink Reformat4c46d092018-04-07 15:32:37909 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34910 }
Blink Reformat4c46d092018-04-07 15:32:37911
912 if (this._calculator !== x) {
913 this._calculator = x;
914 this._columns.setCalculator(this._calculator);
915 }
916 this._calculator.reset();
917
Tim van der Lippe1d6e57a2019-09-30 11:55:34918 if (this._calculator.startAtZero) {
Blink Reformat4c46d092018-04-07 15:32:37919 this._columns.hideEventDividers();
Tim van der Lippe1d6e57a2019-09-30 11:55:34920 } else {
Blink Reformat4c46d092018-04-07 15:32:37921 this._columns.showEventDividers();
Tim van der Lippe1d6e57a2019-09-30 11:55:34922 }
Blink Reformat4c46d092018-04-07 15:32:37923
924 this._invalidateAllItems();
925 }
926
927 /**
928 * @param {!Common.Event} event
929 */
930 _loadEventFired(event) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34931 if (!this._recording) {
Blink Reformat4c46d092018-04-07 15:32:37932 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34933 }
Blink Reformat4c46d092018-04-07 15:32:37934
935 const time = /** @type {number} */ (event.data.loadTime);
936 if (time) {
937 this._mainRequestLoadTime = time;
Alexei Filippovfdcd8a62018-12-17 21:32:30938 this._columns.addEventDividers([time], 'network-load-divider');
Blink Reformat4c46d092018-04-07 15:32:37939 }
940 }
941
942 /**
943 * @param {!Common.Event} event
944 */
945 _domContentLoadedEventFired(event) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34946 if (!this._recording) {
Blink Reformat4c46d092018-04-07 15:32:37947 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34948 }
Blink Reformat4c46d092018-04-07 15:32:37949 const data = /** @type {number} */ (event.data);
950 if (data) {
951 this._mainRequestDOMContentLoadedTime = data;
Alexei Filippovfdcd8a62018-12-17 21:32:30952 this._columns.addEventDividers([data], 'network-dcl-divider');
Blink Reformat4c46d092018-04-07 15:32:37953 }
954 }
955
956 /**
957 * @override
958 */
959 wasShown() {
960 this._refreshIfNeeded();
961 this._columns.wasShown();
962 }
963
964 /**
965 * @override
966 */
967 willHide() {
968 this._columns.willHide();
969 }
970
971 /**
972 * @override
973 */
974 onResize() {
975 this._rowHeight = this._computeRowHeight();
976 }
977
978 /**
979 * @return {!Array<!Network.NetworkNode>}
980 */
981 flatNodesList() {
982 return this._dataGrid.rootNode().flatChildren();
983 }
984
Brandon Goddard88d885a2019-10-31 16:11:05985 updateNodeBackground() {
986 if (this._dataGrid.selectedNode) {
987 this._dataGrid.selectedNode.updateBackgroundColor();
988 }
989 }
990
991 /**
992 * @param {boolean} isSelected
993 */
994 updateNodeSelectedClass(isSelected) {
995 if (isSelected) {
996 this.element.classList.remove('no-node-selected');
997 } else {
998 this.element.classList.add('no-node-selected');
999 }
1000 }
1001
Blink Reformat4c46d092018-04-07 15:32:371002 stylesChanged() {
1003 this._columns.scheduleRefresh();
1004 }
1005
1006 _refresh() {
1007 this._needsRefresh = false;
1008
1009 if (this._refreshRequestId) {
1010 this.element.window().cancelAnimationFrame(this._refreshRequestId);
1011 this._refreshRequestId = null;
1012 }
1013
1014 this.removeAllNodeHighlights();
1015
1016 this._timeCalculator.updateBoundariesForEventTime(this._mainRequestLoadTime);
1017 this._durationCalculator.updateBoundariesForEventTime(this._mainRequestLoadTime);
1018 this._timeCalculator.updateBoundariesForEventTime(this._mainRequestDOMContentLoadedTime);
1019 this._durationCalculator.updateBoundariesForEventTime(this._mainRequestDOMContentLoadedTime);
1020
1021 /** @type {!Map<!Network.NetworkNode, !Network.NetworkNode>} */
1022 const nodesToInsert = new Map();
1023 /** @type {!Array<!Network.NetworkNode>} */
1024 const nodesToRefresh = [];
1025
1026 /** @type {!Set<!Network.NetworkRequestNode>} */
1027 const staleNodes = new Set();
1028
1029 // While creating nodes it may add more entries into _staleRequests because redirect request nodes update the parent
1030 // node so we loop until we have no more stale requests.
1031 while (this._staleRequests.size) {
1032 const request = this._staleRequests.firstValue();
1033 this._staleRequests.delete(request);
1034 let node = request[Network.NetworkLogView._networkNodeSymbol];
Tim van der Lippe1d6e57a2019-09-30 11:55:341035 if (!node) {
Blink Reformat4c46d092018-04-07 15:32:371036 node = this._createNodeForRequest(request);
Tim van der Lippe1d6e57a2019-09-30 11:55:341037 }
Blink Reformat4c46d092018-04-07 15:32:371038 staleNodes.add(node);
1039 }
1040
1041 for (const node of staleNodes) {
1042 const isFilteredOut = !this._applyFilter(node);
Tim van der Lippe1d6e57a2019-09-30 11:55:341043 if (isFilteredOut && node === this._hoveredNode) {
Blink Reformat4c46d092018-04-07 15:32:371044 this._setHoveredNode(null);
Tim van der Lippe1d6e57a2019-09-30 11:55:341045 }
Blink Reformat4c46d092018-04-07 15:32:371046
Tim van der Lippe1d6e57a2019-09-30 11:55:341047 if (!isFilteredOut) {
Blink Reformat4c46d092018-04-07 15:32:371048 nodesToRefresh.push(node);
Tim van der Lippe1d6e57a2019-09-30 11:55:341049 }
Blink Reformat4c46d092018-04-07 15:32:371050 const request = node.request();
1051 this._timeCalculator.updateBoundaries(request);
1052 this._durationCalculator.updateBoundaries(request);
1053 const newParent = this._parentNodeForInsert(node);
Tim van der Lippe1d6e57a2019-09-30 11:55:341054 if (node[Network.NetworkLogView._isFilteredOutSymbol] === isFilteredOut && node.parent === newParent) {
Blink Reformat4c46d092018-04-07 15:32:371055 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341056 }
Blink Reformat4c46d092018-04-07 15:32:371057 node[Network.NetworkLogView._isFilteredOutSymbol] = isFilteredOut;
1058 const removeFromParent = node.parent && (isFilteredOut || node.parent !== newParent);
1059 if (removeFromParent) {
1060 let parent = node.parent;
1061 parent.removeChild(node);
1062 while (parent && !parent.hasChildren() && parent.dataGrid && parent.dataGrid.rootNode() !== parent) {
1063 const grandparent = parent.parent;
1064 grandparent.removeChild(parent);
1065 parent = grandparent;
1066 }
1067 }
1068
Tim van der Lippe1d6e57a2019-09-30 11:55:341069 if (!newParent || isFilteredOut) {
Blink Reformat4c46d092018-04-07 15:32:371070 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341071 }
Blink Reformat4c46d092018-04-07 15:32:371072
1073 if (!newParent.dataGrid && !nodesToInsert.has(newParent)) {
1074 nodesToInsert.set(newParent, this._dataGrid.rootNode());
1075 nodesToRefresh.push(newParent);
1076 }
1077 nodesToInsert.set(node, newParent);
1078 }
1079
Tim van der Lippe1d6e57a2019-09-30 11:55:341080 for (const node of nodesToInsert.keys()) {
Blink Reformat4c46d092018-04-07 15:32:371081 nodesToInsert.get(node).appendChild(node);
Tim van der Lippe1d6e57a2019-09-30 11:55:341082 }
Blink Reformat4c46d092018-04-07 15:32:371083
Tim van der Lippe1d6e57a2019-09-30 11:55:341084 for (const node of nodesToRefresh) {
Blink Reformat4c46d092018-04-07 15:32:371085 node.refresh();
Tim van der Lippe1d6e57a2019-09-30 11:55:341086 }
Blink Reformat4c46d092018-04-07 15:32:371087
1088 this._updateSummaryBar();
1089
Tim van der Lippe1d6e57a2019-09-30 11:55:341090 if (nodesToInsert.size) {
Blink Reformat4c46d092018-04-07 15:32:371091 this._columns.sortByCurrentColumn();
Tim van der Lippe1d6e57a2019-09-30 11:55:341092 }
Blink Reformat4c46d092018-04-07 15:32:371093
1094 this._dataGrid.updateInstantly();
1095 this._didRefreshForTest();
1096 }
1097
1098 _didRefreshForTest() {
1099 }
1100
1101 /**
1102 * @param {!Network.NetworkRequestNode} node
1103 * @return {?Network.NetworkNode}
1104 */
1105 _parentNodeForInsert(node) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341106 if (!this._activeGroupLookup) {
Blink Reformat4c46d092018-04-07 15:32:371107 return this._dataGrid.rootNode();
Tim van der Lippe1d6e57a2019-09-30 11:55:341108 }
Blink Reformat4c46d092018-04-07 15:32:371109
1110 const groupNode = this._activeGroupLookup.groupNodeForRequest(node.request());
Tim van der Lippe1d6e57a2019-09-30 11:55:341111 if (!groupNode) {
Blink Reformat4c46d092018-04-07 15:32:371112 return this._dataGrid.rootNode();
Tim van der Lippe1d6e57a2019-09-30 11:55:341113 }
Blink Reformat4c46d092018-04-07 15:32:371114 return groupNode;
1115 }
1116
1117 _reset() {
Brandon Goddard88d885a2019-10-31 16:11:051118 this.dispatchEventToListeners(Network.NetworkLogView.Events.RequestActivated, /* showPanel */ true);
Blink Reformat4c46d092018-04-07 15:32:371119
1120 this._setHoveredNode(null);
1121 this._columns.reset();
1122
1123 this._timeFilter = null;
1124 this._calculator.reset();
1125
1126 this._timeCalculator.setWindow(null);
1127 this.linkifier.reset();
Blink Reformat4c46d092018-04-07 15:32:371128
Tim van der Lippe1d6e57a2019-09-30 11:55:341129 if (this._activeGroupLookup) {
Blink Reformat4c46d092018-04-07 15:32:371130 this._activeGroupLookup.reset();
Tim van der Lippe1d6e57a2019-09-30 11:55:341131 }
Blink Reformat4c46d092018-04-07 15:32:371132 this._staleRequests.clear();
1133 this._resetSuggestionBuilder();
1134
1135 this._mainRequestLoadTime = -1;
1136 this._mainRequestDOMContentLoadedTime = -1;
1137
1138 this._dataGrid.rootNode().removeChildren();
1139 this._updateSummaryBar();
1140 this._dataGrid.setStickToBottom(true);
1141 this.scheduleRefresh();
1142 }
1143
1144 /**
1145 * @param {string} filterString
1146 */
1147 setTextFilterValue(filterString) {
1148 this._textFilterUI.setValue(filterString);
1149 this._dataURLFilterUI.setChecked(false);
1150 this._resourceCategoryFilterUI.reset();
1151 }
1152
1153 /**
1154 * @param {!SDK.NetworkRequest} request
1155 */
1156 _createNodeForRequest(request) {
1157 const node = new Network.NetworkRequestNode(this, request);
1158 request[Network.NetworkLogView._networkNodeSymbol] = node;
1159 node[Network.NetworkLogView._isFilteredOutSymbol] = true;
1160
Tim van der Lippe1d6e57a2019-09-30 11:55:341161 for (let redirect = request.redirectSource(); redirect; redirect = redirect.redirectSource()) {
Blink Reformat4c46d092018-04-07 15:32:371162 this._refreshRequest(redirect);
Tim van der Lippe1d6e57a2019-09-30 11:55:341163 }
Blink Reformat4c46d092018-04-07 15:32:371164 return node;
1165 }
1166
1167 /**
1168 * @param {!Common.Event} event
1169 */
1170 _onRequestUpdated(event) {
1171 const request = /** @type {!SDK.NetworkRequest} */ (event.data);
1172 this._refreshRequest(request);
1173 }
1174
1175 /**
1176 * @param {!SDK.NetworkRequest} request
1177 */
1178 _refreshRequest(request) {
1179 Network.NetworkLogView._subdomains(request.domain)
1180 .forEach(
1181 this._suggestionBuilder.addItem.bind(this._suggestionBuilder, Network.NetworkLogView.FilterType.Domain));
1182 this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.Method, request.requestMethod);
1183 this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.MimeType, request.mimeType);
1184 this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.Scheme, '' + request.scheme);
1185 this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.StatusCode, '' + request.statusCode);
1186
1187 const priority = request.priority();
1188 if (priority) {
1189 this._suggestionBuilder.addItem(
1190 Network.NetworkLogView.FilterType.Priority, PerfUI.uiLabelForNetworkPriority(priority));
1191 }
1192
1193 if (request.mixedContentType !== Protocol.Security.MixedContentType.None) {
1194 this._suggestionBuilder.addItem(
1195 Network.NetworkLogView.FilterType.MixedContent, Network.NetworkLogView.MixedContentFilterValues.All);
1196 }
1197
1198 if (request.mixedContentType === Protocol.Security.MixedContentType.OptionallyBlockable) {
1199 this._suggestionBuilder.addItem(
1200 Network.NetworkLogView.FilterType.MixedContent, Network.NetworkLogView.MixedContentFilterValues.Displayed);
1201 }
1202
1203 if (request.mixedContentType === Protocol.Security.MixedContentType.Blockable) {
1204 const suggestion = request.wasBlocked() ? Network.NetworkLogView.MixedContentFilterValues.Blocked :
1205 Network.NetworkLogView.MixedContentFilterValues.BlockOverridden;
1206 this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.MixedContent, suggestion);
1207 }
1208
1209 const responseHeaders = request.responseHeaders;
Tim van der Lippe1d6e57a2019-09-30 11:55:341210 for (let i = 0, l = responseHeaders.length; i < l; ++i) {
Blink Reformat4c46d092018-04-07 15:32:371211 this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.HasResponseHeader, responseHeaders[i].name);
Tim van der Lippe1d6e57a2019-09-30 11:55:341212 }
Blink Reformat4c46d092018-04-07 15:32:371213 const cookies = request.responseCookies;
1214 for (let i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
1215 const cookie = cookies[i];
1216 this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.SetCookieDomain, cookie.domain());
1217 this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.SetCookieName, cookie.name());
1218 this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.SetCookieValue, cookie.value());
1219 }
1220
1221 this._staleRequests.add(request);
1222 this.scheduleRefresh();
1223 }
1224
1225 /**
1226 * @return {number}
1227 */
1228 rowHeight() {
1229 return this._rowHeight;
1230 }
1231
1232 /**
1233 * @param {boolean} gridMode
1234 */
1235 switchViewMode(gridMode) {
1236 this._columns.switchViewMode(gridMode);
1237 }
1238
1239 /**
1240 * @param {!UI.ContextMenu} contextMenu
1241 * @param {!SDK.NetworkRequest} request
1242 */
1243 handleContextMenuForRequest(contextMenu, request) {
1244 contextMenu.appendApplicableItems(request);
1245 let copyMenu = contextMenu.clipboardSection().appendSubMenuItem(Common.UIString('Copy'));
1246 const footerSection = copyMenu.footerSection();
1247 if (request) {
1248 copyMenu.defaultSection().appendItem(
Tim van der Lippe50cfa9b2019-10-01 10:40:581249 UI.copyLinkAddressLabel(),
1250 Host.InspectorFrontendHost.copyText.bind(Host.InspectorFrontendHost, request.contentURL()));
Blink Reformat4c46d092018-04-07 15:32:371251 if (request.requestHeadersText()) {
1252 copyMenu.defaultSection().appendItem(
1253 Common.UIString('Copy request headers'), Network.NetworkLogView._copyRequestHeaders.bind(null, request));
1254 }
1255
1256 if (request.responseHeadersText) {
1257 copyMenu.defaultSection().appendItem(
1258 Common.UIString('Copy response headers'), Network.NetworkLogView._copyResponseHeaders.bind(null, request));
1259 }
1260
1261 if (request.finished) {
1262 copyMenu.defaultSection().appendItem(
1263 Common.UIString('Copy response'), Network.NetworkLogView._copyResponse.bind(null, request));
1264 }
1265
Harley Libcf41f92018-09-10 18:01:131266 const disableIfBlob = request.isBlobRequest();
Blink Reformat4c46d092018-04-07 15:32:371267 if (Host.isWin()) {
1268 footerSection.appendItem(
Harley Libcf41f92018-09-10 18:01:131269 Common.UIString('Copy as PowerShell'), this._copyPowerShellCommand.bind(this, request), disableIfBlob);
Blink Reformat4c46d092018-04-07 15:32:371270 footerSection.appendItem(
Harley Libcf41f92018-09-10 18:01:131271 Common.UIString('Copy as fetch'), this._copyFetchCall.bind(this, request), disableIfBlob);
Blink Reformat4c46d092018-04-07 15:32:371272 footerSection.appendItem(
Harley Libcf41f92018-09-10 18:01:131273 Common.UIString('Copy as cURL (cmd)'), this._copyCurlCommand.bind(this, request, 'win'), disableIfBlob);
1274 footerSection.appendItem(
1275 Common.UIString('Copy as cURL (bash)'), this._copyCurlCommand.bind(this, request, 'unix'), disableIfBlob);
Blink Reformat4c46d092018-04-07 15:32:371276 footerSection.appendItem(Common.UIString('Copy all as PowerShell'), this._copyAllPowerShellCommand.bind(this));
1277 footerSection.appendItem(Common.UIString('Copy all as fetch'), this._copyAllFetchCall.bind(this));
1278 footerSection.appendItem(Common.UIString('Copy all as cURL (cmd)'), this._copyAllCurlCommand.bind(this, 'win'));
1279 footerSection.appendItem(
1280 Common.UIString('Copy all as cURL (bash)'), this._copyAllCurlCommand.bind(this, 'unix'));
1281 } else {
Harley Libcf41f92018-09-10 18:01:131282 footerSection.appendItem(
1283 Common.UIString('Copy as fetch'), this._copyFetchCall.bind(this, request), disableIfBlob);
1284 footerSection.appendItem(
1285 Common.UIString('Copy as cURL'), this._copyCurlCommand.bind(this, request, 'unix'), disableIfBlob);
Blink Reformat4c46d092018-04-07 15:32:371286 footerSection.appendItem(Common.UIString('Copy all as fetch'), this._copyAllFetchCall.bind(this));
1287 footerSection.appendItem(Common.UIString('Copy all as cURL'), this._copyAllCurlCommand.bind(this, 'unix'));
1288 }
1289 } else {
1290 copyMenu = contextMenu.clipboardSection().appendSubMenuItem(Common.UIString('Copy'));
1291 }
1292 footerSection.appendItem(Common.UIString('Copy all as HAR'), this._copyAll.bind(this));
1293
Joey Arhar0e1093c2019-05-21 00:34:221294 contextMenu.saveSection().appendItem(ls`Save all as HAR with content`, this.exportAll.bind(this));
Blink Reformat4c46d092018-04-07 15:32:371295
1296 contextMenu.editSection().appendItem(Common.UIString('Clear browser cache'), this._clearBrowserCache.bind(this));
1297 contextMenu.editSection().appendItem(
1298 Common.UIString('Clear browser cookies'), this._clearBrowserCookies.bind(this));
1299
1300 if (request) {
1301 const maxBlockedURLLength = 20;
1302 const manager = SDK.multitargetNetworkManager;
1303 let patterns = manager.blockedPatterns();
1304
Tim van der Lippeffa78622019-09-16 12:07:121305 /**
1306 * @param {string} url
1307 */
1308 function addBlockedURL(url) {
1309 patterns.push({enabled: true, url: url});
1310 manager.setBlockedPatterns(patterns);
1311 manager.setBlockingEnabled(true);
1312 UI.viewManager.showView('network.blocked-urls');
1313 }
1314
1315 /**
1316 * @param {string} url
1317 */
1318 function removeBlockedURL(url) {
1319 patterns = patterns.filter(pattern => pattern.url !== url);
1320 manager.setBlockedPatterns(patterns);
1321 UI.viewManager.showView('network.blocked-urls');
1322 }
1323
Blink Reformat4c46d092018-04-07 15:32:371324 const urlWithoutScheme = request.parsedURL.urlWithoutScheme();
1325 if (urlWithoutScheme && !patterns.find(pattern => pattern.url === urlWithoutScheme)) {
1326 contextMenu.debugSection().appendItem(
1327 Common.UIString('Block request URL'), addBlockedURL.bind(null, urlWithoutScheme));
1328 } else if (urlWithoutScheme) {
1329 const croppedURL = urlWithoutScheme.trimMiddle(maxBlockedURLLength);
1330 contextMenu.debugSection().appendItem(
1331 Common.UIString('Unblock %s', croppedURL), removeBlockedURL.bind(null, urlWithoutScheme));
1332 }
1333
1334 const domain = request.parsedURL.domain();
1335 if (domain && !patterns.find(pattern => pattern.url === domain)) {
1336 contextMenu.debugSection().appendItem(
1337 Common.UIString('Block request domain'), addBlockedURL.bind(null, domain));
1338 } else if (domain) {
1339 const croppedDomain = domain.trimMiddle(maxBlockedURLLength);
1340 contextMenu.debugSection().appendItem(
1341 Common.UIString('Unblock %s', croppedDomain), removeBlockedURL.bind(null, domain));
1342 }
1343
1344 if (SDK.NetworkManager.canReplayRequest(request)) {
1345 contextMenu.debugSection().appendItem(
1346 Common.UIString('Replay XHR'), SDK.NetworkManager.replayRequest.bind(null, request));
1347 }
Blink Reformat4c46d092018-04-07 15:32:371348 }
1349 }
1350
1351 _harRequests() {
Joey Arharb3d6de42019-04-23 21:26:171352 return SDK.networkLog.requests().filter(Network.NetworkLogView.HTTPRequestsFilter).filter(request => {
1353 return request.finished ||
1354 (request.resourceType() === Common.resourceTypes.WebSocket && request.responseReceivedTime);
1355 });
Blink Reformat4c46d092018-04-07 15:32:371356 }
1357
1358 async _copyAll() {
Pavel Feldman18d13562018-07-31 03:31:181359 const harArchive = {log: await SDK.HARLog.build(this._harRequests())};
Tim van der Lippe50cfa9b2019-10-01 10:40:581360 Host.InspectorFrontendHost.copyText(JSON.stringify(harArchive, null, 2));
Blink Reformat4c46d092018-04-07 15:32:371361 }
1362
1363 /**
1364 * @param {!SDK.NetworkRequest} request
1365 * @param {string} platform
1366 */
1367 async _copyCurlCommand(request, platform) {
1368 const command = await this._generateCurlCommand(request, platform);
Tim van der Lippe50cfa9b2019-10-01 10:40:581369 Host.InspectorFrontendHost.copyText(command);
Blink Reformat4c46d092018-04-07 15:32:371370 }
1371
1372 /**
1373 * @param {string} platform
1374 */
1375 async _copyAllCurlCommand(platform) {
Harley Libcf41f92018-09-10 18:01:131376 const commands = await this._generateAllCurlCommand(SDK.networkLog.requests(), platform);
Tim van der Lippe50cfa9b2019-10-01 10:40:581377 Host.InspectorFrontendHost.copyText(commands);
Blink Reformat4c46d092018-04-07 15:32:371378 }
1379
1380 /**
1381 * @param {!SDK.NetworkRequest} request
1382 * @param {string} platform
1383 */
1384 async _copyFetchCall(request, platform) {
1385 const command = await this._generateFetchCall(request);
Tim van der Lippe50cfa9b2019-10-01 10:40:581386 Host.InspectorFrontendHost.copyText(command);
Blink Reformat4c46d092018-04-07 15:32:371387 }
1388
1389 async _copyAllFetchCall() {
Harley Libcf41f92018-09-10 18:01:131390 const commands = await this._generateAllFetchCall(SDK.networkLog.requests());
Tim van der Lippe50cfa9b2019-10-01 10:40:581391 Host.InspectorFrontendHost.copyText(commands);
Blink Reformat4c46d092018-04-07 15:32:371392 }
1393
1394 /**
1395 * @param {!SDK.NetworkRequest} request
1396 */
1397 async _copyPowerShellCommand(request) {
1398 const command = await this._generatePowerShellCommand(request);
Tim van der Lippe50cfa9b2019-10-01 10:40:581399 Host.InspectorFrontendHost.copyText(command);
Blink Reformat4c46d092018-04-07 15:32:371400 }
1401
1402 async _copyAllPowerShellCommand() {
Harley Li5a470e92019-09-26 21:38:351403 const commands = await this._generateAllPowerShellCommand(SDK.networkLog.requests());
Tim van der Lippe50cfa9b2019-10-01 10:40:581404 Host.InspectorFrontendHost.copyText(commands);
Blink Reformat4c46d092018-04-07 15:32:371405 }
1406
Joey Arhar0e1093c2019-05-21 00:34:221407 async exportAll() {
Blink Reformat4c46d092018-04-07 15:32:371408 const url = SDK.targetManager.mainTarget().inspectedURL();
1409 const parsedURL = url.asParsedURL();
1410 const filename = parsedURL ? parsedURL.host : 'network-log';
1411 const stream = new Bindings.FileOutputStream();
1412
Tim van der Lippe1d6e57a2019-09-30 11:55:341413 if (!await stream.open(filename + '.har')) {
Blink Reformat4c46d092018-04-07 15:32:371414 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341415 }
Blink Reformat4c46d092018-04-07 15:32:371416
1417 const progressIndicator = new UI.ProgressIndicator();
1418 this._progressBarContainer.appendChild(progressIndicator.element);
1419 await Network.HARWriter.write(stream, this._harRequests(), progressIndicator);
1420 progressIndicator.done();
1421 stream.close();
1422 }
1423
1424 _clearBrowserCache() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341425 if (confirm(Common.UIString('Are you sure you want to clear browser cache?'))) {
Blink Reformat4c46d092018-04-07 15:32:371426 SDK.multitargetNetworkManager.clearBrowserCache();
Tim van der Lippe1d6e57a2019-09-30 11:55:341427 }
Blink Reformat4c46d092018-04-07 15:32:371428 }
1429
1430 _clearBrowserCookies() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341431 if (confirm(Common.UIString('Are you sure you want to clear browser cookies?'))) {
Blink Reformat4c46d092018-04-07 15:32:371432 SDK.multitargetNetworkManager.clearBrowserCookies();
Tim van der Lippe1d6e57a2019-09-30 11:55:341433 }
Blink Reformat4c46d092018-04-07 15:32:371434 }
1435
1436 _removeAllHighlights() {
1437 this.removeAllNodeHighlights();
Tim van der Lippe1d6e57a2019-09-30 11:55:341438 for (let i = 0; i < this._highlightedSubstringChanges.length; ++i) {
Blink Reformat4c46d092018-04-07 15:32:371439 UI.revertDomChanges(this._highlightedSubstringChanges[i]);
Tim van der Lippe1d6e57a2019-09-30 11:55:341440 }
Blink Reformat4c46d092018-04-07 15:32:371441 this._highlightedSubstringChanges = [];
1442 }
1443
1444 /**
1445 * @param {!Network.NetworkRequestNode} node
1446 * @return {boolean}
1447 */
1448 _applyFilter(node) {
1449 const request = node.request();
Tim van der Lippe1d6e57a2019-09-30 11:55:341450 if (this._timeFilter && !this._timeFilter(request)) {
Blink Reformat4c46d092018-04-07 15:32:371451 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:341452 }
Blink Reformat4c46d092018-04-07 15:32:371453 const categoryName = request.resourceType().category().title;
Tim van der Lippe1d6e57a2019-09-30 11:55:341454 if (!this._resourceCategoryFilterUI.accept(categoryName)) {
Blink Reformat4c46d092018-04-07 15:32:371455 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:341456 }
1457 if (this._dataURLFilterUI.checked() && (request.parsedURL.isDataURL() || request.parsedURL.isBlobURL())) {
Blink Reformat4c46d092018-04-07 15:32:371458 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:341459 }
1460 if (request.statusText === 'Service Worker Fallback Required') {
Blink Reformat4c46d092018-04-07 15:32:371461 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:341462 }
Blink Reformat4c46d092018-04-07 15:32:371463 for (let i = 0; i < this._filters.length; ++i) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341464 if (!this._filters[i](request)) {
Blink Reformat4c46d092018-04-07 15:32:371465 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:341466 }
Blink Reformat4c46d092018-04-07 15:32:371467 }
1468 return true;
1469 }
1470
1471 /**
1472 * @param {string} query
1473 */
1474 _parseFilterQuery(query) {
1475 const descriptors = this._filterParser.parse(query);
1476 this._filters = descriptors.map(descriptor => {
1477 const key = descriptor.key;
1478 const text = descriptor.text || '';
1479 const regex = descriptor.regex;
1480 let filter;
1481 if (key) {
1482 const defaultText = (key + ':' + text).escapeForRegExp();
1483 filter = this._createSpecialFilter(/** @type {!Network.NetworkLogView.FilterType} */ (key), text) ||
1484 Network.NetworkLogView._requestPathFilter.bind(null, new RegExp(defaultText, 'i'));
1485 } else if (descriptor.regex) {
1486 filter = Network.NetworkLogView._requestPathFilter.bind(null, /** @type {!RegExp} */ (regex));
1487 } else {
1488 filter = Network.NetworkLogView._requestPathFilter.bind(null, new RegExp(text.escapeForRegExp(), 'i'));
1489 }
1490 return descriptor.negative ? Network.NetworkLogView._negativeFilter.bind(null, filter) : filter;
1491 });
1492 }
1493
1494 /**
1495 * @param {!Network.NetworkLogView.FilterType} type
1496 * @param {string} value
1497 * @return {?Network.NetworkLogView.Filter}
1498 */
1499 _createSpecialFilter(type, value) {
1500 switch (type) {
1501 case Network.NetworkLogView.FilterType.Domain:
1502 return Network.NetworkLogView._createRequestDomainFilter(value);
1503
1504 case Network.NetworkLogView.FilterType.HasResponseHeader:
1505 return Network.NetworkLogView._requestResponseHeaderFilter.bind(null, value);
1506
1507 case Network.NetworkLogView.FilterType.Is:
Tim van der Lippe1d6e57a2019-09-30 11:55:341508 if (value.toLowerCase() === Network.NetworkLogView.IsFilterType.Running) {
Blink Reformat4c46d092018-04-07 15:32:371509 return Network.NetworkLogView._runningRequestFilter;
Tim van der Lippe1d6e57a2019-09-30 11:55:341510 }
1511 if (value.toLowerCase() === Network.NetworkLogView.IsFilterType.FromCache) {
Blink Reformat4c46d092018-04-07 15:32:371512 return Network.NetworkLogView._fromCacheRequestFilter;
Tim van der Lippe1d6e57a2019-09-30 11:55:341513 }
1514 if (value.toLowerCase() === Network.NetworkLogView.IsFilterType.ServiceWorkerIntercepted) {
Joey Arhard183e7e2019-02-28 03:37:051515 return Network.NetworkLogView._interceptedByServiceWorkerFilter;
Tim van der Lippe1d6e57a2019-09-30 11:55:341516 }
1517 if (value.toLowerCase() === Network.NetworkLogView.IsFilterType.ServiceWorkerInitiated) {
Joey Arhard183e7e2019-02-28 03:37:051518 return Network.NetworkLogView._initiatedByServiceWorkerFilter;
Tim van der Lippe1d6e57a2019-09-30 11:55:341519 }
Blink Reformat4c46d092018-04-07 15:32:371520 break;
1521
1522 case Network.NetworkLogView.FilterType.LargerThan:
1523 return this._createSizeFilter(value.toLowerCase());
1524
1525 case Network.NetworkLogView.FilterType.Method:
1526 return Network.NetworkLogView._requestMethodFilter.bind(null, value);
1527
1528 case Network.NetworkLogView.FilterType.MimeType:
1529 return Network.NetworkLogView._requestMimeTypeFilter.bind(null, value);
1530
1531 case Network.NetworkLogView.FilterType.MixedContent:
1532 return Network.NetworkLogView._requestMixedContentFilter.bind(
1533 null, /** @type {!Network.NetworkLogView.MixedContentFilterValues} */ (value));
1534
1535 case Network.NetworkLogView.FilterType.Scheme:
1536 return Network.NetworkLogView._requestSchemeFilter.bind(null, value);
1537
1538 case Network.NetworkLogView.FilterType.SetCookieDomain:
1539 return Network.NetworkLogView._requestSetCookieDomainFilter.bind(null, value);
1540
1541 case Network.NetworkLogView.FilterType.SetCookieName:
1542 return Network.NetworkLogView._requestSetCookieNameFilter.bind(null, value);
1543
1544 case Network.NetworkLogView.FilterType.SetCookieValue:
1545 return Network.NetworkLogView._requestSetCookieValueFilter.bind(null, value);
1546
1547 case Network.NetworkLogView.FilterType.Priority:
1548 return Network.NetworkLogView._requestPriorityFilter.bind(null, PerfUI.uiLabelToNetworkPriority(value));
1549
1550 case Network.NetworkLogView.FilterType.StatusCode:
1551 return Network.NetworkLogView._statusCodeFilter.bind(null, value);
1552 }
1553 return null;
1554 }
1555
1556 /**
1557 * @param {string} value
1558 * @return {?Network.NetworkLogView.Filter}
1559 */
1560 _createSizeFilter(value) {
1561 let multiplier = 1;
1562 if (value.endsWith('k')) {
1563 multiplier = 1024;
1564 value = value.substring(0, value.length - 1);
1565 } else if (value.endsWith('m')) {
1566 multiplier = 1024 * 1024;
1567 value = value.substring(0, value.length - 1);
1568 }
1569 const quantity = Number(value);
Tim van der Lippe1d6e57a2019-09-30 11:55:341570 if (isNaN(quantity)) {
Blink Reformat4c46d092018-04-07 15:32:371571 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341572 }
Blink Reformat4c46d092018-04-07 15:32:371573 return Network.NetworkLogView._requestSizeLargerThanFilter.bind(null, quantity * multiplier);
1574 }
1575
1576 _filterRequests() {
1577 this._removeAllHighlights();
1578 this._invalidateAllItems();
1579 }
1580
1581 /**
1582 * @param {!SDK.NetworkRequest} request
1583 * @return {?Network.NetworkRequestNode}
1584 */
1585 _reveal(request) {
1586 this.removeAllNodeHighlights();
1587 const node = request[Network.NetworkLogView._networkNodeSymbol];
Tim van der Lippe1d6e57a2019-09-30 11:55:341588 if (!node || !node.dataGrid) {
Blink Reformat4c46d092018-04-07 15:32:371589 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341590 }
Blink Reformat4c46d092018-04-07 15:32:371591 node.reveal();
1592 return node;
1593 }
1594
1595 /**
1596 * @param {!SDK.NetworkRequest} request
1597 */
1598 revealAndHighlightRequest(request) {
1599 const node = this._reveal(request);
Tim van der Lippe1d6e57a2019-09-30 11:55:341600 if (node) {
Blink Reformat4c46d092018-04-07 15:32:371601 this._highlightNode(node);
Tim van der Lippe1d6e57a2019-09-30 11:55:341602 }
Blink Reformat4c46d092018-04-07 15:32:371603 }
1604
1605 /**
1606 * @param {!SDK.NetworkRequest} request
1607 */
1608 selectRequest(request) {
Eugene Ostroukhovb600f662018-05-09 00:18:141609 this.setTextFilterValue('');
Blink Reformat4c46d092018-04-07 15:32:371610 const node = this._reveal(request);
Tim van der Lippe1d6e57a2019-09-30 11:55:341611 if (node) {
Blink Reformat4c46d092018-04-07 15:32:371612 node.select();
Tim van der Lippe1d6e57a2019-09-30 11:55:341613 }
Blink Reformat4c46d092018-04-07 15:32:371614 }
1615
1616 removeAllNodeHighlights() {
1617 if (this._highlightedNode) {
1618 this._highlightedNode.element().classList.remove('highlighted-row');
1619 this._highlightedNode = null;
1620 }
1621 }
1622
1623 /**
1624 * @param {!Network.NetworkRequestNode} node
1625 */
1626 _highlightNode(node) {
1627 UI.runCSSAnimationOnce(node.element(), 'highlighted-row');
1628 this._highlightedNode = node;
1629 }
1630
1631 /**
Harley Libcf41f92018-09-10 18:01:131632 * @param {!Array<!SDK.NetworkRequest>} requests
1633 * @return {!Array<!SDK.NetworkRequest>}
1634 */
1635 _filterOutBlobRequests(requests) {
1636 return requests.filter(request => !request.isBlobRequest());
1637 }
1638
1639 /**
Blink Reformat4c46d092018-04-07 15:32:371640 * @param {!SDK.NetworkRequest} request
1641 * @return {!Promise<string>}
1642 */
1643 async _generateFetchCall(request) {
1644 const ignoredHeaders = {
1645 // Internal headers
1646 'method': 1,
1647 'path': 1,
1648 'scheme': 1,
1649 'version': 1,
1650
1651 // Unsafe headers
1652 // Keep this list synchronized with src/net/http/http_util.cc
1653 'accept-charset': 1,
1654 'accept-encoding': 1,
1655 'access-control-request-headers': 1,
1656 'access-control-request-method': 1,
1657 'connection': 1,
1658 'content-length': 1,
1659 'cookie': 1,
1660 'cookie2': 1,
1661 'date': 1,
1662 'dnt': 1,
1663 'expect': 1,
1664 'host': 1,
1665 'keep-alive': 1,
1666 'origin': 1,
1667 'referer': 1,
1668 'te': 1,
1669 'trailer': 1,
1670 'transfer-encoding': 1,
1671 'upgrade': 1,
1672 'via': 1,
1673 // TODO(phistuck) - remove this once crbug.com/571722 is fixed.
1674 'user-agent': 1
1675 };
1676
1677 const credentialHeaders = {'cookie': 1, 'authorization': 1};
1678
1679 const url = JSON.stringify(request.url());
1680
1681 const requestHeaders = request.requestHeaders();
1682 const headerData = requestHeaders.reduce((result, header) => {
1683 const name = header.name;
1684
Tim van der Lippe1d6e57a2019-09-30 11:55:341685 if (!ignoredHeaders[name.toLowerCase()] && !name.includes(':')) {
Blink Reformat4c46d092018-04-07 15:32:371686 result.append(name, header.value);
Tim van der Lippe1d6e57a2019-09-30 11:55:341687 }
Blink Reformat4c46d092018-04-07 15:32:371688
1689 return result;
1690 }, new Headers());
1691
1692 const headers = {};
Tim van der Lippe1d6e57a2019-09-30 11:55:341693 for (const headerArray of headerData) {
PhistucK6ed0a3e2018-08-04 06:28:411694 headers[headerArray[0]] = headerArray[1];
Tim van der Lippe1d6e57a2019-09-30 11:55:341695 }
Blink Reformat4c46d092018-04-07 15:32:371696
1697 const credentials =
1698 request.requestCookies || requestHeaders.some(({name}) => credentialHeaders[name.toLowerCase()]) ? 'include' :
1699 'omit';
1700
1701 const referrerHeader = requestHeaders.find(({name}) => name.toLowerCase() === 'referer');
1702
1703 const referrer = referrerHeader ? referrerHeader.value : void 0;
1704
1705 const referrerPolicy = request.referrerPolicy() || void 0;
1706
1707 const requestBody = await request.requestFormData();
1708
1709 const fetchOptions = {
1710 credentials,
PhistucK6ed0a3e2018-08-04 06:28:411711 headers: Object.keys(headers).length ? headers : void 0,
Blink Reformat4c46d092018-04-07 15:32:371712 referrer,
1713 referrerPolicy,
1714 body: requestBody,
1715 method: request.requestMethod,
1716 mode: 'cors'
1717 };
1718
1719 const options = JSON.stringify(fetchOptions);
1720 return `fetch(${url}, ${options});`;
1721 }
1722
1723 /**
Harley Libcf41f92018-09-10 18:01:131724 * @param {!Array<!SDK.NetworkRequest>} requests
1725 * @return {!Promise<string>}
1726 */
1727 async _generateAllFetchCall(requests) {
1728 const nonBlobRequests = this._filterOutBlobRequests(requests);
1729 const commands = await Promise.all(nonBlobRequests.map(request => this._generateFetchCall(request)));
1730 return commands.join(' ;\n');
1731 }
1732
1733 /**
Blink Reformat4c46d092018-04-07 15:32:371734 * @param {!SDK.NetworkRequest} request
1735 * @param {string} platform
1736 * @return {!Promise<string>}
1737 */
1738 async _generateCurlCommand(request, platform) {
1739 let command = ['curl'];
Eric Lawrence7a7b3682019-10-17 23:06:361740 // Most of these headers are derived from the URL and are automatically added by cURL.
1741 // The |Accept-Encoding| header is ignored to prevent decompression errors. crbug.com/1015321
1742 const ignoredHeaders = {'accept-encoding': 1, 'host': 1, 'method': 1, 'path': 1, 'scheme': 1, 'version': 1};
Blink Reformat4c46d092018-04-07 15:32:371743
1744 function escapeStringWin(str) {
1745 /* If there are no new line characters do not escape the " characters
1746 since it only uglifies the command.
1747
1748 Because cmd.exe parser and MS Crt arguments parsers use some of the
1749 same escape characters, they can interact with each other in
1750 horrible ways, the order of operations is critical.
1751
1752 Replace \ with \\ first because it is an escape character for certain
1753 conditions in both parsers.
1754
1755 Replace all " with \" to ensure the first parser does not remove it.
1756
1757 Then escape all characters we are not sure about with ^ to ensure it
1758 gets to MS Crt parser safely.
1759
1760 The % character is special because MS Crt parser will try and look for
1761 ENV variables and fill them in it's place. We cannot escape them with %
1762 and cannot escape them with ^ (because it's cmd.exe's escape not MS Crt
1763 parser); So we can get cmd.exe parser to escape the character after it,
1764 if it is followed by a valid beginning character of an ENV variable.
1765 This ensures we do not try and double escape another ^ if it was placed
1766 by the previous replace.
1767
1768 Lastly we replace new lines with ^ and TWO new lines because the first
1769 new line is there to enact the escape command the second is the character
1770 to escape (in this case new line).
1771 */
1772 const encapsChars = /[\r\n]/.test(str) ? '^"' : '"';
1773 return encapsChars +
1774 str.replace(/\\/g, '\\\\')
1775 .replace(/"/g, '\\"')
1776 .replace(/[^a-zA-Z0-9\s_\-:=+~'\/.',?;()*`]/g, '^$&')
1777 .replace(/%(?=[a-zA-Z0-9_])/g, '%^')
1778 .replace(/\r\n|[\n\r]/g, '^\n\n') +
1779 encapsChars;
1780 }
1781
1782 /**
1783 * @param {string} str
1784 * @return {string}
1785 */
1786 function escapeStringPosix(str) {
1787 /**
1788 * @param {string} x
1789 * @return {string}
1790 */
1791 function escapeCharacter(x) {
Erik Luoaa676752018-08-21 05:52:221792 const code = x.charCodeAt(0);
Joey Arhar2d21f712019-05-20 21:07:121793 let hexString = code.toString(16);
1794 // Zero pad to four digits to comply with ANSI-C Quoting:
1795 // http://www.gnu.org/software/bash/manual/html_node/ANSI_002dC-Quoting.html
Tim van der Lippe1d6e57a2019-09-30 11:55:341796 while (hexString.length < 4) {
Joey Arhar2d21f712019-05-20 21:07:121797 hexString = '0' + hexString;
Tim van der Lippe1d6e57a2019-09-30 11:55:341798 }
Joey Arhar2d21f712019-05-20 21:07:121799
1800 return '\\u' + hexString;
Blink Reformat4c46d092018-04-07 15:32:371801 }
1802
Joey Arhar512e3742019-01-25 21:33:541803 if (/[\u0000-\u001f\u007f-\u009f!]|\'/.test(str)) {
Blink Reformat4c46d092018-04-07 15:32:371804 // Use ANSI-C quoting syntax.
1805 return '$\'' +
1806 str.replace(/\\/g, '\\\\')
1807 .replace(/\'/g, '\\\'')
1808 .replace(/\n/g, '\\n')
1809 .replace(/\r/g, '\\r')
Joey Arhar512e3742019-01-25 21:33:541810 .replace(/[\u0000-\u001f\u007f-\u009f!]/g, escapeCharacter) +
Blink Reformat4c46d092018-04-07 15:32:371811 '\'';
1812 } else {
1813 // Use single quote syntax.
1814 return '\'' + str + '\'';
1815 }
1816 }
1817
1818 // cURL command expected to run on the same platform that DevTools run
1819 // (it may be different from the inspected page platform).
1820 const escapeString = platform === 'win' ? escapeStringWin : escapeStringPosix;
1821
1822 command.push(escapeString(request.url()).replace(/[[{}\]]/g, '\\$&'));
1823
1824 let inferredMethod = 'GET';
1825 const data = [];
1826 const requestContentType = request.requestContentType();
1827 const formData = await request.requestFormData();
1828 if (requestContentType && requestContentType.startsWith('application/x-www-form-urlencoded') && formData) {
1829 data.push('--data');
1830 data.push(escapeString(formData));
1831 ignoredHeaders['content-length'] = true;
1832 inferredMethod = 'POST';
1833 } else if (formData) {
1834 data.push('--data-binary');
1835 data.push(escapeString(formData));
1836 ignoredHeaders['content-length'] = true;
1837 inferredMethod = 'POST';
1838 }
1839
1840 if (request.requestMethod !== inferredMethod) {
1841 command.push('-X');
1842 command.push(request.requestMethod);
1843 }
1844
1845 const requestHeaders = request.requestHeaders();
1846 for (let i = 0; i < requestHeaders.length; i++) {
1847 const header = requestHeaders[i];
1848 const name = header.name.replace(/^:/, ''); // Translate SPDY v3 headers to HTTP headers.
Tim van der Lippe1d6e57a2019-09-30 11:55:341849 if (name.toLowerCase() in ignoredHeaders) {
Blink Reformat4c46d092018-04-07 15:32:371850 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341851 }
Blink Reformat4c46d092018-04-07 15:32:371852 command.push('-H');
1853 command.push(escapeString(name + ': ' + header.value));
1854 }
1855 command = command.concat(data);
1856 command.push('--compressed');
1857
Tim van der Lippe1d6e57a2019-09-30 11:55:341858 if (request.securityState() === Protocol.Security.SecurityState.Insecure) {
Blink Reformat4c46d092018-04-07 15:32:371859 command.push('--insecure');
Tim van der Lippe1d6e57a2019-09-30 11:55:341860 }
Blink Reformat4c46d092018-04-07 15:32:371861 return command.join(' ');
1862 }
1863
1864 /**
Harley Libcf41f92018-09-10 18:01:131865 * @param {!Array<!SDK.NetworkRequest>} requests
1866 * @param {string} platform
1867 * @return {!Promise<string>}
1868 */
1869 async _generateAllCurlCommand(requests, platform) {
1870 const nonBlobRequests = this._filterOutBlobRequests(requests);
1871 const commands = await Promise.all(nonBlobRequests.map(request => this._generateCurlCommand(request, platform)));
Tim van der Lippe1d6e57a2019-09-30 11:55:341872 if (platform === 'win') {
Harley Libcf41f92018-09-10 18:01:131873 return commands.join(' &\r\n');
Tim van der Lippe1d6e57a2019-09-30 11:55:341874 } else {
Harley Libcf41f92018-09-10 18:01:131875 return commands.join(' ;\n');
Tim van der Lippe1d6e57a2019-09-30 11:55:341876 }
Harley Libcf41f92018-09-10 18:01:131877 }
1878
1879 /**
Blink Reformat4c46d092018-04-07 15:32:371880 * @param {!SDK.NetworkRequest} request
1881 * @return {!Promise<string>}
1882 */
1883 async _generatePowerShellCommand(request) {
1884 const command = ['Invoke-WebRequest'];
1885 const ignoredHeaders =
1886 new Set(['host', 'connection', 'proxy-connection', 'content-length', 'expect', 'range', 'content-type']);
1887
1888 /**
1889 * @param {string} str
1890 * @return {string}
1891 */
1892 function escapeString(str) {
1893 return '"' +
1894 str.replace(/[`\$"]/g, '`$&').replace(/[^\x20-\x7E]/g, char => '$([char]' + char.charCodeAt(0) + ')') + '"';
1895 }
1896
1897 command.push('-Uri');
1898 command.push(escapeString(request.url()));
1899
1900 if (request.requestMethod !== 'GET') {
1901 command.push('-Method');
1902 command.push(escapeString(request.requestMethod));
1903 }
1904
1905 const requestHeaders = request.requestHeaders();
1906 const headerNameValuePairs = [];
1907 for (const header of requestHeaders) {
1908 const name = header.name.replace(/^:/, ''); // Translate h2 headers to HTTP headers.
Tim van der Lippe1d6e57a2019-09-30 11:55:341909 if (ignoredHeaders.has(name.toLowerCase())) {
Blink Reformat4c46d092018-04-07 15:32:371910 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341911 }
Blink Reformat4c46d092018-04-07 15:32:371912 headerNameValuePairs.push(escapeString(name) + '=' + escapeString(header.value));
1913 }
1914 if (headerNameValuePairs.length) {
1915 command.push('-Headers');
1916 command.push('@{' + headerNameValuePairs.join('; ') + '}');
1917 }
1918
1919 const contentTypeHeader = requestHeaders.find(({name}) => name.toLowerCase() === 'content-type');
1920 if (contentTypeHeader) {
1921 command.push('-ContentType');
1922 command.push(escapeString(contentTypeHeader.value));
1923 }
1924
1925 const formData = await request.requestFormData();
1926 if (formData) {
1927 command.push('-Body');
1928 const body = escapeString(formData);
Tim van der Lippe1d6e57a2019-09-30 11:55:341929 if (/[^\x20-\x7E]/.test(formData)) {
Blink Reformat4c46d092018-04-07 15:32:371930 command.push('([System.Text.Encoding]::UTF8.GetBytes(' + body + '))');
Tim van der Lippe1d6e57a2019-09-30 11:55:341931 } else {
Blink Reformat4c46d092018-04-07 15:32:371932 command.push(body);
Tim van der Lippe1d6e57a2019-09-30 11:55:341933 }
Blink Reformat4c46d092018-04-07 15:32:371934 }
1935
1936 return command.join(' ');
1937 }
Harley Libcf41f92018-09-10 18:01:131938
1939 /**
1940 * @param {!Array<!SDK.NetworkRequest>} requests
1941 * @return {!Promise<string>}
1942 */
1943 async _generateAllPowerShellCommand(requests) {
1944 const nonBlobRequests = this._filterOutBlobRequests(requests);
1945 const commands = await Promise.all(nonBlobRequests.map(request => this._generatePowerShellCommand(request)));
1946 return commands.join(';\r\n');
1947 }
Joey Arhara86c14e2019-03-12 03:20:501948
1949 /**
1950 * @return {string}
1951 */
1952 static getDCLEventColor() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341953 if (UI.themeSupport.themeName() === 'dark') {
Joey Arhara86c14e2019-03-12 03:20:501954 return '#03A9F4';
Tim van der Lippe1d6e57a2019-09-30 11:55:341955 }
Joey Arhara86c14e2019-03-12 03:20:501956 return '#0867CB';
1957 }
1958
1959 /**
1960 * @return {string}
1961 */
1962 static getLoadEventColor() {
1963 return UI.themeSupport.patchColorText('#B31412', UI.ThemeSupport.ColorUsage.Foreground);
1964 }
Blink Reformat4c46d092018-04-07 15:32:371965};
1966
1967Network.NetworkLogView._isFilteredOutSymbol = Symbol('isFilteredOut');
1968Network.NetworkLogView._networkNodeSymbol = Symbol('NetworkNode');
1969
1970Network.NetworkLogView.HTTPSchemas = {
1971 'http': true,
1972 'https': true,
1973 'ws': true,
1974 'wss': true
1975};
1976
1977/** @enum {symbol} */
1978Network.NetworkLogView.Events = {
Brandon Goddard88d885a2019-10-31 16:11:051979 RequestSelected: Symbol('RequestSelected'),
1980 RequestActivated: Symbol('RequestActivated')
Blink Reformat4c46d092018-04-07 15:32:371981};
1982
1983/** @enum {string} */
1984Network.NetworkLogView.FilterType = {
1985 Domain: 'domain',
1986 HasResponseHeader: 'has-response-header',
1987 Is: 'is',
1988 LargerThan: 'larger-than',
1989 Method: 'method',
1990 MimeType: 'mime-type',
1991 MixedContent: 'mixed-content',
1992 Priority: 'priority',
1993 Scheme: 'scheme',
1994 SetCookieDomain: 'set-cookie-domain',
1995 SetCookieName: 'set-cookie-name',
1996 SetCookieValue: 'set-cookie-value',
1997 StatusCode: 'status-code'
1998};
1999
2000/** @enum {string} */
2001Network.NetworkLogView.MixedContentFilterValues = {
2002 All: 'all',
2003 Displayed: 'displayed',
2004 Blocked: 'blocked',
2005 BlockOverridden: 'block-overridden'
2006};
2007
2008/** @enum {string} */
2009Network.NetworkLogView.IsFilterType = {
2010 Running: 'running',
Joey Arhard183e7e2019-02-28 03:37:052011 FromCache: 'from-cache',
2012 ServiceWorkerIntercepted: 'service-worker-intercepted',
2013 ServiceWorkerInitiated: 'service-worker-initiated'
Blink Reformat4c46d092018-04-07 15:32:372014};
2015
2016/** @type {!Array<string>} */
2017Network.NetworkLogView._searchKeys =
2018 Object.keys(Network.NetworkLogView.FilterType).map(key => Network.NetworkLogView.FilterType[key]);
2019
2020/** @typedef {function(!SDK.NetworkRequest): boolean} */
2021Network.NetworkLogView.Filter;
2022
2023/**
2024 * @interface
2025 */
2026Network.GroupLookupInterface = function() {};
2027
2028Network.GroupLookupInterface.prototype = {
2029 /**
2030 * @param {!SDK.NetworkRequest} request
2031 * @return {?Network.NetworkGroupNode}
2032 */
2033 groupNodeForRequest: function(request) {},
2034
2035 reset: function() {}
2036};