blob: f1e53b89eaab0172c4963a0f11b6945f577fe55c [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`,
Changhao Han9ec3f6e2019-11-12 18:43:25812 ls`${selectedTransferSize} B / ${transferSize} B transferred over network`);
Joey Arhara86c14e2019-03-12 03:20:50813 this._summaryToolbar.appendSeparator();
814 appendChunk(
815 ls`${Number.bytesToString(selectedResourceSize)} / ${Number.bytesToString(resourceSize)} resources`,
Changhao Han9ec3f6e2019-11-12 18:43:25816 ls`${selectedResourceSize} B / ${resourceSize} B resources loaded by the page`);
Blink Reformat4c46d092018-04-07 15:32:37817 } else {
Joey Arhara86c14e2019-03-12 03:20:50818 appendChunk(ls`${nodeCount} requests`);
819 this._summaryToolbar.appendSeparator();
Changhao Han9ec3f6e2019-11-12 18:43:25820 appendChunk(
821 ls`${Number.bytesToString(transferSize)} transferred`, ls`${transferSize} B transferred over network`);
Joey Arhara86c14e2019-03-12 03:20:50822 this._summaryToolbar.appendSeparator();
Changhao Han9ec3f6e2019-11-12 18:43:25823 appendChunk(
824 ls`${Number.bytesToString(resourceSize)} resources`, ls`${resourceSize} B resources loaded by the page`);
Blink Reformat4c46d092018-04-07 15:32:37825 }
Dan Beam87466b52018-12-01 18:41:20826
Blink Reformat4c46d092018-04-07 15:32:37827 if (baseTime !== -1 && maxTime !== -1) {
Joey Arhara86c14e2019-03-12 03:20:50828 this._summaryToolbar.appendSeparator();
829 appendChunk(ls`Finish: ${Number.secondsToString(maxTime - baseTime)}`);
Blink Reformat4c46d092018-04-07 15:32:37830 if (this._mainRequestDOMContentLoadedTime !== -1 && this._mainRequestDOMContentLoadedTime > baseTime) {
Joey Arhara86c14e2019-03-12 03:20:50831 this._summaryToolbar.appendSeparator();
Alexei Filippovfdcd8a62018-12-17 21:32:30832 const domContentLoadedText =
833 ls`DOMContentLoaded: ${Number.secondsToString(this._mainRequestDOMContentLoadedTime - baseTime)}`;
Joey Arhara86c14e2019-03-12 03:20:50834 appendChunk(domContentLoadedText).style.color = Network.NetworkLogView.getDCLEventColor();
Blink Reformat4c46d092018-04-07 15:32:37835 }
836 if (this._mainRequestLoadTime !== -1) {
Joey Arhara86c14e2019-03-12 03:20:50837 this._summaryToolbar.appendSeparator();
Alexei Filippovfdcd8a62018-12-17 21:32:30838 const loadText = ls`Load: ${Number.secondsToString(this._mainRequestLoadTime - baseTime)}`;
Joey Arhara86c14e2019-03-12 03:20:50839 appendChunk(loadText).style.color = Network.NetworkLogView.getLoadEventColor();
Blink Reformat4c46d092018-04-07 15:32:37840 }
841 }
Blink Reformat4c46d092018-04-07 15:32:37842 }
843
844 scheduleRefresh() {
Tim van der Lippe1d6e57a2019-09-30 11:55:34845 if (this._needsRefresh) {
Blink Reformat4c46d092018-04-07 15:32:37846 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34847 }
Blink Reformat4c46d092018-04-07 15:32:37848
849 this._needsRefresh = true;
850
Tim van der Lippe1d6e57a2019-09-30 11:55:34851 if (this.isShowing() && !this._refreshRequestId) {
Blink Reformat4c46d092018-04-07 15:32:37852 this._refreshRequestId = this.element.window().requestAnimationFrame(this._refresh.bind(this));
Tim van der Lippe1d6e57a2019-09-30 11:55:34853 }
Blink Reformat4c46d092018-04-07 15:32:37854 }
855
856 /**
857 * @param {!Array<number>} times
858 */
859 addFilmStripFrames(times) {
860 this._columns.addEventDividers(times, 'network-frame-divider');
861 }
862
863 /**
864 * @param {number} time
865 */
866 selectFilmStripFrame(time) {
867 this._columns.selectFilmStripFrame(time);
868 }
869
870 clearFilmStripFrame() {
871 this._columns.clearFilmStripFrame();
872 }
873
874 _refreshIfNeeded() {
Tim van der Lippe1d6e57a2019-09-30 11:55:34875 if (this._needsRefresh) {
Blink Reformat4c46d092018-04-07 15:32:37876 this._refresh();
Tim van der Lippe1d6e57a2019-09-30 11:55:34877 }
Blink Reformat4c46d092018-04-07 15:32:37878 }
879
880 /**
881 * @param {boolean=} deferUpdate
882 */
883 _invalidateAllItems(deferUpdate) {
Pavel Feldman18d13562018-07-31 03:31:18884 this._staleRequests = new Set(SDK.networkLog.requests());
Tim van der Lippe1d6e57a2019-09-30 11:55:34885 if (deferUpdate) {
Blink Reformat4c46d092018-04-07 15:32:37886 this.scheduleRefresh();
Tim van der Lippe1d6e57a2019-09-30 11:55:34887 } else {
Blink Reformat4c46d092018-04-07 15:32:37888 this._refresh();
Tim van der Lippe1d6e57a2019-09-30 11:55:34889 }
Blink Reformat4c46d092018-04-07 15:32:37890 }
891
892 /**
893 * @return {!Network.NetworkTimeCalculator}
894 */
895 timeCalculator() {
896 return this._timeCalculator;
897 }
898
899 /**
900 * @return {!Network.NetworkTimeCalculator}
901 */
902 calculator() {
903 return this._calculator;
904 }
905
906 /**
907 * @param {!Network.NetworkTimeCalculator} x
908 */
909 setCalculator(x) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34910 if (!x || this._calculator === x) {
Blink Reformat4c46d092018-04-07 15:32:37911 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34912 }
Blink Reformat4c46d092018-04-07 15:32:37913
914 if (this._calculator !== x) {
915 this._calculator = x;
916 this._columns.setCalculator(this._calculator);
917 }
918 this._calculator.reset();
919
Tim van der Lippe1d6e57a2019-09-30 11:55:34920 if (this._calculator.startAtZero) {
Blink Reformat4c46d092018-04-07 15:32:37921 this._columns.hideEventDividers();
Tim van der Lippe1d6e57a2019-09-30 11:55:34922 } else {
Blink Reformat4c46d092018-04-07 15:32:37923 this._columns.showEventDividers();
Tim van der Lippe1d6e57a2019-09-30 11:55:34924 }
Blink Reformat4c46d092018-04-07 15:32:37925
926 this._invalidateAllItems();
927 }
928
929 /**
930 * @param {!Common.Event} event
931 */
932 _loadEventFired(event) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34933 if (!this._recording) {
Blink Reformat4c46d092018-04-07 15:32:37934 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34935 }
Blink Reformat4c46d092018-04-07 15:32:37936
937 const time = /** @type {number} */ (event.data.loadTime);
938 if (time) {
939 this._mainRequestLoadTime = time;
Alexei Filippovfdcd8a62018-12-17 21:32:30940 this._columns.addEventDividers([time], 'network-load-divider');
Blink Reformat4c46d092018-04-07 15:32:37941 }
942 }
943
944 /**
945 * @param {!Common.Event} event
946 */
947 _domContentLoadedEventFired(event) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34948 if (!this._recording) {
Blink Reformat4c46d092018-04-07 15:32:37949 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34950 }
Blink Reformat4c46d092018-04-07 15:32:37951 const data = /** @type {number} */ (event.data);
952 if (data) {
953 this._mainRequestDOMContentLoadedTime = data;
Alexei Filippovfdcd8a62018-12-17 21:32:30954 this._columns.addEventDividers([data], 'network-dcl-divider');
Blink Reformat4c46d092018-04-07 15:32:37955 }
956 }
957
958 /**
959 * @override
960 */
961 wasShown() {
962 this._refreshIfNeeded();
963 this._columns.wasShown();
964 }
965
966 /**
967 * @override
968 */
969 willHide() {
970 this._columns.willHide();
971 }
972
973 /**
974 * @override
975 */
976 onResize() {
977 this._rowHeight = this._computeRowHeight();
978 }
979
980 /**
981 * @return {!Array<!Network.NetworkNode>}
982 */
983 flatNodesList() {
984 return this._dataGrid.rootNode().flatChildren();
985 }
986
Brandon Goddard88d885a2019-10-31 16:11:05987 updateNodeBackground() {
988 if (this._dataGrid.selectedNode) {
989 this._dataGrid.selectedNode.updateBackgroundColor();
990 }
991 }
992
993 /**
994 * @param {boolean} isSelected
995 */
996 updateNodeSelectedClass(isSelected) {
997 if (isSelected) {
998 this.element.classList.remove('no-node-selected');
999 } else {
1000 this.element.classList.add('no-node-selected');
1001 }
1002 }
1003
Blink Reformat4c46d092018-04-07 15:32:371004 stylesChanged() {
1005 this._columns.scheduleRefresh();
1006 }
1007
1008 _refresh() {
1009 this._needsRefresh = false;
1010
1011 if (this._refreshRequestId) {
1012 this.element.window().cancelAnimationFrame(this._refreshRequestId);
1013 this._refreshRequestId = null;
1014 }
1015
1016 this.removeAllNodeHighlights();
1017
1018 this._timeCalculator.updateBoundariesForEventTime(this._mainRequestLoadTime);
1019 this._durationCalculator.updateBoundariesForEventTime(this._mainRequestLoadTime);
1020 this._timeCalculator.updateBoundariesForEventTime(this._mainRequestDOMContentLoadedTime);
1021 this._durationCalculator.updateBoundariesForEventTime(this._mainRequestDOMContentLoadedTime);
1022
1023 /** @type {!Map<!Network.NetworkNode, !Network.NetworkNode>} */
1024 const nodesToInsert = new Map();
1025 /** @type {!Array<!Network.NetworkNode>} */
1026 const nodesToRefresh = [];
1027
1028 /** @type {!Set<!Network.NetworkRequestNode>} */
1029 const staleNodes = new Set();
1030
1031 // While creating nodes it may add more entries into _staleRequests because redirect request nodes update the parent
1032 // node so we loop until we have no more stale requests.
1033 while (this._staleRequests.size) {
1034 const request = this._staleRequests.firstValue();
1035 this._staleRequests.delete(request);
1036 let node = request[Network.NetworkLogView._networkNodeSymbol];
Tim van der Lippe1d6e57a2019-09-30 11:55:341037 if (!node) {
Blink Reformat4c46d092018-04-07 15:32:371038 node = this._createNodeForRequest(request);
Tim van der Lippe1d6e57a2019-09-30 11:55:341039 }
Blink Reformat4c46d092018-04-07 15:32:371040 staleNodes.add(node);
1041 }
1042
1043 for (const node of staleNodes) {
1044 const isFilteredOut = !this._applyFilter(node);
Tim van der Lippe1d6e57a2019-09-30 11:55:341045 if (isFilteredOut && node === this._hoveredNode) {
Blink Reformat4c46d092018-04-07 15:32:371046 this._setHoveredNode(null);
Tim van der Lippe1d6e57a2019-09-30 11:55:341047 }
Blink Reformat4c46d092018-04-07 15:32:371048
Tim van der Lippe1d6e57a2019-09-30 11:55:341049 if (!isFilteredOut) {
Blink Reformat4c46d092018-04-07 15:32:371050 nodesToRefresh.push(node);
Tim van der Lippe1d6e57a2019-09-30 11:55:341051 }
Blink Reformat4c46d092018-04-07 15:32:371052 const request = node.request();
1053 this._timeCalculator.updateBoundaries(request);
1054 this._durationCalculator.updateBoundaries(request);
1055 const newParent = this._parentNodeForInsert(node);
Tim van der Lippe1d6e57a2019-09-30 11:55:341056 if (node[Network.NetworkLogView._isFilteredOutSymbol] === isFilteredOut && node.parent === newParent) {
Blink Reformat4c46d092018-04-07 15:32:371057 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341058 }
Blink Reformat4c46d092018-04-07 15:32:371059 node[Network.NetworkLogView._isFilteredOutSymbol] = isFilteredOut;
1060 const removeFromParent = node.parent && (isFilteredOut || node.parent !== newParent);
1061 if (removeFromParent) {
1062 let parent = node.parent;
1063 parent.removeChild(node);
1064 while (parent && !parent.hasChildren() && parent.dataGrid && parent.dataGrid.rootNode() !== parent) {
1065 const grandparent = parent.parent;
1066 grandparent.removeChild(parent);
1067 parent = grandparent;
1068 }
1069 }
1070
Tim van der Lippe1d6e57a2019-09-30 11:55:341071 if (!newParent || isFilteredOut) {
Blink Reformat4c46d092018-04-07 15:32:371072 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341073 }
Blink Reformat4c46d092018-04-07 15:32:371074
1075 if (!newParent.dataGrid && !nodesToInsert.has(newParent)) {
1076 nodesToInsert.set(newParent, this._dataGrid.rootNode());
1077 nodesToRefresh.push(newParent);
1078 }
1079 nodesToInsert.set(node, newParent);
1080 }
1081
Tim van der Lippe1d6e57a2019-09-30 11:55:341082 for (const node of nodesToInsert.keys()) {
Blink Reformat4c46d092018-04-07 15:32:371083 nodesToInsert.get(node).appendChild(node);
Tim van der Lippe1d6e57a2019-09-30 11:55:341084 }
Blink Reformat4c46d092018-04-07 15:32:371085
Tim van der Lippe1d6e57a2019-09-30 11:55:341086 for (const node of nodesToRefresh) {
Blink Reformat4c46d092018-04-07 15:32:371087 node.refresh();
Tim van der Lippe1d6e57a2019-09-30 11:55:341088 }
Blink Reformat4c46d092018-04-07 15:32:371089
1090 this._updateSummaryBar();
1091
Tim van der Lippe1d6e57a2019-09-30 11:55:341092 if (nodesToInsert.size) {
Blink Reformat4c46d092018-04-07 15:32:371093 this._columns.sortByCurrentColumn();
Tim van der Lippe1d6e57a2019-09-30 11:55:341094 }
Blink Reformat4c46d092018-04-07 15:32:371095
1096 this._dataGrid.updateInstantly();
1097 this._didRefreshForTest();
1098 }
1099
1100 _didRefreshForTest() {
1101 }
1102
1103 /**
1104 * @param {!Network.NetworkRequestNode} node
1105 * @return {?Network.NetworkNode}
1106 */
1107 _parentNodeForInsert(node) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341108 if (!this._activeGroupLookup) {
Blink Reformat4c46d092018-04-07 15:32:371109 return this._dataGrid.rootNode();
Tim van der Lippe1d6e57a2019-09-30 11:55:341110 }
Blink Reformat4c46d092018-04-07 15:32:371111
1112 const groupNode = this._activeGroupLookup.groupNodeForRequest(node.request());
Tim van der Lippe1d6e57a2019-09-30 11:55:341113 if (!groupNode) {
Blink Reformat4c46d092018-04-07 15:32:371114 return this._dataGrid.rootNode();
Tim van der Lippe1d6e57a2019-09-30 11:55:341115 }
Blink Reformat4c46d092018-04-07 15:32:371116 return groupNode;
1117 }
1118
1119 _reset() {
Rob Paveza011e0232019-11-15 22:10:181120 this.dispatchEventToListeners(Network.NetworkLogView.Events.RequestActivated, /* showPanel */ false);
Blink Reformat4c46d092018-04-07 15:32:371121
1122 this._setHoveredNode(null);
1123 this._columns.reset();
1124
1125 this._timeFilter = null;
1126 this._calculator.reset();
1127
1128 this._timeCalculator.setWindow(null);
1129 this.linkifier.reset();
Blink Reformat4c46d092018-04-07 15:32:371130
Tim van der Lippe1d6e57a2019-09-30 11:55:341131 if (this._activeGroupLookup) {
Blink Reformat4c46d092018-04-07 15:32:371132 this._activeGroupLookup.reset();
Tim van der Lippe1d6e57a2019-09-30 11:55:341133 }
Blink Reformat4c46d092018-04-07 15:32:371134 this._staleRequests.clear();
1135 this._resetSuggestionBuilder();
1136
1137 this._mainRequestLoadTime = -1;
1138 this._mainRequestDOMContentLoadedTime = -1;
1139
1140 this._dataGrid.rootNode().removeChildren();
1141 this._updateSummaryBar();
1142 this._dataGrid.setStickToBottom(true);
1143 this.scheduleRefresh();
1144 }
1145
1146 /**
1147 * @param {string} filterString
1148 */
1149 setTextFilterValue(filterString) {
1150 this._textFilterUI.setValue(filterString);
1151 this._dataURLFilterUI.setChecked(false);
1152 this._resourceCategoryFilterUI.reset();
1153 }
1154
1155 /**
1156 * @param {!SDK.NetworkRequest} request
1157 */
1158 _createNodeForRequest(request) {
1159 const node = new Network.NetworkRequestNode(this, request);
1160 request[Network.NetworkLogView._networkNodeSymbol] = node;
1161 node[Network.NetworkLogView._isFilteredOutSymbol] = true;
1162
Tim van der Lippe1d6e57a2019-09-30 11:55:341163 for (let redirect = request.redirectSource(); redirect; redirect = redirect.redirectSource()) {
Blink Reformat4c46d092018-04-07 15:32:371164 this._refreshRequest(redirect);
Tim van der Lippe1d6e57a2019-09-30 11:55:341165 }
Blink Reformat4c46d092018-04-07 15:32:371166 return node;
1167 }
1168
1169 /**
1170 * @param {!Common.Event} event
1171 */
1172 _onRequestUpdated(event) {
1173 const request = /** @type {!SDK.NetworkRequest} */ (event.data);
1174 this._refreshRequest(request);
1175 }
1176
1177 /**
1178 * @param {!SDK.NetworkRequest} request
1179 */
1180 _refreshRequest(request) {
1181 Network.NetworkLogView._subdomains(request.domain)
1182 .forEach(
1183 this._suggestionBuilder.addItem.bind(this._suggestionBuilder, Network.NetworkLogView.FilterType.Domain));
1184 this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.Method, request.requestMethod);
1185 this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.MimeType, request.mimeType);
1186 this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.Scheme, '' + request.scheme);
1187 this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.StatusCode, '' + request.statusCode);
1188
1189 const priority = request.priority();
1190 if (priority) {
1191 this._suggestionBuilder.addItem(
1192 Network.NetworkLogView.FilterType.Priority, PerfUI.uiLabelForNetworkPriority(priority));
1193 }
1194
1195 if (request.mixedContentType !== Protocol.Security.MixedContentType.None) {
1196 this._suggestionBuilder.addItem(
1197 Network.NetworkLogView.FilterType.MixedContent, Network.NetworkLogView.MixedContentFilterValues.All);
1198 }
1199
1200 if (request.mixedContentType === Protocol.Security.MixedContentType.OptionallyBlockable) {
1201 this._suggestionBuilder.addItem(
1202 Network.NetworkLogView.FilterType.MixedContent, Network.NetworkLogView.MixedContentFilterValues.Displayed);
1203 }
1204
1205 if (request.mixedContentType === Protocol.Security.MixedContentType.Blockable) {
1206 const suggestion = request.wasBlocked() ? Network.NetworkLogView.MixedContentFilterValues.Blocked :
1207 Network.NetworkLogView.MixedContentFilterValues.BlockOverridden;
1208 this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.MixedContent, suggestion);
1209 }
1210
1211 const responseHeaders = request.responseHeaders;
Tim van der Lippe1d6e57a2019-09-30 11:55:341212 for (let i = 0, l = responseHeaders.length; i < l; ++i) {
Blink Reformat4c46d092018-04-07 15:32:371213 this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.HasResponseHeader, responseHeaders[i].name);
Tim van der Lippe1d6e57a2019-09-30 11:55:341214 }
Blink Reformat4c46d092018-04-07 15:32:371215 const cookies = request.responseCookies;
1216 for (let i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
1217 const cookie = cookies[i];
1218 this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.SetCookieDomain, cookie.domain());
1219 this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.SetCookieName, cookie.name());
1220 this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.SetCookieValue, cookie.value());
1221 }
1222
1223 this._staleRequests.add(request);
1224 this.scheduleRefresh();
1225 }
1226
1227 /**
1228 * @return {number}
1229 */
1230 rowHeight() {
1231 return this._rowHeight;
1232 }
1233
1234 /**
1235 * @param {boolean} gridMode
1236 */
1237 switchViewMode(gridMode) {
1238 this._columns.switchViewMode(gridMode);
1239 }
1240
1241 /**
1242 * @param {!UI.ContextMenu} contextMenu
1243 * @param {!SDK.NetworkRequest} request
1244 */
1245 handleContextMenuForRequest(contextMenu, request) {
1246 contextMenu.appendApplicableItems(request);
1247 let copyMenu = contextMenu.clipboardSection().appendSubMenuItem(Common.UIString('Copy'));
1248 const footerSection = copyMenu.footerSection();
1249 if (request) {
1250 copyMenu.defaultSection().appendItem(
Tim van der Lippe50cfa9b2019-10-01 10:40:581251 UI.copyLinkAddressLabel(),
1252 Host.InspectorFrontendHost.copyText.bind(Host.InspectorFrontendHost, request.contentURL()));
Blink Reformat4c46d092018-04-07 15:32:371253 if (request.requestHeadersText()) {
1254 copyMenu.defaultSection().appendItem(
1255 Common.UIString('Copy request headers'), Network.NetworkLogView._copyRequestHeaders.bind(null, request));
1256 }
1257
1258 if (request.responseHeadersText) {
1259 copyMenu.defaultSection().appendItem(
1260 Common.UIString('Copy response headers'), Network.NetworkLogView._copyResponseHeaders.bind(null, request));
1261 }
1262
1263 if (request.finished) {
1264 copyMenu.defaultSection().appendItem(
1265 Common.UIString('Copy response'), Network.NetworkLogView._copyResponse.bind(null, request));
1266 }
1267
Harley Libcf41f92018-09-10 18:01:131268 const disableIfBlob = request.isBlobRequest();
Blink Reformat4c46d092018-04-07 15:32:371269 if (Host.isWin()) {
1270 footerSection.appendItem(
Harley Libcf41f92018-09-10 18:01:131271 Common.UIString('Copy as PowerShell'), this._copyPowerShellCommand.bind(this, request), disableIfBlob);
Blink Reformat4c46d092018-04-07 15:32:371272 footerSection.appendItem(
Harley Libcf41f92018-09-10 18:01:131273 Common.UIString('Copy as fetch'), this._copyFetchCall.bind(this, request), disableIfBlob);
Blink Reformat4c46d092018-04-07 15:32:371274 footerSection.appendItem(
Harley Libcf41f92018-09-10 18:01:131275 Common.UIString('Copy as cURL (cmd)'), this._copyCurlCommand.bind(this, request, 'win'), disableIfBlob);
1276 footerSection.appendItem(
1277 Common.UIString('Copy as cURL (bash)'), this._copyCurlCommand.bind(this, request, 'unix'), disableIfBlob);
Blink Reformat4c46d092018-04-07 15:32:371278 footerSection.appendItem(Common.UIString('Copy all as PowerShell'), this._copyAllPowerShellCommand.bind(this));
1279 footerSection.appendItem(Common.UIString('Copy all as fetch'), this._copyAllFetchCall.bind(this));
1280 footerSection.appendItem(Common.UIString('Copy all as cURL (cmd)'), this._copyAllCurlCommand.bind(this, 'win'));
1281 footerSection.appendItem(
1282 Common.UIString('Copy all as cURL (bash)'), this._copyAllCurlCommand.bind(this, 'unix'));
1283 } else {
Harley Libcf41f92018-09-10 18:01:131284 footerSection.appendItem(
1285 Common.UIString('Copy as fetch'), this._copyFetchCall.bind(this, request), disableIfBlob);
1286 footerSection.appendItem(
1287 Common.UIString('Copy as cURL'), this._copyCurlCommand.bind(this, request, 'unix'), disableIfBlob);
Blink Reformat4c46d092018-04-07 15:32:371288 footerSection.appendItem(Common.UIString('Copy all as fetch'), this._copyAllFetchCall.bind(this));
1289 footerSection.appendItem(Common.UIString('Copy all as cURL'), this._copyAllCurlCommand.bind(this, 'unix'));
1290 }
1291 } else {
1292 copyMenu = contextMenu.clipboardSection().appendSubMenuItem(Common.UIString('Copy'));
1293 }
1294 footerSection.appendItem(Common.UIString('Copy all as HAR'), this._copyAll.bind(this));
1295
Joey Arhar0e1093c2019-05-21 00:34:221296 contextMenu.saveSection().appendItem(ls`Save all as HAR with content`, this.exportAll.bind(this));
Blink Reformat4c46d092018-04-07 15:32:371297
1298 contextMenu.editSection().appendItem(Common.UIString('Clear browser cache'), this._clearBrowserCache.bind(this));
1299 contextMenu.editSection().appendItem(
1300 Common.UIString('Clear browser cookies'), this._clearBrowserCookies.bind(this));
1301
1302 if (request) {
1303 const maxBlockedURLLength = 20;
1304 const manager = SDK.multitargetNetworkManager;
1305 let patterns = manager.blockedPatterns();
1306
Tim van der Lippeffa78622019-09-16 12:07:121307 /**
1308 * @param {string} url
1309 */
1310 function addBlockedURL(url) {
1311 patterns.push({enabled: true, url: url});
1312 manager.setBlockedPatterns(patterns);
1313 manager.setBlockingEnabled(true);
1314 UI.viewManager.showView('network.blocked-urls');
1315 }
1316
1317 /**
1318 * @param {string} url
1319 */
1320 function removeBlockedURL(url) {
1321 patterns = patterns.filter(pattern => pattern.url !== url);
1322 manager.setBlockedPatterns(patterns);
1323 UI.viewManager.showView('network.blocked-urls');
1324 }
1325
Blink Reformat4c46d092018-04-07 15:32:371326 const urlWithoutScheme = request.parsedURL.urlWithoutScheme();
1327 if (urlWithoutScheme && !patterns.find(pattern => pattern.url === urlWithoutScheme)) {
1328 contextMenu.debugSection().appendItem(
1329 Common.UIString('Block request URL'), addBlockedURL.bind(null, urlWithoutScheme));
1330 } else if (urlWithoutScheme) {
1331 const croppedURL = urlWithoutScheme.trimMiddle(maxBlockedURLLength);
1332 contextMenu.debugSection().appendItem(
1333 Common.UIString('Unblock %s', croppedURL), removeBlockedURL.bind(null, urlWithoutScheme));
1334 }
1335
1336 const domain = request.parsedURL.domain();
1337 if (domain && !patterns.find(pattern => pattern.url === domain)) {
1338 contextMenu.debugSection().appendItem(
1339 Common.UIString('Block request domain'), addBlockedURL.bind(null, domain));
1340 } else if (domain) {
1341 const croppedDomain = domain.trimMiddle(maxBlockedURLLength);
1342 contextMenu.debugSection().appendItem(
1343 Common.UIString('Unblock %s', croppedDomain), removeBlockedURL.bind(null, domain));
1344 }
1345
1346 if (SDK.NetworkManager.canReplayRequest(request)) {
1347 contextMenu.debugSection().appendItem(
1348 Common.UIString('Replay XHR'), SDK.NetworkManager.replayRequest.bind(null, request));
1349 }
Blink Reformat4c46d092018-04-07 15:32:371350 }
1351 }
1352
1353 _harRequests() {
Joey Arharb3d6de42019-04-23 21:26:171354 return SDK.networkLog.requests().filter(Network.NetworkLogView.HTTPRequestsFilter).filter(request => {
1355 return request.finished ||
1356 (request.resourceType() === Common.resourceTypes.WebSocket && request.responseReceivedTime);
1357 });
Blink Reformat4c46d092018-04-07 15:32:371358 }
1359
1360 async _copyAll() {
Pavel Feldman18d13562018-07-31 03:31:181361 const harArchive = {log: await SDK.HARLog.build(this._harRequests())};
Tim van der Lippe50cfa9b2019-10-01 10:40:581362 Host.InspectorFrontendHost.copyText(JSON.stringify(harArchive, null, 2));
Blink Reformat4c46d092018-04-07 15:32:371363 }
1364
1365 /**
1366 * @param {!SDK.NetworkRequest} request
1367 * @param {string} platform
1368 */
1369 async _copyCurlCommand(request, platform) {
1370 const command = await this._generateCurlCommand(request, platform);
Tim van der Lippe50cfa9b2019-10-01 10:40:581371 Host.InspectorFrontendHost.copyText(command);
Blink Reformat4c46d092018-04-07 15:32:371372 }
1373
1374 /**
1375 * @param {string} platform
1376 */
1377 async _copyAllCurlCommand(platform) {
Harley Libcf41f92018-09-10 18:01:131378 const commands = await this._generateAllCurlCommand(SDK.networkLog.requests(), platform);
Tim van der Lippe50cfa9b2019-10-01 10:40:581379 Host.InspectorFrontendHost.copyText(commands);
Blink Reformat4c46d092018-04-07 15:32:371380 }
1381
1382 /**
1383 * @param {!SDK.NetworkRequest} request
1384 * @param {string} platform
1385 */
1386 async _copyFetchCall(request, platform) {
1387 const command = await this._generateFetchCall(request);
Tim van der Lippe50cfa9b2019-10-01 10:40:581388 Host.InspectorFrontendHost.copyText(command);
Blink Reformat4c46d092018-04-07 15:32:371389 }
1390
1391 async _copyAllFetchCall() {
Harley Libcf41f92018-09-10 18:01:131392 const commands = await this._generateAllFetchCall(SDK.networkLog.requests());
Tim van der Lippe50cfa9b2019-10-01 10:40:581393 Host.InspectorFrontendHost.copyText(commands);
Blink Reformat4c46d092018-04-07 15:32:371394 }
1395
1396 /**
1397 * @param {!SDK.NetworkRequest} request
1398 */
1399 async _copyPowerShellCommand(request) {
1400 const command = await this._generatePowerShellCommand(request);
Tim van der Lippe50cfa9b2019-10-01 10:40:581401 Host.InspectorFrontendHost.copyText(command);
Blink Reformat4c46d092018-04-07 15:32:371402 }
1403
1404 async _copyAllPowerShellCommand() {
Harley Li5a470e92019-09-26 21:38:351405 const commands = await this._generateAllPowerShellCommand(SDK.networkLog.requests());
Tim van der Lippe50cfa9b2019-10-01 10:40:581406 Host.InspectorFrontendHost.copyText(commands);
Blink Reformat4c46d092018-04-07 15:32:371407 }
1408
Joey Arhar0e1093c2019-05-21 00:34:221409 async exportAll() {
Blink Reformat4c46d092018-04-07 15:32:371410 const url = SDK.targetManager.mainTarget().inspectedURL();
1411 const parsedURL = url.asParsedURL();
1412 const filename = parsedURL ? parsedURL.host : 'network-log';
1413 const stream = new Bindings.FileOutputStream();
1414
Tim van der Lippe1d6e57a2019-09-30 11:55:341415 if (!await stream.open(filename + '.har')) {
Blink Reformat4c46d092018-04-07 15:32:371416 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341417 }
Blink Reformat4c46d092018-04-07 15:32:371418
1419 const progressIndicator = new UI.ProgressIndicator();
1420 this._progressBarContainer.appendChild(progressIndicator.element);
1421 await Network.HARWriter.write(stream, this._harRequests(), progressIndicator);
1422 progressIndicator.done();
1423 stream.close();
1424 }
1425
1426 _clearBrowserCache() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341427 if (confirm(Common.UIString('Are you sure you want to clear browser cache?'))) {
Blink Reformat4c46d092018-04-07 15:32:371428 SDK.multitargetNetworkManager.clearBrowserCache();
Tim van der Lippe1d6e57a2019-09-30 11:55:341429 }
Blink Reformat4c46d092018-04-07 15:32:371430 }
1431
1432 _clearBrowserCookies() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341433 if (confirm(Common.UIString('Are you sure you want to clear browser cookies?'))) {
Blink Reformat4c46d092018-04-07 15:32:371434 SDK.multitargetNetworkManager.clearBrowserCookies();
Tim van der Lippe1d6e57a2019-09-30 11:55:341435 }
Blink Reformat4c46d092018-04-07 15:32:371436 }
1437
1438 _removeAllHighlights() {
1439 this.removeAllNodeHighlights();
Tim van der Lippe1d6e57a2019-09-30 11:55:341440 for (let i = 0; i < this._highlightedSubstringChanges.length; ++i) {
Blink Reformat4c46d092018-04-07 15:32:371441 UI.revertDomChanges(this._highlightedSubstringChanges[i]);
Tim van der Lippe1d6e57a2019-09-30 11:55:341442 }
Blink Reformat4c46d092018-04-07 15:32:371443 this._highlightedSubstringChanges = [];
1444 }
1445
1446 /**
1447 * @param {!Network.NetworkRequestNode} node
1448 * @return {boolean}
1449 */
1450 _applyFilter(node) {
1451 const request = node.request();
Tim van der Lippe1d6e57a2019-09-30 11:55:341452 if (this._timeFilter && !this._timeFilter(request)) {
Blink Reformat4c46d092018-04-07 15:32:371453 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:341454 }
Blink Reformat4c46d092018-04-07 15:32:371455 const categoryName = request.resourceType().category().title;
Tim van der Lippe1d6e57a2019-09-30 11:55:341456 if (!this._resourceCategoryFilterUI.accept(categoryName)) {
Blink Reformat4c46d092018-04-07 15:32:371457 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:341458 }
1459 if (this._dataURLFilterUI.checked() && (request.parsedURL.isDataURL() || request.parsedURL.isBlobURL())) {
Blink Reformat4c46d092018-04-07 15:32:371460 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:341461 }
1462 if (request.statusText === 'Service Worker Fallback Required') {
Blink Reformat4c46d092018-04-07 15:32:371463 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:341464 }
Blink Reformat4c46d092018-04-07 15:32:371465 for (let i = 0; i < this._filters.length; ++i) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341466 if (!this._filters[i](request)) {
Blink Reformat4c46d092018-04-07 15:32:371467 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:341468 }
Blink Reformat4c46d092018-04-07 15:32:371469 }
1470 return true;
1471 }
1472
1473 /**
1474 * @param {string} query
1475 */
1476 _parseFilterQuery(query) {
1477 const descriptors = this._filterParser.parse(query);
1478 this._filters = descriptors.map(descriptor => {
1479 const key = descriptor.key;
1480 const text = descriptor.text || '';
1481 const regex = descriptor.regex;
1482 let filter;
1483 if (key) {
1484 const defaultText = (key + ':' + text).escapeForRegExp();
1485 filter = this._createSpecialFilter(/** @type {!Network.NetworkLogView.FilterType} */ (key), text) ||
1486 Network.NetworkLogView._requestPathFilter.bind(null, new RegExp(defaultText, 'i'));
1487 } else if (descriptor.regex) {
1488 filter = Network.NetworkLogView._requestPathFilter.bind(null, /** @type {!RegExp} */ (regex));
1489 } else {
1490 filter = Network.NetworkLogView._requestPathFilter.bind(null, new RegExp(text.escapeForRegExp(), 'i'));
1491 }
1492 return descriptor.negative ? Network.NetworkLogView._negativeFilter.bind(null, filter) : filter;
1493 });
1494 }
1495
1496 /**
1497 * @param {!Network.NetworkLogView.FilterType} type
1498 * @param {string} value
1499 * @return {?Network.NetworkLogView.Filter}
1500 */
1501 _createSpecialFilter(type, value) {
1502 switch (type) {
1503 case Network.NetworkLogView.FilterType.Domain:
1504 return Network.NetworkLogView._createRequestDomainFilter(value);
1505
1506 case Network.NetworkLogView.FilterType.HasResponseHeader:
1507 return Network.NetworkLogView._requestResponseHeaderFilter.bind(null, value);
1508
1509 case Network.NetworkLogView.FilterType.Is:
Tim van der Lippe1d6e57a2019-09-30 11:55:341510 if (value.toLowerCase() === Network.NetworkLogView.IsFilterType.Running) {
Blink Reformat4c46d092018-04-07 15:32:371511 return Network.NetworkLogView._runningRequestFilter;
Tim van der Lippe1d6e57a2019-09-30 11:55:341512 }
1513 if (value.toLowerCase() === Network.NetworkLogView.IsFilterType.FromCache) {
Blink Reformat4c46d092018-04-07 15:32:371514 return Network.NetworkLogView._fromCacheRequestFilter;
Tim van der Lippe1d6e57a2019-09-30 11:55:341515 }
1516 if (value.toLowerCase() === Network.NetworkLogView.IsFilterType.ServiceWorkerIntercepted) {
Joey Arhard183e7e2019-02-28 03:37:051517 return Network.NetworkLogView._interceptedByServiceWorkerFilter;
Tim van der Lippe1d6e57a2019-09-30 11:55:341518 }
1519 if (value.toLowerCase() === Network.NetworkLogView.IsFilterType.ServiceWorkerInitiated) {
Joey Arhard183e7e2019-02-28 03:37:051520 return Network.NetworkLogView._initiatedByServiceWorkerFilter;
Tim van der Lippe1d6e57a2019-09-30 11:55:341521 }
Blink Reformat4c46d092018-04-07 15:32:371522 break;
1523
1524 case Network.NetworkLogView.FilterType.LargerThan:
1525 return this._createSizeFilter(value.toLowerCase());
1526
1527 case Network.NetworkLogView.FilterType.Method:
1528 return Network.NetworkLogView._requestMethodFilter.bind(null, value);
1529
1530 case Network.NetworkLogView.FilterType.MimeType:
1531 return Network.NetworkLogView._requestMimeTypeFilter.bind(null, value);
1532
1533 case Network.NetworkLogView.FilterType.MixedContent:
1534 return Network.NetworkLogView._requestMixedContentFilter.bind(
1535 null, /** @type {!Network.NetworkLogView.MixedContentFilterValues} */ (value));
1536
1537 case Network.NetworkLogView.FilterType.Scheme:
1538 return Network.NetworkLogView._requestSchemeFilter.bind(null, value);
1539
1540 case Network.NetworkLogView.FilterType.SetCookieDomain:
1541 return Network.NetworkLogView._requestSetCookieDomainFilter.bind(null, value);
1542
1543 case Network.NetworkLogView.FilterType.SetCookieName:
1544 return Network.NetworkLogView._requestSetCookieNameFilter.bind(null, value);
1545
1546 case Network.NetworkLogView.FilterType.SetCookieValue:
1547 return Network.NetworkLogView._requestSetCookieValueFilter.bind(null, value);
1548
1549 case Network.NetworkLogView.FilterType.Priority:
1550 return Network.NetworkLogView._requestPriorityFilter.bind(null, PerfUI.uiLabelToNetworkPriority(value));
1551
1552 case Network.NetworkLogView.FilterType.StatusCode:
1553 return Network.NetworkLogView._statusCodeFilter.bind(null, value);
1554 }
1555 return null;
1556 }
1557
1558 /**
1559 * @param {string} value
1560 * @return {?Network.NetworkLogView.Filter}
1561 */
1562 _createSizeFilter(value) {
1563 let multiplier = 1;
1564 if (value.endsWith('k')) {
1565 multiplier = 1024;
1566 value = value.substring(0, value.length - 1);
1567 } else if (value.endsWith('m')) {
1568 multiplier = 1024 * 1024;
1569 value = value.substring(0, value.length - 1);
1570 }
1571 const quantity = Number(value);
Tim van der Lippe1d6e57a2019-09-30 11:55:341572 if (isNaN(quantity)) {
Blink Reformat4c46d092018-04-07 15:32:371573 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341574 }
Blink Reformat4c46d092018-04-07 15:32:371575 return Network.NetworkLogView._requestSizeLargerThanFilter.bind(null, quantity * multiplier);
1576 }
1577
1578 _filterRequests() {
1579 this._removeAllHighlights();
1580 this._invalidateAllItems();
1581 }
1582
1583 /**
1584 * @param {!SDK.NetworkRequest} request
1585 * @return {?Network.NetworkRequestNode}
1586 */
1587 _reveal(request) {
1588 this.removeAllNodeHighlights();
1589 const node = request[Network.NetworkLogView._networkNodeSymbol];
Tim van der Lippe1d6e57a2019-09-30 11:55:341590 if (!node || !node.dataGrid) {
Blink Reformat4c46d092018-04-07 15:32:371591 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341592 }
Blink Reformat4c46d092018-04-07 15:32:371593 node.reveal();
1594 return node;
1595 }
1596
1597 /**
1598 * @param {!SDK.NetworkRequest} request
1599 */
1600 revealAndHighlightRequest(request) {
1601 const node = this._reveal(request);
Tim van der Lippe1d6e57a2019-09-30 11:55:341602 if (node) {
Blink Reformat4c46d092018-04-07 15:32:371603 this._highlightNode(node);
Tim van der Lippe1d6e57a2019-09-30 11:55:341604 }
Blink Reformat4c46d092018-04-07 15:32:371605 }
1606
1607 /**
1608 * @param {!SDK.NetworkRequest} request
1609 */
1610 selectRequest(request) {
Eugene Ostroukhovb600f662018-05-09 00:18:141611 this.setTextFilterValue('');
Blink Reformat4c46d092018-04-07 15:32:371612 const node = this._reveal(request);
Tim van der Lippe1d6e57a2019-09-30 11:55:341613 if (node) {
Blink Reformat4c46d092018-04-07 15:32:371614 node.select();
Tim van der Lippe1d6e57a2019-09-30 11:55:341615 }
Blink Reformat4c46d092018-04-07 15:32:371616 }
1617
1618 removeAllNodeHighlights() {
1619 if (this._highlightedNode) {
1620 this._highlightedNode.element().classList.remove('highlighted-row');
1621 this._highlightedNode = null;
1622 }
1623 }
1624
1625 /**
1626 * @param {!Network.NetworkRequestNode} node
1627 */
1628 _highlightNode(node) {
1629 UI.runCSSAnimationOnce(node.element(), 'highlighted-row');
1630 this._highlightedNode = node;
1631 }
1632
1633 /**
Harley Libcf41f92018-09-10 18:01:131634 * @param {!Array<!SDK.NetworkRequest>} requests
1635 * @return {!Array<!SDK.NetworkRequest>}
1636 */
1637 _filterOutBlobRequests(requests) {
1638 return requests.filter(request => !request.isBlobRequest());
1639 }
1640
1641 /**
Blink Reformat4c46d092018-04-07 15:32:371642 * @param {!SDK.NetworkRequest} request
1643 * @return {!Promise<string>}
1644 */
1645 async _generateFetchCall(request) {
1646 const ignoredHeaders = {
1647 // Internal headers
1648 'method': 1,
1649 'path': 1,
1650 'scheme': 1,
1651 'version': 1,
1652
1653 // Unsafe headers
1654 // Keep this list synchronized with src/net/http/http_util.cc
1655 'accept-charset': 1,
1656 'accept-encoding': 1,
1657 'access-control-request-headers': 1,
1658 'access-control-request-method': 1,
1659 'connection': 1,
1660 'content-length': 1,
1661 'cookie': 1,
1662 'cookie2': 1,
1663 'date': 1,
1664 'dnt': 1,
1665 'expect': 1,
1666 'host': 1,
1667 'keep-alive': 1,
1668 'origin': 1,
1669 'referer': 1,
1670 'te': 1,
1671 'trailer': 1,
1672 'transfer-encoding': 1,
1673 'upgrade': 1,
1674 'via': 1,
1675 // TODO(phistuck) - remove this once crbug.com/571722 is fixed.
1676 'user-agent': 1
1677 };
1678
1679 const credentialHeaders = {'cookie': 1, 'authorization': 1};
1680
1681 const url = JSON.stringify(request.url());
1682
1683 const requestHeaders = request.requestHeaders();
1684 const headerData = requestHeaders.reduce((result, header) => {
1685 const name = header.name;
1686
Tim van der Lippe1d6e57a2019-09-30 11:55:341687 if (!ignoredHeaders[name.toLowerCase()] && !name.includes(':')) {
Blink Reformat4c46d092018-04-07 15:32:371688 result.append(name, header.value);
Tim van der Lippe1d6e57a2019-09-30 11:55:341689 }
Blink Reformat4c46d092018-04-07 15:32:371690
1691 return result;
1692 }, new Headers());
1693
1694 const headers = {};
Tim van der Lippe1d6e57a2019-09-30 11:55:341695 for (const headerArray of headerData) {
PhistucK6ed0a3e2018-08-04 06:28:411696 headers[headerArray[0]] = headerArray[1];
Tim van der Lippe1d6e57a2019-09-30 11:55:341697 }
Blink Reformat4c46d092018-04-07 15:32:371698
1699 const credentials =
1700 request.requestCookies || requestHeaders.some(({name}) => credentialHeaders[name.toLowerCase()]) ? 'include' :
1701 'omit';
1702
1703 const referrerHeader = requestHeaders.find(({name}) => name.toLowerCase() === 'referer');
1704
1705 const referrer = referrerHeader ? referrerHeader.value : void 0;
1706
1707 const referrerPolicy = request.referrerPolicy() || void 0;
1708
1709 const requestBody = await request.requestFormData();
1710
1711 const fetchOptions = {
1712 credentials,
PhistucK6ed0a3e2018-08-04 06:28:411713 headers: Object.keys(headers).length ? headers : void 0,
Blink Reformat4c46d092018-04-07 15:32:371714 referrer,
1715 referrerPolicy,
1716 body: requestBody,
1717 method: request.requestMethod,
1718 mode: 'cors'
1719 };
1720
1721 const options = JSON.stringify(fetchOptions);
1722 return `fetch(${url}, ${options});`;
1723 }
1724
1725 /**
Harley Libcf41f92018-09-10 18:01:131726 * @param {!Array<!SDK.NetworkRequest>} requests
1727 * @return {!Promise<string>}
1728 */
1729 async _generateAllFetchCall(requests) {
1730 const nonBlobRequests = this._filterOutBlobRequests(requests);
1731 const commands = await Promise.all(nonBlobRequests.map(request => this._generateFetchCall(request)));
1732 return commands.join(' ;\n');
1733 }
1734
1735 /**
Blink Reformat4c46d092018-04-07 15:32:371736 * @param {!SDK.NetworkRequest} request
1737 * @param {string} platform
1738 * @return {!Promise<string>}
1739 */
1740 async _generateCurlCommand(request, platform) {
1741 let command = ['curl'];
Eric Lawrence7a7b3682019-10-17 23:06:361742 // Most of these headers are derived from the URL and are automatically added by cURL.
1743 // The |Accept-Encoding| header is ignored to prevent decompression errors. crbug.com/1015321
1744 const ignoredHeaders = {'accept-encoding': 1, 'host': 1, 'method': 1, 'path': 1, 'scheme': 1, 'version': 1};
Blink Reformat4c46d092018-04-07 15:32:371745
1746 function escapeStringWin(str) {
1747 /* If there are no new line characters do not escape the " characters
1748 since it only uglifies the command.
1749
1750 Because cmd.exe parser and MS Crt arguments parsers use some of the
1751 same escape characters, they can interact with each other in
1752 horrible ways, the order of operations is critical.
1753
1754 Replace \ with \\ first because it is an escape character for certain
1755 conditions in both parsers.
1756
1757 Replace all " with \" to ensure the first parser does not remove it.
1758
1759 Then escape all characters we are not sure about with ^ to ensure it
1760 gets to MS Crt parser safely.
1761
1762 The % character is special because MS Crt parser will try and look for
1763 ENV variables and fill them in it's place. We cannot escape them with %
1764 and cannot escape them with ^ (because it's cmd.exe's escape not MS Crt
1765 parser); So we can get cmd.exe parser to escape the character after it,
1766 if it is followed by a valid beginning character of an ENV variable.
1767 This ensures we do not try and double escape another ^ if it was placed
1768 by the previous replace.
1769
1770 Lastly we replace new lines with ^ and TWO new lines because the first
1771 new line is there to enact the escape command the second is the character
1772 to escape (in this case new line).
1773 */
1774 const encapsChars = /[\r\n]/.test(str) ? '^"' : '"';
1775 return encapsChars +
1776 str.replace(/\\/g, '\\\\')
1777 .replace(/"/g, '\\"')
1778 .replace(/[^a-zA-Z0-9\s_\-:=+~'\/.',?;()*`]/g, '^$&')
1779 .replace(/%(?=[a-zA-Z0-9_])/g, '%^')
1780 .replace(/\r\n|[\n\r]/g, '^\n\n') +
1781 encapsChars;
1782 }
1783
1784 /**
1785 * @param {string} str
1786 * @return {string}
1787 */
1788 function escapeStringPosix(str) {
1789 /**
1790 * @param {string} x
1791 * @return {string}
1792 */
1793 function escapeCharacter(x) {
Erik Luoaa676752018-08-21 05:52:221794 const code = x.charCodeAt(0);
Joey Arhar2d21f712019-05-20 21:07:121795 let hexString = code.toString(16);
1796 // Zero pad to four digits to comply with ANSI-C Quoting:
1797 // http://www.gnu.org/software/bash/manual/html_node/ANSI_002dC-Quoting.html
Tim van der Lippe1d6e57a2019-09-30 11:55:341798 while (hexString.length < 4) {
Joey Arhar2d21f712019-05-20 21:07:121799 hexString = '0' + hexString;
Tim van der Lippe1d6e57a2019-09-30 11:55:341800 }
Joey Arhar2d21f712019-05-20 21:07:121801
1802 return '\\u' + hexString;
Blink Reformat4c46d092018-04-07 15:32:371803 }
1804
Joey Arhar512e3742019-01-25 21:33:541805 if (/[\u0000-\u001f\u007f-\u009f!]|\'/.test(str)) {
Blink Reformat4c46d092018-04-07 15:32:371806 // Use ANSI-C quoting syntax.
1807 return '$\'' +
1808 str.replace(/\\/g, '\\\\')
1809 .replace(/\'/g, '\\\'')
1810 .replace(/\n/g, '\\n')
1811 .replace(/\r/g, '\\r')
Joey Arhar512e3742019-01-25 21:33:541812 .replace(/[\u0000-\u001f\u007f-\u009f!]/g, escapeCharacter) +
Blink Reformat4c46d092018-04-07 15:32:371813 '\'';
1814 } else {
1815 // Use single quote syntax.
1816 return '\'' + str + '\'';
1817 }
1818 }
1819
1820 // cURL command expected to run on the same platform that DevTools run
1821 // (it may be different from the inspected page platform).
1822 const escapeString = platform === 'win' ? escapeStringWin : escapeStringPosix;
1823
1824 command.push(escapeString(request.url()).replace(/[[{}\]]/g, '\\$&'));
1825
1826 let inferredMethod = 'GET';
1827 const data = [];
1828 const requestContentType = request.requestContentType();
1829 const formData = await request.requestFormData();
1830 if (requestContentType && requestContentType.startsWith('application/x-www-form-urlencoded') && formData) {
1831 data.push('--data');
1832 data.push(escapeString(formData));
1833 ignoredHeaders['content-length'] = true;
1834 inferredMethod = 'POST';
1835 } else if (formData) {
1836 data.push('--data-binary');
1837 data.push(escapeString(formData));
1838 ignoredHeaders['content-length'] = true;
1839 inferredMethod = 'POST';
1840 }
1841
1842 if (request.requestMethod !== inferredMethod) {
1843 command.push('-X');
1844 command.push(request.requestMethod);
1845 }
1846
1847 const requestHeaders = request.requestHeaders();
1848 for (let i = 0; i < requestHeaders.length; i++) {
1849 const header = requestHeaders[i];
1850 const name = header.name.replace(/^:/, ''); // Translate SPDY v3 headers to HTTP headers.
Tim van der Lippe1d6e57a2019-09-30 11:55:341851 if (name.toLowerCase() in ignoredHeaders) {
Blink Reformat4c46d092018-04-07 15:32:371852 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341853 }
Blink Reformat4c46d092018-04-07 15:32:371854 command.push('-H');
1855 command.push(escapeString(name + ': ' + header.value));
1856 }
1857 command = command.concat(data);
1858 command.push('--compressed');
1859
Tim van der Lippe1d6e57a2019-09-30 11:55:341860 if (request.securityState() === Protocol.Security.SecurityState.Insecure) {
Blink Reformat4c46d092018-04-07 15:32:371861 command.push('--insecure');
Tim van der Lippe1d6e57a2019-09-30 11:55:341862 }
Blink Reformat4c46d092018-04-07 15:32:371863 return command.join(' ');
1864 }
1865
1866 /**
Harley Libcf41f92018-09-10 18:01:131867 * @param {!Array<!SDK.NetworkRequest>} requests
1868 * @param {string} platform
1869 * @return {!Promise<string>}
1870 */
1871 async _generateAllCurlCommand(requests, platform) {
1872 const nonBlobRequests = this._filterOutBlobRequests(requests);
1873 const commands = await Promise.all(nonBlobRequests.map(request => this._generateCurlCommand(request, platform)));
Tim van der Lippe1d6e57a2019-09-30 11:55:341874 if (platform === 'win') {
Harley Libcf41f92018-09-10 18:01:131875 return commands.join(' &\r\n');
Tim van der Lippe1d6e57a2019-09-30 11:55:341876 } else {
Harley Libcf41f92018-09-10 18:01:131877 return commands.join(' ;\n');
Tim van der Lippe1d6e57a2019-09-30 11:55:341878 }
Harley Libcf41f92018-09-10 18:01:131879 }
1880
1881 /**
Blink Reformat4c46d092018-04-07 15:32:371882 * @param {!SDK.NetworkRequest} request
1883 * @return {!Promise<string>}
1884 */
1885 async _generatePowerShellCommand(request) {
1886 const command = ['Invoke-WebRequest'];
1887 const ignoredHeaders =
1888 new Set(['host', 'connection', 'proxy-connection', 'content-length', 'expect', 'range', 'content-type']);
1889
1890 /**
1891 * @param {string} str
1892 * @return {string}
1893 */
1894 function escapeString(str) {
1895 return '"' +
1896 str.replace(/[`\$"]/g, '`$&').replace(/[^\x20-\x7E]/g, char => '$([char]' + char.charCodeAt(0) + ')') + '"';
1897 }
1898
1899 command.push('-Uri');
1900 command.push(escapeString(request.url()));
1901
1902 if (request.requestMethod !== 'GET') {
1903 command.push('-Method');
1904 command.push(escapeString(request.requestMethod));
1905 }
1906
1907 const requestHeaders = request.requestHeaders();
1908 const headerNameValuePairs = [];
1909 for (const header of requestHeaders) {
1910 const name = header.name.replace(/^:/, ''); // Translate h2 headers to HTTP headers.
Tim van der Lippe1d6e57a2019-09-30 11:55:341911 if (ignoredHeaders.has(name.toLowerCase())) {
Blink Reformat4c46d092018-04-07 15:32:371912 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341913 }
Blink Reformat4c46d092018-04-07 15:32:371914 headerNameValuePairs.push(escapeString(name) + '=' + escapeString(header.value));
1915 }
1916 if (headerNameValuePairs.length) {
1917 command.push('-Headers');
1918 command.push('@{' + headerNameValuePairs.join('; ') + '}');
1919 }
1920
1921 const contentTypeHeader = requestHeaders.find(({name}) => name.toLowerCase() === 'content-type');
1922 if (contentTypeHeader) {
1923 command.push('-ContentType');
1924 command.push(escapeString(contentTypeHeader.value));
1925 }
1926
1927 const formData = await request.requestFormData();
1928 if (formData) {
1929 command.push('-Body');
1930 const body = escapeString(formData);
Tim van der Lippe1d6e57a2019-09-30 11:55:341931 if (/[^\x20-\x7E]/.test(formData)) {
Blink Reformat4c46d092018-04-07 15:32:371932 command.push('([System.Text.Encoding]::UTF8.GetBytes(' + body + '))');
Tim van der Lippe1d6e57a2019-09-30 11:55:341933 } else {
Blink Reformat4c46d092018-04-07 15:32:371934 command.push(body);
Tim van der Lippe1d6e57a2019-09-30 11:55:341935 }
Blink Reformat4c46d092018-04-07 15:32:371936 }
1937
1938 return command.join(' ');
1939 }
Harley Libcf41f92018-09-10 18:01:131940
1941 /**
1942 * @param {!Array<!SDK.NetworkRequest>} requests
1943 * @return {!Promise<string>}
1944 */
1945 async _generateAllPowerShellCommand(requests) {
1946 const nonBlobRequests = this._filterOutBlobRequests(requests);
1947 const commands = await Promise.all(nonBlobRequests.map(request => this._generatePowerShellCommand(request)));
1948 return commands.join(';\r\n');
1949 }
Joey Arhara86c14e2019-03-12 03:20:501950
1951 /**
1952 * @return {string}
1953 */
1954 static getDCLEventColor() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341955 if (UI.themeSupport.themeName() === 'dark') {
Joey Arhara86c14e2019-03-12 03:20:501956 return '#03A9F4';
Tim van der Lippe1d6e57a2019-09-30 11:55:341957 }
Joey Arhara86c14e2019-03-12 03:20:501958 return '#0867CB';
1959 }
1960
1961 /**
1962 * @return {string}
1963 */
1964 static getLoadEventColor() {
1965 return UI.themeSupport.patchColorText('#B31412', UI.ThemeSupport.ColorUsage.Foreground);
1966 }
Blink Reformat4c46d092018-04-07 15:32:371967};
1968
1969Network.NetworkLogView._isFilteredOutSymbol = Symbol('isFilteredOut');
1970Network.NetworkLogView._networkNodeSymbol = Symbol('NetworkNode');
1971
1972Network.NetworkLogView.HTTPSchemas = {
1973 'http': true,
1974 'https': true,
1975 'ws': true,
1976 'wss': true
1977};
1978
1979/** @enum {symbol} */
1980Network.NetworkLogView.Events = {
Brandon Goddard88d885a2019-10-31 16:11:051981 RequestSelected: Symbol('RequestSelected'),
1982 RequestActivated: Symbol('RequestActivated')
Blink Reformat4c46d092018-04-07 15:32:371983};
1984
1985/** @enum {string} */
1986Network.NetworkLogView.FilterType = {
1987 Domain: 'domain',
1988 HasResponseHeader: 'has-response-header',
1989 Is: 'is',
1990 LargerThan: 'larger-than',
1991 Method: 'method',
1992 MimeType: 'mime-type',
1993 MixedContent: 'mixed-content',
1994 Priority: 'priority',
1995 Scheme: 'scheme',
1996 SetCookieDomain: 'set-cookie-domain',
1997 SetCookieName: 'set-cookie-name',
1998 SetCookieValue: 'set-cookie-value',
1999 StatusCode: 'status-code'
2000};
2001
2002/** @enum {string} */
2003Network.NetworkLogView.MixedContentFilterValues = {
2004 All: 'all',
2005 Displayed: 'displayed',
2006 Blocked: 'blocked',
2007 BlockOverridden: 'block-overridden'
2008};
2009
2010/** @enum {string} */
2011Network.NetworkLogView.IsFilterType = {
2012 Running: 'running',
Joey Arhard183e7e2019-02-28 03:37:052013 FromCache: 'from-cache',
2014 ServiceWorkerIntercepted: 'service-worker-intercepted',
2015 ServiceWorkerInitiated: 'service-worker-initiated'
Blink Reformat4c46d092018-04-07 15:32:372016};
2017
2018/** @type {!Array<string>} */
2019Network.NetworkLogView._searchKeys =
2020 Object.keys(Network.NetworkLogView.FilterType).map(key => Network.NetworkLogView.FilterType[key]);
2021
2022/** @typedef {function(!SDK.NetworkRequest): boolean} */
2023Network.NetworkLogView.Filter;
2024
2025/**
2026 * @interface
2027 */
2028Network.GroupLookupInterface = function() {};
2029
2030Network.GroupLookupInterface.prototype = {
2031 /**
2032 * @param {!SDK.NetworkRequest} request
2033 * @return {?Network.NetworkGroupNode}
2034 */
2035 groupNodeForRequest: function(request) {},
2036
2037 reset: function() {}
2038};