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

Side by Side Diff: Source/devtools/front_end/network/NetworkPanel.js

Issue 730463002: Revert of DevTools: Split NetworkPanel.js (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org> 3 * Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org>
4 * Copyright (C) 2010, 2011, 2012, 2013, 2014 Google Inc. All rights reserved. 4 * Copyright (C) 2011 Google Inc. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 9 *
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 15 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
16 * its contributors may be used to endorse or promote products derived 16 * its contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission. 17 * from this software without specific prior written permission.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 /** 31 /**
32 * @constructor 32 * @constructor
33 * @implements {WebInspector.Searchable}
34 * @implements {WebInspector.TargetManager.Observer}
35 * @extends {WebInspector.VBox}
36 * @param {!WebInspector.FilterBar} filterBar
37 * @param {!WebInspector.Setting} coulmnsVisibilitySetting
38 */
39 WebInspector.NetworkLogView = function(filterBar, coulmnsVisibilitySetting)
40 {
41 WebInspector.VBox.call(this);
42 this.registerRequiredCSS("network/networkLogView.css");
43 this.registerRequiredCSS("ui/filter.css");
44
45 this._filterBar = filterBar;
46 this._coulmnsVisibilitySetting = coulmnsVisibilitySetting;
47 this._allowRequestSelection = false;
48 /** @type {!Map.<string, !WebInspector.NetworkDataGridNode>} */
49 this._nodesByRequestId = new Map();
50 /** @type {!Object.<string, boolean>} */
51 this._staleRequestIds = {};
52 /** @type {number} */
53 this._mainRequestLoadTime = -1;
54 /** @type {number} */
55 this._mainRequestDOMContentLoadedTime = -1;
56 this._matchedRequestCount = 0;
57 this._highlightedSubstringChanges = [];
58
59 /** @type {!Array.<!WebInspector.NetworkLogView.Filter>} */
60 this._filters = [];
61
62 this._currentMatchedRequestNode = null;
63 this._currentMatchedRequestIndex = -1;
64
65 this._createStatusbarButtons();
66 this._createStatusBarItems();
67 this._linkifier = new WebInspector.Linkifier();
68
69 this._allowPopover = true;
70
71 /** @type {number} */
72 this._rowHeight = 0;
73
74 this._addFilters();
75 this._resetSuggestionBuilder();
76 this._initializeView();
77 this._toggleRecordButton(true);
78
79 WebInspector.targetManager.observeTargets(this);
80 WebInspector.targetManager.addModelListener(WebInspector.NetworkManager, Web Inspector.NetworkManager.EventTypes.RequestStarted, this._onRequestStarted, this );
81 WebInspector.targetManager.addModelListener(WebInspector.NetworkManager, Web Inspector.NetworkManager.EventTypes.RequestUpdated, this._onRequestUpdated, this );
82 WebInspector.targetManager.addModelListener(WebInspector.NetworkManager, Web Inspector.NetworkManager.EventTypes.RequestFinished, this._onRequestUpdated, thi s);
83
84 WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.WillReloadPage, this._willReloadPage, this);
85 WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNav igated, this);
86 WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.Load, this._loadEventFired, this);
87 WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded, this._domContentLoad edEventFired, this);
88 }
89
90 WebInspector.NetworkLogView.HTTPSchemas = {"http": true, "https": true, "ws": tr ue, "wss": true};
91 WebInspector.NetworkLogView._responseHeaderColumns = ["Cache-Control", "Connecti on", "Content-Encoding", "Content-Length", "ETag", "Keep-Alive", "Last-Modified" , "Server", "Vary"];
92 WebInspector.NetworkLogView.defaultColumnsVisibility = {
93 method: true, status: true, scheme: false, domain: false, remoteAddress: fal se, type: true, initiator: true, cookies: false, setCookies: false, size: true, time: true, connectionId: false,
94 "Cache-Control": false, "Connection": false, "Content-Encoding": false, "Con tent-Length": false, "ETag": false, "Keep-Alive": false, "Last-Modified": false, "Server": false, "Vary": false
95 };
96 WebInspector.NetworkLogView._defaultRefreshDelay = 500;
97
98 /** @enum {string} */
99 WebInspector.NetworkLogView.FilterType = {
100 Domain: "Domain",
101 HasResponseHeader: "HasResponseHeader",
102 Is: "Is",
103 Method: "Method",
104 MimeType: "MimeType",
105 Scheme: "Scheme",
106 SetCookieDomain: "SetCookieDomain",
107 SetCookieName: "SetCookieName",
108 SetCookieValue: "SetCookieValue",
109 StatusCode: "StatusCode"
110 };
111
112 /** @enum {string} */
113 WebInspector.NetworkLogView.IsFilterType = {
114 Running: "running"
115 };
116
117 /** @type {!Array.<string>} */
118 WebInspector.NetworkLogView._searchKeys = Object.values(WebInspector.NetworkLogV iew.FilterType);
119
120 /** @type {!Object.<string, string>} */
121 WebInspector.NetworkLogView._columnTitles = {
122 "name": WebInspector.UIString("Name"),
123 "method": WebInspector.UIString("Method"),
124 "status": WebInspector.UIString("Status"),
125 "scheme": WebInspector.UIString("Scheme"),
126 "domain": WebInspector.UIString("Domain"),
127 "remoteAddress": WebInspector.UIString("Remote Address"),
128 "type": WebInspector.UIString("Type"),
129 "initiator": WebInspector.UIString("Initiator"),
130 "cookies": WebInspector.UIString("Cookies"),
131 "setCookies": WebInspector.UIString("Set-Cookies"),
132 "size": WebInspector.UIString("Size"),
133 "time": WebInspector.UIString("Time"),
134 "connectionId": WebInspector.UIString("Connection Id"),
135 "timeline": WebInspector.UIString("Timeline"),
136
137 // Response header columns
138 "Cache-Control": WebInspector.UIString("Cache-Control"),
139 "Connection": WebInspector.UIString("Connection"),
140 "Content-Encoding": WebInspector.UIString("Content-Encoding"),
141 "Content-Length": WebInspector.UIString("Content-Length"),
142 "ETag": WebInspector.UIString("ETag"),
143 "Keep-Alive": WebInspector.UIString("Keep-Alive"),
144 "Last-Modified": WebInspector.UIString("Last-Modified"),
145 "Server": WebInspector.UIString("Server"),
146 "Vary": WebInspector.UIString("Vary")
147 };
148
149 WebInspector.NetworkLogView.prototype = {
150 /**
151 * @param {!WebInspector.Target} target
152 */
153 targetAdded: function(target)
154 {
155 target.networkLog.requests.forEach(this._appendRequest.bind(this));
156 },
157
158 /**
159 * @param {!WebInspector.Target} target
160 */
161 targetRemoved: function(target)
162 {
163 },
164
165 /**
166 * @return {boolean}
167 */
168 allowRequestSelection: function()
169 {
170 return this._allowRequestSelection;
171 },
172
173 _addFilters: function()
174 {
175 this._textFilterUI = new WebInspector.TextFilterUI();
176 this._textFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterC hanged, this._filterChanged, this);
177 this._filterBar.addFilter(this._textFilterUI);
178
179 var types = [];
180 for (var typeId in WebInspector.resourceTypes) {
181 var resourceType = WebInspector.resourceTypes[typeId];
182 if (resourceType === WebInspector.resourceTypes.TextTrack)
183 continue;
184 types.push({name: resourceType.name(), label: resourceType.categoryT itle()});
185 }
186 this._resourceTypeFilterUI = new WebInspector.NamedBitSetFilterUI(types, WebInspector.settings.networkResourceTypeFilters);
187 this._resourceTypeFilterUI.addEventListener(WebInspector.FilterUI.Events .FilterChanged, this._filterChanged.bind(this), this);
188 this._filterBar.addFilter(this._resourceTypeFilterUI);
189
190 var dataURLSetting = WebInspector.settings.networkHideDataURL;
191 this._dataURLFilterUI = new WebInspector.CheckboxFilterUI("hide-data-url ", WebInspector.UIString("Hide data URLs"), true, dataURLSetting);
192 this._dataURLFilterUI.addEventListener(WebInspector.FilterUI.Events.Filt erChanged, this._filterChanged.bind(this), this);
193 this._filterBar.addFilter(this._dataURLFilterUI);
194 },
195
196 _resetSuggestionBuilder: function()
197 {
198 this._suggestionBuilder = new WebInspector.FilterSuggestionBuilder(WebIn spector.NetworkLogView._searchKeys);
199 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.I s, WebInspector.NetworkLogView.IsFilterType.Running);
200 this._textFilterUI.setSuggestionBuilder(this._suggestionBuilder);
201 },
202
203 /**
204 * @param {!WebInspector.Event} event
205 */
206 _filterChanged: function(event)
207 {
208 this._removeAllNodeHighlights();
209 this._parseFilterQuery(this._textFilterUI.value());
210 this._filterRequests();
211 },
212
213 _initializeView: function()
214 {
215 this.element.id = "network-container";
216
217 this._createSortingFunctions();
218 this._createCalculators();
219 this._createTable();
220 this._createTimelineGrid();
221 this._summaryBarElement = this.element.createChild("div", "network-summa ry-bar");
222
223 this._updateRowsSize();
224
225 this._popoverHelper = new WebInspector.PopoverHelper(this.element, this. _getPopoverAnchor.bind(this), this._showPopover.bind(this), this._onHidePopover. bind(this));
226 // Enable faster hint.
227 this._popoverHelper.setTimeout(250, 250);
228
229 this.switchViewMode(true);
230 },
231
232 /**
233 * @return {!Array.<!Element>}
234 */
235 statusBarItems: function()
236 {
237 return [
238 this._recordButton.element,
239 this._clearButton.element,
240 this._filterBar.filterButton().element,
241 this._largerRequestsButton.element,
242 this._preserveLogCheckbox.element,
243 this._disableCacheCheckbox.element,
244 this._progressBarContainer];
245 },
246
247 /**
248 * @return {boolean}
249 */
250 usesLargeRows: function()
251 {
252 return !!WebInspector.settings.resourcesLargeRows.get();
253 },
254
255 /**
256 * @param {boolean} flag
257 */
258 setAllowPopover: function(flag)
259 {
260 this._allowPopover = flag;
261 },
262
263 /**
264 * @return {!Array.<!Element>}
265 */
266 elementsToRestoreScrollPositionsFor: function()
267 {
268 if (!this._dataGrid) // Not initialized yet.
269 return [];
270 return [this._dataGrid.scrollContainer];
271 },
272
273 _createTimelineGrid: function()
274 {
275 this._timelineGrid = new WebInspector.TimelineGrid();
276 this._timelineGrid.element.classList.add("network-timeline-grid");
277 this._dataGrid.element.appendChild(this._timelineGrid.element);
278 },
279
280 _createTable: function()
281 {
282 var columns = [];
283 columns.push({
284 id: "name",
285 titleDOMFragment: this._makeHeaderFragment(WebInspector.UIString("Na me"), WebInspector.UIString("Path")),
286 title: WebInspector.NetworkLogView._columnTitles["name"],
287 sortable: true,
288 weight: 20,
289 disclosure: true
290 });
291
292 columns.push({
293 id: "method",
294 title: WebInspector.NetworkLogView._columnTitles["method"],
295 sortable: true,
296 weight: 6
297 });
298
299 columns.push({
300 id: "status",
301 titleDOMFragment: this._makeHeaderFragment(WebInspector.UIString("St atus"), WebInspector.UIString("Text")),
302 title: WebInspector.NetworkLogView._columnTitles["status"],
303 sortable: true,
304 weight: 6
305 });
306
307 columns.push({
308 id: "scheme",
309 title: WebInspector.NetworkLogView._columnTitles["scheme"],
310 sortable: true,
311 weight: 6
312 });
313
314 columns.push({
315 id: "domain",
316 title: WebInspector.NetworkLogView._columnTitles["domain"],
317 sortable: true,
318 weight: 6
319 });
320
321 columns.push({
322 id: "remoteAddress",
323 title: WebInspector.NetworkLogView._columnTitles["remoteAddress"],
324 sortable: true,
325 weight: 10,
326 align: WebInspector.DataGrid.Align.Right
327 });
328
329 columns.push({
330 id: "type",
331 title: WebInspector.NetworkLogView._columnTitles["type"],
332 sortable: true,
333 weight: 6
334 });
335
336 columns.push({
337 id: "initiator",
338 title: WebInspector.NetworkLogView._columnTitles["initiator"],
339 sortable: true,
340 weight: 10
341 });
342
343 columns.push({
344 id: "cookies",
345 title: WebInspector.NetworkLogView._columnTitles["cookies"],
346 sortable: true,
347 weight: 6,
348 align: WebInspector.DataGrid.Align.Right
349 });
350
351 columns.push({
352 id: "setCookies",
353 title: WebInspector.NetworkLogView._columnTitles["setCookies"],
354 sortable: true,
355 weight: 6,
356 align: WebInspector.DataGrid.Align.Right
357 });
358
359 columns.push({
360 id: "size",
361 titleDOMFragment: this._makeHeaderFragment(WebInspector.UIString("Si ze"), WebInspector.UIString("Content")),
362 title: WebInspector.NetworkLogView._columnTitles["size"],
363 sortable: true,
364 weight: 6,
365 align: WebInspector.DataGrid.Align.Right
366 });
367
368 columns.push({
369 id: "time",
370 titleDOMFragment: this._makeHeaderFragment(WebInspector.UIString("Ti me"), WebInspector.UIString("Latency")),
371 title: WebInspector.NetworkLogView._columnTitles["time"],
372 sortable: true,
373 weight: 6,
374 align: WebInspector.DataGrid.Align.Right
375 });
376
377 columns.push({
378 id: "connectionId",
379 title: WebInspector.NetworkLogView._columnTitles["connectionId"],
380 sortable: true,
381 weight: 6
382 });
383
384 var responseHeaderColumns = WebInspector.NetworkLogView._responseHeaderC olumns;
385 for (var i = 0; i < responseHeaderColumns.length; ++i) {
386 var headerName = responseHeaderColumns[i];
387 var descriptor = {
388 id: headerName,
389 title: WebInspector.NetworkLogView._columnTitles[headerName],
390 weight: 6
391 }
392 if (headerName === "Content-Length")
393 descriptor.align = WebInspector.DataGrid.Align.Right;
394 columns.push(descriptor);
395 }
396
397 columns.push({
398 id: "timeline",
399 titleDOMFragment: createDocumentFragment(),
400 title: WebInspector.NetworkLogView._columnTitles["timeline"],
401 sortable: false,
402 weight: 40,
403 sort: WebInspector.DataGrid.Order.Ascending
404 });
405
406 this._dataGrid = new WebInspector.SortableDataGrid(columns);
407 this._dataGrid.setStickToBottom(true);
408 this._updateColumns();
409 this._dataGrid.setName("networkLog");
410 this._dataGrid.setResizeMethod(WebInspector.DataGrid.ResizeMethod.Last);
411 this._dataGrid.element.classList.add("network-log-grid");
412 this._dataGrid.element.addEventListener("contextmenu", this._contextMenu .bind(this), true);
413 this._dataGrid.show(this.element);
414
415 // Event listeners need to be added _after_ we attach to the document, s o that owner document is properly update.
416 this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChan ged, this._sortItems, this);
417 this._dataGrid.addEventListener(WebInspector.DataGrid.Events.ColumnsResi zed, this._updateDividersIfNeeded, this);
418
419 this._patchTimelineHeader();
420 this._dataGrid.sortNodes(this._sortingFunctions.startTime, false);
421 },
422
423 /**
424 * @param {string} title
425 * @param {string} subtitle
426 * @return {!DocumentFragment}
427 */
428 _makeHeaderFragment: function(title, subtitle)
429 {
430 var fragment = createDocumentFragment();
431 fragment.createTextChild(title);
432 var subtitleDiv = fragment.createChild("div", "network-header-subtitle") ;
433 subtitleDiv.createTextChild(subtitle);
434 return fragment;
435 },
436
437 _patchTimelineHeader: function()
438 {
439 var timelineSorting = createElement("select");
440
441 var option = createElement("option");
442 option.value = "startTime";
443 option.label = WebInspector.UIString("Timeline");
444 timelineSorting.appendChild(option);
445
446 option = createElement("option");
447 option.value = "startTime";
448 option.label = WebInspector.UIString("Start Time");
449 timelineSorting.appendChild(option);
450
451 option = createElement("option");
452 option.value = "responseTime";
453 option.label = WebInspector.UIString("Response Time");
454 timelineSorting.appendChild(option);
455
456 option = createElement("option");
457 option.value = "endTime";
458 option.label = WebInspector.UIString("End Time");
459 timelineSorting.appendChild(option);
460
461 option = createElement("option");
462 option.value = "duration";
463 option.label = WebInspector.UIString("Duration");
464 timelineSorting.appendChild(option);
465
466 option = createElement("option");
467 option.value = "latency";
468 option.label = WebInspector.UIString("Latency");
469 timelineSorting.appendChild(option);
470
471 var header = this._dataGrid.headerTableHeader("timeline");
472 header.replaceChild(timelineSorting, header.firstChild);
473
474 timelineSorting.addEventListener("click", function(event) { event.consum e() }, false);
475 timelineSorting.addEventListener("change", this._sortByTimeline.bind(thi s), false);
476 this._timelineSortSelector = timelineSorting;
477 },
478
479 _createSortingFunctions: function()
480 {
481 this._sortingFunctions = {};
482 this._sortingFunctions.name = WebInspector.NetworkDataGridNode.NameCompa rator;
483 this._sortingFunctions.method = WebInspector.NetworkDataGridNode.Request PropertyComparator.bind(null, "method", false);
484 this._sortingFunctions.status = WebInspector.NetworkDataGridNode.Request PropertyComparator.bind(null, "statusCode", false);
485 this._sortingFunctions.scheme = WebInspector.NetworkDataGridNode.Request PropertyComparator.bind(null, "scheme", false);
486 this._sortingFunctions.domain = WebInspector.NetworkDataGridNode.Request PropertyComparator.bind(null, "domain", false);
487 this._sortingFunctions.remoteAddress = WebInspector.NetworkDataGridNode. RemoteAddressComparator;
488 this._sortingFunctions.type = WebInspector.NetworkDataGridNode.RequestPr opertyComparator.bind(null, "mimeType", false);
489 this._sortingFunctions.initiator = WebInspector.NetworkDataGridNode.Init iatorComparator;
490 this._sortingFunctions.cookies = WebInspector.NetworkDataGridNode.Reques tCookiesCountComparator;
491 this._sortingFunctions.setCookies = WebInspector.NetworkDataGridNode.Res ponseCookiesCountComparator;
492 this._sortingFunctions.size = WebInspector.NetworkDataGridNode.SizeCompa rator;
493 this._sortingFunctions.time = WebInspector.NetworkDataGridNode.RequestPr opertyComparator.bind(null, "duration", false);
494 this._sortingFunctions.connectionId = WebInspector.NetworkDataGridNode.R equestPropertyComparator.bind(null, "connectionId", false);
495 this._sortingFunctions.timeline = WebInspector.NetworkDataGridNode.Reque stPropertyComparator.bind(null, "startTime", false);
496 this._sortingFunctions.startTime = WebInspector.NetworkDataGridNode.Requ estPropertyComparator.bind(null, "startTime", false);
497 this._sortingFunctions.endTime = WebInspector.NetworkDataGridNode.Reques tPropertyComparator.bind(null, "endTime", false);
498 this._sortingFunctions.responseTime = WebInspector.NetworkDataGridNode.R equestPropertyComparator.bind(null, "responseReceivedTime", false);
499 this._sortingFunctions.duration = WebInspector.NetworkDataGridNode.Reque stPropertyComparator.bind(null, "duration", true);
500 this._sortingFunctions.latency = WebInspector.NetworkDataGridNode.Reques tPropertyComparator.bind(null, "latency", true);
501 },
502
503 _createCalculators: function()
504 {
505 /** @type {!WebInspector.NetworkTransferTimeCalculator} */
506 this._timeCalculator = new WebInspector.NetworkTransferTimeCalculator();
507 /** @type {!WebInspector.NetworkTransferDurationCalculator} */
508 this._durationCalculator = new WebInspector.NetworkTransferDurationCalcu lator();
509
510 /** @type {!Object.<string, !WebInspector.NetworkTimeCalculator>} */
511 this._calculators = {};
512 this._calculators.timeline = this._timeCalculator;
513 this._calculators.startTime = this._timeCalculator;
514 this._calculators.endTime = this._timeCalculator;
515 this._calculators.responseTime = this._timeCalculator;
516 this._calculators.duration = this._durationCalculator;
517 this._calculators.latency = this._durationCalculator;
518
519 this._calculator = this._timeCalculator;
520 },
521
522 _sortItems: function()
523 {
524 this._removeAllNodeHighlights();
525 var columnIdentifier = this._dataGrid.sortColumnIdentifier();
526 if (columnIdentifier === "timeline") {
527 this._sortByTimeline();
528 return;
529 }
530 var sortingFunction = this._sortingFunctions[columnIdentifier];
531 if (!sortingFunction)
532 return;
533
534 this._dataGrid.sortNodes(sortingFunction, !this._dataGrid.isSortOrderAsc ending());
535 this._highlightNthMatchedRequestForSearch(this._updateMatchCountAndFindM atchIndex(this._currentMatchedRequestNode), false);
536 this._timelineSortSelector.selectedIndex = 0;
537
538 WebInspector.notifications.dispatchEventToListeners(WebInspector.UserMet rics.UserAction, {
539 action: WebInspector.UserMetrics.UserActionNames.NetworkSort,
540 column: columnIdentifier,
541 sortOrder: this._dataGrid.sortOrder()
542 });
543 },
544
545 _sortByTimeline: function()
546 {
547 this._removeAllNodeHighlights();
548 var selectedIndex = this._timelineSortSelector.selectedIndex;
549 if (!selectedIndex)
550 selectedIndex = 1; // Sort by start time by default.
551 var selectedOption = this._timelineSortSelector[selectedIndex];
552 var value = selectedOption.value;
553
554 this._setCalculator(this._calculators[value]);
555 var sortingFunction = this._sortingFunctions[value];
556 this._dataGrid.sortNodes(sortingFunction);
557 this._highlightNthMatchedRequestForSearch(this._updateMatchCountAndFindM atchIndex(this._currentMatchedRequestNode), false);
558 this._dataGrid.markColumnAsSortedBy("timeline", WebInspector.DataGrid.Or der.Ascending);
559 },
560
561 _createStatusBarItems: function()
562 {
563 this._progressBarContainer = createElement("div");
564 this._progressBarContainer.className = "status-bar-item";
565 },
566
567 _updateSummaryBar: function()
568 {
569 var requestsNumber = this._nodesByRequestId.size;
570
571 if (!requestsNumber) {
572 if (this._summaryBarElement._isDisplayingWarning)
573 return;
574 this._summaryBarElement._isDisplayingWarning = true;
575 this._summaryBarElement.removeChildren();
576 this._summaryBarElement.createChild("div", "warning-icon-small");
577 var text = WebInspector.UIString("No requests captured. Reload the p age to see detailed information on the network activity.");
578 this._summaryBarElement.createTextChild(text);
579 this._summaryBarElement.title = text;
580 return;
581 }
582 delete this._summaryBarElement._isDisplayingWarning;
583
584 var transferSize = 0;
585 var selectedRequestsNumber = 0;
586 var selectedTransferSize = 0;
587 var baseTime = -1;
588 var maxTime = -1;
589 var nodes = this._nodesByRequestId.valuesArray();
590 for (var i = 0; i < nodes.length; ++i) {
591 var request = nodes[i].request();
592 var requestTransferSize = request.transferSize;
593 transferSize += requestTransferSize;
594 if (!nodes[i]._isFilteredOut) {
595 selectedRequestsNumber++;
596 selectedTransferSize += requestTransferSize;
597 }
598 if (request.url === request.target().resourceTreeModel.inspectedPage URL())
599 baseTime = request.startTime;
600 if (request.endTime > maxTime)
601 maxTime = request.endTime;
602 }
603 var text = "";
604 if (selectedRequestsNumber !== requestsNumber) {
605 text += String.sprintf(WebInspector.UIString("%d / %d requests"), se lectedRequestsNumber, requestsNumber);
606 text += " \u2758 " + String.sprintf(WebInspector.UIString("%s / %s transferred"), Number.bytesToString(selectedTransferSize), Number.bytesToString (transferSize));
607 } else {
608 text += String.sprintf(WebInspector.UIString("%d requests"), request sNumber);
609 text += " \u2758 " + String.sprintf(WebInspector.UIString("%s tran sferred"), Number.bytesToString(transferSize));
610 }
611 if (baseTime !== -1 && this._mainRequestLoadTime !== -1 && this._mainReq uestDOMContentLoadedTime !== -1 && this._mainRequestDOMContentLoadedTime > baseT ime) {
612 text += " \u2758 " + String.sprintf(WebInspector.UIString("%s (loa d: %s, DOMContentLoaded: %s)"),
613 Number.secondsToString(maxTime - baseTime),
614 Number.secondsToString(this._mainRequestLoadTime - baseT ime),
615 Number.secondsToString(this._mainRequestDOMContentLoaded Time - baseTime));
616 }
617 this._summaryBarElement.textContent = text;
618 this._summaryBarElement.title = text;
619 },
620
621 _scheduleRefresh: function()
622 {
623 if (this._needsRefresh)
624 return;
625
626 this._needsRefresh = true;
627
628 if (this.isShowing() && !this._refreshTimeout)
629 this._refreshTimeout = setTimeout(this.refresh.bind(this), WebInspec tor.NetworkLogView._defaultRefreshDelay);
630 },
631
632 _updateDividersIfNeeded: function()
633 {
634 var timelineOffset = this._dataGrid.columnOffset("timeline");
635 // Position timline grid location.
636 if (timelineOffset)
637 this._timelineGrid.element.style.left = timelineOffset + "px";
638
639 var calculator = this.calculator();
640 var proceed = true;
641 if (!this.isShowing()) {
642 this._scheduleRefresh();
643 proceed = false;
644 } else {
645 calculator.setDisplayWindow(this._timelineGrid.dividersElement.clien tWidth);
646 proceed = this._timelineGrid.updateDividers(calculator);
647 }
648 if (!proceed)
649 return;
650
651 if (calculator.startAtZero) {
652 // If our current sorting method starts at zero, that means it shows all
653 // requests starting at the same point, and so onLoad event and DOMC ontent
654 // event lines really wouldn't make much sense here, so don't render them.
655 return;
656 }
657
658 this._timelineGrid.removeEventDividers();
659 var loadTimePercent = calculator.computePercentageFromEventTime(this._ma inRequestLoadTime);
660 if (this._mainRequestLoadTime !== -1 && loadTimePercent >= 0) {
661 var loadDivider = createElementWithClass("div", "network-event-divid er-padding");
662 loadDivider.createChild("div", "network-event-divider network-red-di vider");
663 loadDivider.title = WebInspector.UIString("Load event");
664 loadDivider.style.left = loadTimePercent + "%";
665 this._timelineGrid.addEventDivider(loadDivider);
666 }
667
668 var domLoadTimePrecent = calculator.computePercentageFromEventTime(this. _mainRequestDOMContentLoadedTime);
669 if (this._mainRequestDOMContentLoadedTime !== -1 && domLoadTimePrecent > = 0) {
670 var domContentLoadedDivider = createElementWithClass("div", "network -event-divider-padding");
671 domContentLoadedDivider.createChild("div", "network-event-divider ne twork-blue-divider");
672 domContentLoadedDivider.title = WebInspector.UIString("DOMContentLoa ded event");
673 domContentLoadedDivider.style.left = domLoadTimePrecent + "%";
674 this._timelineGrid.addEventDivider(domContentLoadedDivider);
675 }
676 },
677
678 _refreshIfNeeded: function()
679 {
680 if (this._needsRefresh)
681 this.refresh();
682 },
683
684 _invalidateAllItems: function()
685 {
686 var requestIds = this._nodesByRequestId.keysArray();
687 for (var i = 0; i < requestIds.length; ++i)
688 this._staleRequestIds[requestIds[i]] = true;
689 },
690
691 /**
692 * @return {!WebInspector.NetworkTimeCalculator}
693 */
694 calculator: function()
695 {
696 return this._calculator;
697 },
698
699 /**
700 * @param {!WebInspector.NetworkTimeCalculator} x
701 */
702 _setCalculator: function(x)
703 {
704 if (!x || this._calculator === x)
705 return;
706
707 this._calculator = x;
708 this._calculator.reset();
709
710 if (this._calculator.startAtZero)
711 this._timelineGrid.hideEventDividers();
712 else
713 this._timelineGrid.showEventDividers();
714
715 this._invalidateAllItems();
716 this.refresh();
717 },
718
719 _createStatusbarButtons: function()
720 {
721 this._recordButton = new WebInspector.StatusBarButton("", "record-profil e-status-bar-item");
722 this._recordButton.addEventListener("click", this._onRecordButtonClicked , this);
723
724 this._clearButton = new WebInspector.StatusBarButton(WebInspector.UIStri ng("Clear"), "clear-status-bar-item");
725 this._clearButton.addEventListener("click", this._reset, this);
726
727 this._largerRequestsButton = new WebInspector.StatusBarButton(WebInspect or.UIString("Use small resource rows."), "network-larger-resources-status-bar-it em");
728 this._largerRequestsButton.setToggled(WebInspector.settings.resourcesLar geRows.get());
729 this._largerRequestsButton.addEventListener("click", this._toggleLargerR equests, this);
730
731 this._preserveLogCheckbox = new WebInspector.StatusBarCheckbox(WebInspec tor.UIString("Preserve log"));
732 this._preserveLogCheckbox.element.title = WebInspector.UIString("Do not clear log on page reload / navigation.");
733
734 this._disableCacheCheckbox = new WebInspector.StatusBarCheckbox(WebInspe ctor.UIString("Disable cache"));
735 WebInspector.SettingsUI.bindCheckbox(this._disableCacheCheckbox.inputEle ment, WebInspector.settings.cacheDisabled);
736 this._disableCacheCheckbox.element.title = WebInspector.UIString("Disabl e cache (while DevTools is open).");
737 },
738
739 /**
740 * @param {!WebInspector.Event} event
741 */
742 _loadEventFired: function(event)
743 {
744 if (!this._recordButton.toggled())
745 return;
746
747 var data = /** @type {number} */ (event.data);
748 this._mainRequestLoadTime = data || -1;
749 // Schedule refresh to update boundaries and draw the new line.
750 this._scheduleRefresh();
751 },
752
753 /**
754 * @param {!WebInspector.Event} event
755 */
756 _domContentLoadedEventFired: function(event)
757 {
758 if (!this._recordButton.toggled())
759 return;
760 var data = /** @type {number} */ (event.data);
761 this._mainRequestDOMContentLoadedTime = data || -1;
762 // Schedule refresh to update boundaries and draw the new line.
763 this._scheduleRefresh();
764 },
765
766 wasShown: function()
767 {
768 this._refreshIfNeeded();
769 },
770
771 willHide: function()
772 {
773 this._popoverHelper.hidePopover();
774 },
775
776 refresh: function()
777 {
778 this._needsRefresh = false;
779 if (this._refreshTimeout) {
780 clearTimeout(this._refreshTimeout);
781 delete this._refreshTimeout;
782 }
783
784 this._removeAllNodeHighlights();
785 var boundariesChanged = false;
786 var calculator = this.calculator();
787 if (calculator.updateBoundariesForEventTime) {
788 boundariesChanged = calculator.updateBoundariesForEventTime(this._ma inRequestLoadTime) || boundariesChanged;
789 boundariesChanged = calculator.updateBoundariesForEventTime(this._ma inRequestDOMContentLoadedTime) || boundariesChanged;
790 }
791
792 var dataGrid = this._dataGrid;
793 var rootNode = dataGrid.rootNode();
794 var nodesToInsert = [];
795 for (var requestId in this._staleRequestIds) {
796 var node = this._nodesByRequestId.get(requestId);
797 if (!node)
798 continue;
799 if (!node._isFilteredOut)
800 rootNode.removeChild(node);
801 node._isFilteredOut = !this._applyFilter(node);
802 if (!node._isFilteredOut)
803 nodesToInsert.push(node);
804 }
805
806 for (var i = 0; i < nodesToInsert.length; ++i) {
807 var node = nodesToInsert[i];
808 var request = node.request();
809 node.refresh();
810 dataGrid.insertChild(node);
811 node._isMatchingSearchQuery = this._matchRequest(request);
812 if (calculator.updateBoundaries(request))
813 boundariesChanged = true;
814 }
815
816 this._highlightNthMatchedRequestForSearch(this._updateMatchCountAndFindM atchIndex(this._currentMatchedRequestNode), false);
817
818 if (boundariesChanged) {
819 // The boundaries changed, so all item graphs are stale.
820 this._updateDividersIfNeeded();
821 var nodes = this._nodesByRequestId.valuesArray();
822 for (var i = 0; i < nodes.length; ++i)
823 nodes[i].refreshGraph();
824 }
825
826 this._staleRequestIds = {};
827 this._updateSummaryBar();
828 },
829
830 _onRecordButtonClicked: function()
831 {
832 if (!this._recordButton.toggled())
833 this._reset();
834 this._toggleRecordButton(!this._recordButton.toggled());
835 },
836
837 /**
838 * @param {boolean} toggled
839 */
840 _toggleRecordButton: function(toggled)
841 {
842 this._recordButton.setToggled(toggled);
843 this._recordButton.setTitle(toggled ? WebInspector.UIString("Stop Record ing Network Log") : WebInspector.UIString("Record Network Log"));
844 },
845
846 _reset: function()
847 {
848 this.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes.Vie wCleared);
849
850 this._clearSearchMatchedList();
851 if (this._popoverHelper)
852 this._popoverHelper.hidePopover();
853
854 if (this._calculator)
855 this._calculator.reset();
856
857 var nodes = this._nodesByRequestId.valuesArray();
858 for (var i = 0; i < nodes.length; ++i)
859 nodes[i].dispose();
860
861 this._nodesByRequestId.clear();
862 this._staleRequestIds = {};
863 this._resetSuggestionBuilder();
864
865 if (this._dataGrid) {
866 this._dataGrid.rootNode().removeChildren();
867 this._updateDividersIfNeeded();
868 this._updateSummaryBar();
869 }
870
871 this._mainRequestLoadTime = -1;
872 this._mainRequestDOMContentLoadedTime = -1;
873 },
874
875 /**
876 * @param {!WebInspector.Event} event
877 */
878 _onRequestStarted: function(event)
879 {
880 if (this._recordButton.toggled()) {
881 var request = /** @type {!WebInspector.NetworkRequest} */ (event.dat a);
882 this._appendRequest(request);
883 }
884 },
885
886 /**
887 * @param {!WebInspector.NetworkRequest} request
888 */
889 _appendRequest: function(request)
890 {
891 var node = new WebInspector.NetworkDataGridNode(this, request);
892
893 // In case of redirect request id is reassigned to a redirected
894 // request and we need to update _nodesByRequestId and search results.
895 var originalRequestNode = this._nodesByRequestId.get(request.requestId);
896 if (originalRequestNode)
897 this._nodesByRequestId.set(originalRequestNode.request().requestId, originalRequestNode);
898 this._nodesByRequestId.set(request.requestId, node);
899
900 // Pull all the redirects of the main request upon commit load.
901 if (request.redirects) {
902 for (var i = 0; i < request.redirects.length; ++i)
903 this._refreshRequest(request.redirects[i]);
904 }
905
906 this._refreshRequest(request);
907 },
908
909 /**
910 * @param {!WebInspector.Event} event
911 */
912 _onRequestUpdated: function(event)
913 {
914 var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
915 this._refreshRequest(request);
916 },
917
918 /**
919 * @param {!WebInspector.NetworkRequest} request
920 */
921 _refreshRequest: function(request)
922 {
923 if (!this._nodesByRequestId.get(request.requestId))
924 return;
925
926 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.D omain, request.domain);
927 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.M ethod, request.requestMethod);
928 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.M imeType, request.mimeType);
929 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.S cheme, "" + request.scheme);
930 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.S tatusCode, "" + request.statusCode);
931
932 var responseHeaders = request.responseHeaders;
933 for (var i = 0, l = responseHeaders.length; i < l; ++i)
934 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterTy pe.HasResponseHeader, responseHeaders[i].name);
935 var cookies = request.responseCookies;
936 for (var i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
937 var cookie = cookies[i];
938 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterTy pe.SetCookieDomain, cookie.domain());
939 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterTy pe.SetCookieName, cookie.name());
940 this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterTy pe.SetCookieValue, cookie.value());
941 }
942
943 this._staleRequestIds[request.requestId] = true;
944 this._scheduleRefresh();
945 },
946
947 /**
948 * @param {!WebInspector.Event} event
949 */
950 _willReloadPage: function(event)
951 {
952 this._recordButton.setToggled(true);
953 if (!this._preserveLogCheckbox.checked())
954 this._reset();
955 },
956
957 /**
958 * @param {!WebInspector.Event} event
959 */
960 _mainFrameNavigated: function(event)
961 {
962 if (!this._recordButton.toggled() || this._preserveLogCheckbox.checked() )
963 return;
964
965 var frame = /** @type {!WebInspector.ResourceTreeFrame} */ (event.data);
966 var loaderId = frame.loaderId;
967
968 // Pick provisional load requests.
969 var requestsToPick = [];
970 var requests = frame.target().networkLog.requests;
971 for (var i = 0; i < requests.length; ++i) {
972 var request = requests[i];
973 if (request.loaderId === loaderId)
974 requestsToPick.push(request);
975 }
976
977 this._reset();
978
979 for (var i = 0; i < requestsToPick.length; ++i)
980 this._appendRequest(requestsToPick[i]);
981 },
982
983 /**
984 * @param {boolean} detailed
985 */
986 switchViewMode: function(detailed)
987 {
988 if (this._detailedMode === detailed)
989 return;
990 this._detailedMode = detailed;
991
992 if (detailed) {
993 if (this._dataGrid.selectedNode)
994 this._dataGrid.selectedNode.selected = false;
995 } else {
996 this._removeAllNodeHighlights();
997 this._popoverHelper.hidePopover();
998 }
999
1000 this.element.classList.toggle("brief-mode", !detailed);
1001 this._updateColumns();
1002 },
1003
1004 _toggleLargerRequests: function()
1005 {
1006 WebInspector.settings.resourcesLargeRows.set(!WebInspector.settings.reso urcesLargeRows.get());
1007 this._updateRowsSize();
1008 },
1009
1010 /**
1011 * @return {number}
1012 */
1013 rowHeight: function()
1014 {
1015 return this._rowHeight;
1016 },
1017
1018 _updateRowsSize: function()
1019 {
1020 var largeRows = this.usesLargeRows();
1021 this._largerRequestsButton.setToggled(largeRows);
1022 this._rowHeight = largeRows ? 41 : 21;
1023 this._largerRequestsButton.setTitle(WebInspector.UIString(largeRows ? "U se small resource rows." : "Use large resource rows."));
1024 this._dataGrid.element.classList.toggle("small", !largeRows);
1025 this._timelineGrid.element.classList.toggle("small", !largeRows);
1026 this.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes.Row SizeChanged, { largeRows: largeRows });
1027 },
1028
1029 /**
1030 * @param {!Element} element
1031 * @param {!Event} event
1032 * @return {!Element|!AnchorBox|undefined}
1033 */
1034 _getPopoverAnchor: function(element, event)
1035 {
1036 if (!this._allowPopover)
1037 return;
1038 var anchor = element.enclosingNodeOrSelfWithClass("network-graph-bar") | | element.enclosingNodeOrSelfWithClass("network-graph-label");
1039 if (anchor && anchor.parentElement.request && anchor.parentElement.reque st.timing)
1040 return anchor;
1041 anchor = element.enclosingNodeOrSelfWithClass("network-script-initiated" );
1042 if (anchor && anchor.request) {
1043 var request = /** @type {!WebInspector.NetworkRequest} */ (anchor.re quest);
1044 var initiator = anchor.request.initiator();
1045 if (initiator && (initiator.stackTrace || initiator.asyncStackTrace) )
1046 return anchor;
1047 }
1048 },
1049
1050 /**
1051 * @param {!Element} anchor
1052 * @param {!WebInspector.Popover} popover
1053 */
1054 _showPopover: function(anchor, popover)
1055 {
1056 var content;
1057 if (anchor.classList.contains("network-script-initiated")) {
1058 content = this._generateScriptInitiatedPopoverContent(anchor.request );
1059 popover.setCanShrink(true);
1060 } else {
1061 content = WebInspector.RequestTimingView.createTimingTable(anchor.pa rentElement.request);
1062 popover.setCanShrink(false);
1063 }
1064 popover.show(content, anchor);
1065 },
1066
1067 _onHidePopover: function()
1068 {
1069 this._linkifier.reset();
1070 },
1071
1072 /**
1073 * @param {!WebInspector.NetworkRequest} request
1074 * @return {!Element}
1075 */
1076 _generateScriptInitiatedPopoverContent: function(request)
1077 {
1078 var framesTable = createElementWithClass("table", "network-stack-trace") ;
1079
1080 /**
1081 * @param {!Array.<!ConsoleAgent.CallFrame>} stackTrace
1082 * @this {WebInspector.NetworkLogView}
1083 */
1084 function appendStackTrace(stackTrace)
1085 {
1086 for (var i = 0; i < stackTrace.length; ++i) {
1087 var stackFrame = stackTrace[i];
1088 var row = createElement("tr");
1089 row.createChild("td").textContent = stackFrame.functionName || W ebInspector.UIString("(anonymous function)");
1090 row.createChild("td").textContent = " @ ";
1091 row.createChild("td").appendChild(this._linkifier.linkifyConsole CallFrame(request.target(), stackFrame));
1092 framesTable.appendChild(row);
1093 }
1094 }
1095
1096 // Initiator is not null, checked in _getPopoverAnchor.
1097 var initiator = /** @type {!NetworkAgent.Initiator} */ (request.initiato r());
1098 if (initiator.stackTrace)
1099 appendStackTrace.call(this, initiator.stackTrace);
1100
1101 var asyncStackTrace = initiator.asyncStackTrace;
1102 while (asyncStackTrace) {
1103 var callFrames = asyncStackTrace.callFrames;
1104 if (!callFrames || !callFrames.length)
1105 break;
1106 var row = framesTable.createChild("tr");
1107 row.createChild("td", "network-async-trace-description").textContent = WebInspector.asyncStackTraceLabel(asyncStackTrace.description);
1108 row.createChild("td");
1109 row.createChild("td");
1110 appendStackTrace.call(this, callFrames);
1111 asyncStackTrace = asyncStackTrace.asyncStackTrace;
1112 }
1113
1114 return framesTable;
1115 },
1116
1117 _updateColumns: function()
1118 {
1119 var detailedMode = !!this._detailedMode;
1120 var visibleColumns = {"name": true};
1121 if (detailedMode) {
1122 visibleColumns["timeline"] = true;
1123 var columnsVisibility = this._coulmnsVisibilitySetting.get();
1124 for (var columnIdentifier in columnsVisibility)
1125 visibleColumns[columnIdentifier] = columnsVisibility[columnIdent ifier];
1126 }
1127
1128 this._dataGrid.setColumnsVisiblity(visibleColumns);
1129 },
1130
1131 /**
1132 * @param {string} columnIdentifier
1133 */
1134 _toggleColumnVisibility: function(columnIdentifier)
1135 {
1136 var columnsVisibility = this._coulmnsVisibilitySetting.get();
1137 columnsVisibility[columnIdentifier] = !columnsVisibility[columnIdentifie r];
1138 this._coulmnsVisibilitySetting.set(columnsVisibility);
1139
1140 this._updateColumns();
1141 },
1142
1143 /**
1144 * @return {!Array.<string>}
1145 */
1146 _getConfigurableColumnIDs: function()
1147 {
1148 if (this._configurableColumnIDs)
1149 return this._configurableColumnIDs;
1150
1151 var columnTitles = WebInspector.NetworkLogView._columnTitles;
1152 function compare(id1, id2)
1153 {
1154 return columnTitles[id1].compareTo(columnTitles[id2]);
1155 }
1156
1157 var columnIDs = Object.keys(this._coulmnsVisibilitySetting.get());
1158 this._configurableColumnIDs = columnIDs.sort(compare);
1159 return this._configurableColumnIDs;
1160 },
1161
1162 /**
1163 * @param {!Event} event
1164 */
1165 _contextMenu: function(event)
1166 {
1167 var contextMenu = new WebInspector.ContextMenu(event);
1168
1169 if (this._detailedMode && event.target.isSelfOrDescendant(this._dataGrid .headerTableBody)) {
1170 var columnsVisibility = this._coulmnsVisibilitySetting.get();
1171 var columnIDs = this._getConfigurableColumnIDs();
1172 var columnTitles = WebInspector.NetworkLogView._columnTitles;
1173 for (var i = 0; i < columnIDs.length; ++i) {
1174 var columnIdentifier = columnIDs[i];
1175 contextMenu.appendCheckboxItem(columnTitles[columnIdentifier], t his._toggleColumnVisibility.bind(this, columnIdentifier), !!columnsVisibility[co lumnIdentifier]);
1176 }
1177 contextMenu.show();
1178 return;
1179 }
1180
1181 var gridNode = this._dataGrid.dataGridNodeFromNode(event.target);
1182 var request = gridNode && gridNode.request();
1183
1184 /**
1185 * @param {string} url
1186 */
1187 function openResourceInNewTab(url)
1188 {
1189 InspectorFrontendHost.openInNewTab(url);
1190 }
1191
1192 if (request) {
1193 contextMenu.appendItem(WebInspector.openLinkExternallyLabel(), openR esourceInNewTab.bind(null, request.url));
1194 contextMenu.appendSeparator();
1195 contextMenu.appendItem(WebInspector.copyLinkAddressLabel(), this._co pyLocation.bind(this, request));
1196 if (request.requestHeadersText())
1197 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLow erCaseMenuTitles() ? "Copy request headers" : "Copy Request Headers"), this._cop yRequestHeaders.bind(this, request));
1198 if (request.responseHeadersText)
1199 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLow erCaseMenuTitles() ? "Copy response headers" : "Copy Response Headers"), this._c opyResponseHeaders.bind(this, request));
1200 if (request.finished)
1201 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLow erCaseMenuTitles() ? "Copy response" : "Copy Response"), this._copyResponse.bind (this, request));
1202 contextMenu.appendItem(WebInspector.UIString("Copy as cURL"), this._ copyCurlCommand.bind(this, request));
1203 }
1204 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMe nuTitles() ? "Copy all as HAR" : "Copy All as HAR"), this._copyAll.bind(this));
1205
1206 contextMenu.appendSeparator();
1207 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMe nuTitles() ? "Save as HAR with content" : "Save as HAR with Content"), this._exp ortAll.bind(this));
1208
1209 contextMenu.appendSeparator();
1210 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMe nuTitles() ? "Clear browser cache" : "Clear Browser Cache"), this._clearBrowserC ache.bind(this));
1211 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMe nuTitles() ? "Clear browser cookies" : "Clear Browser Cookies"), this._clearBrow serCookies.bind(this));
1212
1213 if (request && request.resourceType() === WebInspector.resourceTypes.XHR ) {
1214 contextMenu.appendSeparator();
1215 contextMenu.appendItem(WebInspector.UIString("Replay XHR"), request. replayXHR.bind(request));
1216 contextMenu.appendSeparator();
1217 }
1218
1219 contextMenu.show();
1220 },
1221
1222 _harRequests: function()
1223 {
1224 var requests = this._nodesByRequestId.valuesArray().map(function(node) { return node.request(); });
1225 var httpRequests = requests.filter(WebInspector.NetworkLogView.HTTPReque stsFilter);
1226 httpRequests = httpRequests.filter(WebInspector.NetworkLogView.FinishedR equestsFilter);
1227 return httpRequests.filter(WebInspector.NetworkLogView.NonDevToolsReques tsFilter);
1228 },
1229
1230 _copyAll: function()
1231 {
1232 var harArchive = {
1233 log: (new WebInspector.HARLog(this._harRequests())).build()
1234 };
1235 InspectorFrontendHost.copyText(JSON.stringify(harArchive, null, 2));
1236 },
1237
1238 /**
1239 * @param {!WebInspector.NetworkRequest} request
1240 */
1241 _copyLocation: function(request)
1242 {
1243 InspectorFrontendHost.copyText(request.url);
1244 },
1245
1246 /**
1247 * @param {!WebInspector.NetworkRequest} request
1248 */
1249 _copyRequestHeaders: function(request)
1250 {
1251 InspectorFrontendHost.copyText(request.requestHeadersText());
1252 },
1253
1254 /**
1255 * @param {!WebInspector.NetworkRequest} request
1256 */
1257 _copyResponse: function(request)
1258 {
1259 /**
1260 * @param {?string} content
1261 */
1262 function callback(content)
1263 {
1264 if (request.contentEncoded)
1265 content = request.asDataURL();
1266 InspectorFrontendHost.copyText(content || "");
1267 }
1268 request.requestContent(callback);
1269 },
1270
1271 /**
1272 * @param {!WebInspector.NetworkRequest} request
1273 */
1274 _copyResponseHeaders: function(request)
1275 {
1276 InspectorFrontendHost.copyText(request.responseHeadersText);
1277 },
1278
1279 /**
1280 * @param {!WebInspector.NetworkRequest} request
1281 */
1282 _copyCurlCommand: function(request)
1283 {
1284 InspectorFrontendHost.copyText(this._generateCurlCommand(request));
1285 },
1286
1287 _exportAll: function()
1288 {
1289 var filename = WebInspector.targetManager.inspectedPageDomain() + ".har" ;
1290 var stream = new WebInspector.FileOutputStream();
1291 stream.open(filename, openCallback.bind(this));
1292
1293 /**
1294 * @param {boolean} accepted
1295 * @this {WebInspector.NetworkLogView}
1296 */
1297 function openCallback(accepted)
1298 {
1299 if (!accepted)
1300 return;
1301 var progressIndicator = new WebInspector.ProgressIndicator();
1302 this._progressBarContainer.appendChild(progressIndicator.element);
1303 var harWriter = new WebInspector.HARWriter();
1304 harWriter.write(stream, this._harRequests(), progressIndicator);
1305 }
1306 },
1307
1308 _clearBrowserCache: function()
1309 {
1310 if (confirm(WebInspector.UIString("Are you sure you want to clear browse r cache?")))
1311 NetworkAgent.clearBrowserCache();
1312 },
1313
1314 _clearBrowserCookies: function()
1315 {
1316 if (confirm(WebInspector.UIString("Are you sure you want to clear browse r cookies?")))
1317 NetworkAgent.clearBrowserCookies();
1318 },
1319
1320 /**
1321 * @param {!WebInspector.NetworkRequest} request
1322 * @return {boolean}
1323 */
1324 _matchRequest: function(request)
1325 {
1326 var re = this._searchRegExp;
1327 if (!re)
1328 return false;
1329 return re.test(request.name()) || re.test(request.path());
1330 },
1331
1332 _clearSearchMatchedList: function()
1333 {
1334 this._matchedRequestCount = -1;
1335 this._currentMatchedRequestNode = null;
1336 this._removeAllHighlights();
1337 },
1338
1339 _removeAllHighlights: function()
1340 {
1341 this._removeAllNodeHighlights();
1342 for (var i = 0; i < this._highlightedSubstringChanges.length; ++i)
1343 WebInspector.revertDomChanges(this._highlightedSubstringChanges[i]);
1344 this._highlightedSubstringChanges = [];
1345 },
1346
1347 /**
1348 * @param {number} n
1349 * @param {boolean} reveal
1350 */
1351 _highlightNthMatchedRequestForSearch: function(n, reveal)
1352 {
1353 this._removeAllHighlights();
1354
1355 /** @type {!Array.<!WebInspector.NetworkDataGridNode>} */
1356 var nodes = this._dataGrid.rootNode().children;
1357 var matchCount = 0;
1358 var node = null;
1359 for (var i = 0; i < nodes.length; ++i) {
1360 if (nodes[i]._isMatchingSearchQuery) {
1361 if (matchCount === n) {
1362 node = nodes[i];
1363 break;
1364 }
1365 matchCount++;
1366 }
1367 }
1368 if (!node) {
1369 this._currentMatchedRequestNode = null;
1370 return;
1371 }
1372
1373 var request = node.request();
1374 var regExp = this._searchRegExp;
1375 var nameMatched = request.name().match(regExp);
1376 var pathMatched = request.path().match(regExp);
1377 if (!nameMatched && pathMatched && !this._largerRequestsButton.toggled() )
1378 this._toggleLargerRequests();
1379 if (reveal)
1380 WebInspector.Revealer.reveal(request);
1381 var highlightedSubstringChanges = node.highlightMatchedSubstring(regExp) ;
1382 this._highlightedSubstringChanges.push(highlightedSubstringChanges);
1383
1384 this._currentMatchedRequestNode = node;
1385 this._currentMatchedRequestIndex = n;
1386 this.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes.Sea rchIndexUpdated, n);
1387 },
1388
1389 /**
1390 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig
1391 * @param {boolean} shouldJump
1392 * @param {boolean=} jumpBackwards
1393 */
1394 performSearch: function(searchConfig, shouldJump, jumpBackwards)
1395 {
1396 var query = searchConfig.query;
1397 var currentMatchedRequestNode = this._currentMatchedRequestNode;
1398 this._clearSearchMatchedList();
1399 this._searchRegExp = createPlainTextSearchRegex(query, "i");
1400
1401 /** @type {!Array.<!WebInspector.NetworkDataGridNode>} */
1402 var nodes = this._dataGrid.rootNode().children;
1403 for (var i = 0; i < nodes.length; ++i)
1404 nodes[i]._isMatchingSearchQuery = this._matchRequest(nodes[i].reques t());
1405 var newMatchedRequestIndex = this._updateMatchCountAndFindMatchIndex(cur rentMatchedRequestNode);
1406 if (!newMatchedRequestIndex && jumpBackwards)
1407 newMatchedRequestIndex = this._matchedRequestCount - 1;
1408 this._highlightNthMatchedRequestForSearch(newMatchedRequestIndex, should Jump);
1409 },
1410
1411 /**
1412 * @return {boolean}
1413 */
1414 supportsCaseSensitiveSearch: function()
1415 {
1416 return false;
1417 },
1418
1419 /**
1420 * @return {boolean}
1421 */
1422 supportsRegexSearch: function()
1423 {
1424 return false;
1425 },
1426
1427 /**
1428 * @param {?WebInspector.NetworkDataGridNode} node
1429 * @return {number}
1430 */
1431 _updateMatchCountAndFindMatchIndex: function(node)
1432 {
1433 /** @type {!Array.<!WebInspector.NetworkDataGridNode>} */
1434 var nodes = this._dataGrid.rootNode().children;
1435 var matchCount = 0;
1436 var matchIndex = 0;
1437 for (var i = 0; i < nodes.length; ++i) {
1438 if (!nodes[i]._isMatchingSearchQuery)
1439 continue;
1440 if (node === nodes[i])
1441 matchIndex = matchCount;
1442 matchCount++;
1443 }
1444 if (this._matchedRequestCount !== matchCount) {
1445 this._matchedRequestCount = matchCount;
1446 this.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes .SearchCountUpdated, matchCount);
1447 }
1448 return matchIndex;
1449 },
1450
1451 /**
1452 * @param {number} index
1453 * @return {number}
1454 */
1455 _normalizeSearchResultIndex: function(index)
1456 {
1457 return (index + this._matchedRequestCount) % this._matchedRequestCount;
1458 },
1459
1460 /**
1461 * @param {!WebInspector.NetworkDataGridNode} node
1462 * @return {boolean}
1463 */
1464 _applyFilter: function(node)
1465 {
1466 var request = node.request();
1467 var resourceType = request.resourceType();
1468 if (resourceType === WebInspector.resourceTypes.TextTrack)
1469 resourceType = WebInspector.resourceTypes.Other;
1470 if (!this._resourceTypeFilterUI.accept(resourceType.name()))
1471 return false;
1472 if (this._dataURLFilterUI.checked() && request.parsedURL.isDataURL())
1473 return false;
1474 for (var i = 0; i < this._filters.length; ++i) {
1475 if (!this._filters[i](request))
1476 return false;
1477 }
1478 return true;
1479 },
1480
1481 /**
1482 * @param {string} query
1483 */
1484 _parseFilterQuery: function(query)
1485 {
1486 var parsedQuery = this._suggestionBuilder.parseQuery(query);
1487 this._filters = parsedQuery.text.map(this._createTextFilter);
1488 var filters = parsedQuery.filters;
1489 var n = parsedQuery.filters.length;
1490 for (var i = 0; i < n; ++i) {
1491 var filter = parsedQuery.filters[i];
1492 var filterType = /** @type {!WebInspector.NetworkLogView.FilterType} */ (filter.type);
1493 this._filters.push(this._createFilter(filterType, filter.data, filte r.negative));
1494 }
1495 },
1496
1497 /**
1498 * @param {string} text
1499 * @return {!WebInspector.NetworkLogView.Filter}
1500 */
1501 _createTextFilter: function(text)
1502 {
1503 var regexp = new RegExp(text.escapeForRegExp(), "i");
1504 return WebInspector.NetworkLogView._requestNameOrPathFilter.bind(null, r egexp);
1505 },
1506
1507 /**
1508 * @param {!WebInspector.NetworkLogView.FilterType} type
1509 * @param {string} value
1510 * @param {boolean} negative
1511 * @return {!WebInspector.NetworkLogView.Filter}
1512 */
1513 _createFilter: function(type, value, negative)
1514 {
1515 var filter = this._createSpecialFilter(type, value);
1516 if (!filter)
1517 return this._createTextFilter((negative ? "-" : "") + type + ":" + v alue);
1518 if (negative)
1519 return WebInspector.NetworkLogView._negativeFilter.bind(null, filter );
1520 return filter;
1521 },
1522
1523 /**
1524 * @param {!WebInspector.NetworkLogView.FilterType} type
1525 * @param {string} value
1526 * @return {?WebInspector.NetworkLogView.Filter}
1527 */
1528 _createSpecialFilter: function(type, value)
1529 {
1530 switch (type) {
1531 case WebInspector.NetworkLogView.FilterType.Domain:
1532 return WebInspector.NetworkLogView._requestDomainFilter.bind(null, v alue);
1533
1534 case WebInspector.NetworkLogView.FilterType.HasResponseHeader:
1535 return WebInspector.NetworkLogView._requestResponseHeaderFilter.bind (null, value);
1536
1537 case WebInspector.NetworkLogView.FilterType.Is:
1538 if (value.toLowerCase() === WebInspector.NetworkLogView.IsFilterType .Running)
1539 return WebInspector.NetworkLogView._runningRequestFilter;
1540 break;
1541
1542 case WebInspector.NetworkLogView.FilterType.Method:
1543 return WebInspector.NetworkLogView._requestMethodFilter.bind(null, v alue);
1544
1545 case WebInspector.NetworkLogView.FilterType.MimeType:
1546 return WebInspector.NetworkLogView._requestMimeTypeFilter.bind(null, value);
1547
1548 case WebInspector.NetworkLogView.FilterType.Scheme:
1549 return WebInspector.NetworkLogView._requestSchemeFilter.bind(null, v alue);
1550
1551 case WebInspector.NetworkLogView.FilterType.SetCookieDomain:
1552 return WebInspector.NetworkLogView._requestSetCookieDomainFilter.bin d(null, value);
1553
1554 case WebInspector.NetworkLogView.FilterType.SetCookieName:
1555 return WebInspector.NetworkLogView._requestSetCookieNameFilter.bind( null, value);
1556
1557 case WebInspector.NetworkLogView.FilterType.SetCookieValue:
1558 return WebInspector.NetworkLogView._requestSetCookieValueFilter.bind (null, value);
1559
1560 case WebInspector.NetworkLogView.FilterType.StatusCode:
1561 return WebInspector.NetworkLogView._statusCodeFilter.bind(null, valu e);
1562 }
1563 return null;
1564 },
1565
1566 _filterRequests: function()
1567 {
1568 this._removeAllHighlights();
1569 this._invalidateAllItems();
1570 this.refresh();
1571 },
1572
1573 jumpToPreviousSearchResult: function()
1574 {
1575 if (!this._matchedRequestCount)
1576 return;
1577 var index = this._normalizeSearchResultIndex(this._currentMatchedRequest Index - 1);
1578 this._highlightNthMatchedRequestForSearch(index, true);
1579 },
1580
1581 jumpToNextSearchResult: function()
1582 {
1583 if (!this._matchedRequestCount)
1584 return;
1585 var index = this._normalizeSearchResultIndex(this._currentMatchedRequest Index + 1);
1586 this._highlightNthMatchedRequestForSearch(index, true);
1587 },
1588
1589 searchCanceled: function()
1590 {
1591 delete this._searchRegExp;
1592 this._clearSearchMatchedList();
1593 this.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes.Sea rchCountUpdated, 0);
1594 },
1595
1596 /**
1597 * @param {!WebInspector.NetworkRequest} request
1598 */
1599 revealAndHighlightRequest: function(request)
1600 {
1601 this._removeAllNodeHighlights();
1602
1603 var node = this._nodesByRequestId.get(request.requestId);
1604 if (node) {
1605 node.reveal();
1606 this._highlightNode(node);
1607 }
1608 },
1609
1610 _removeAllNodeHighlights: function()
1611 {
1612 if (this._highlightedNode) {
1613 this._highlightedNode.element().classList.remove("highlighted-row");
1614 delete this._highlightedNode;
1615 }
1616 },
1617
1618 /**
1619 * @param {!WebInspector.NetworkDataGridNode} node
1620 */
1621 _highlightNode: function(node)
1622 {
1623 WebInspector.runCSSAnimationOnce(node.element(), "highlighted-row");
1624 this._highlightedNode = node;
1625 },
1626
1627 /**
1628 * @param {!WebInspector.NetworkRequest} request
1629 * @return {string}
1630 */
1631 _generateCurlCommand: function(request)
1632 {
1633 var command = ["curl"];
1634 // These headers are derived from URL (except "version") and would be ad ded by cURL anyway.
1635 var ignoredHeaders = {"host": 1, "method": 1, "path": 1, "scheme": 1, "v ersion": 1};
1636
1637 function escapeStringWin(str)
1638 {
1639 /* Replace quote by double quote (but not by \") because it is
1640 recognized by both cmd.exe and MS Crt arguments parser.
1641
1642 Replace % by "%" because it could be expanded to an environment
1643 variable value. So %% becomes "%""%". Even if an env variable ""
1644 (2 doublequotes) is declared, the cmd.exe will not
1645 substitute it with its value.
1646
1647 Replace each backslash with double backslash to make sure
1648 MS Crt arguments parser won't collapse them.
1649
1650 Replace new line outside of quotes since cmd.exe doesn't let
1651 to do it inside.
1652 */
1653 return "\"" + str.replace(/"/g, "\"\"")
1654 .replace(/%/g, "\"%\"")
1655 .replace(/\\/g, "\\\\")
1656 .replace(/[\r\n]+/g, "\"^$&\"") + "\"";
1657 }
1658
1659 function escapeStringPosix(str)
1660 {
1661 function escapeCharacter(x)
1662 {
1663 var code = x.charCodeAt(0);
1664 if (code < 256) {
1665 // Add leading zero when needed to not care about the next c haracter.
1666 return code < 16 ? "\\x0" + code.toString(16) : "\\x" + code .toString(16);
1667 }
1668 code = code.toString(16);
1669 return "\\u" + ("0000" + code).substr(code.length, 4);
1670 }
1671
1672 if (/[^\x20-\x7E]|\'/.test(str)) {
1673 // Use ANSI-C quoting syntax.
1674 return "$\'" + str.replace(/\\/g, "\\\\")
1675 .replace(/\'/g, "\\\'")
1676 .replace(/\n/g, "\\n")
1677 .replace(/\r/g, "\\r")
1678 .replace(/[^\x20-\x7E]/g, escapeCharacter) + " '";
1679 } else {
1680 // Use single quote syntax.
1681 return "'" + str + "'";
1682 }
1683 }
1684
1685 // cURL command expected to run on the same platform that DevTools run
1686 // (it may be different from the inspected page platform).
1687 var escapeString = WebInspector.isWin() ? escapeStringWin : escapeString Posix;
1688
1689 command.push(escapeString(request.url).replace(/[[{}\]]/g, "\\$&"));
1690
1691 var inferredMethod = "GET";
1692 var data = [];
1693 var requestContentType = request.requestContentType();
1694 if (requestContentType && requestContentType.startsWith("application/x-w ww-form-urlencoded") && request.requestFormData) {
1695 data.push("--data");
1696 data.push(escapeString(request.requestFormData));
1697 ignoredHeaders["content-length"] = true;
1698 inferredMethod = "POST";
1699 } else if (request.requestFormData) {
1700 data.push("--data-binary");
1701 data.push(escapeString(request.requestFormData));
1702 ignoredHeaders["content-length"] = true;
1703 inferredMethod = "POST";
1704 }
1705
1706 if (request.requestMethod !== inferredMethod) {
1707 command.push("-X");
1708 command.push(request.requestMethod);
1709 }
1710
1711 var requestHeaders = request.requestHeaders();
1712 for (var i = 0; i < requestHeaders.length; i++) {
1713 var header = requestHeaders[i];
1714 var name = header.name.replace(/^:/, ""); // Translate SPDY v3 heade rs to HTTP headers.
1715 if (name.toLowerCase() in ignoredHeaders)
1716 continue;
1717 command.push("-H");
1718 command.push(escapeString(name + ": " + header.value));
1719 }
1720 command = command.concat(data);
1721 command.push("--compressed");
1722 return command.join(" ");
1723 },
1724
1725 __proto__: WebInspector.VBox.prototype
1726 }
1727
1728 /** @typedef {function(!WebInspector.NetworkRequest): boolean} */
1729 WebInspector.NetworkLogView.Filter;
1730
1731 /**
1732 * @param {!WebInspector.NetworkLogView.Filter} filter
1733 * @param {!WebInspector.NetworkRequest} request
1734 * @return {boolean}
1735 */
1736 WebInspector.NetworkLogView._negativeFilter = function(filter, request)
1737 {
1738 return !filter(request);
1739 }
1740
1741 /**
1742 * @param {!RegExp} regex
1743 * @param {!WebInspector.NetworkRequest} request
1744 * @return {boolean}
1745 */
1746 WebInspector.NetworkLogView._requestNameOrPathFilter = function(regex, request)
1747 {
1748 return regex.test(request.name()) || regex.test(request.path());
1749 }
1750
1751 /**
1752 * @param {string} value
1753 * @param {!WebInspector.NetworkRequest} request
1754 * @return {boolean}
1755 */
1756 WebInspector.NetworkLogView._requestDomainFilter = function(value, request)
1757 {
1758 return request.domain === value;
1759 }
1760
1761 /**
1762 * @param {!WebInspector.NetworkRequest} request
1763 * @return {boolean}
1764 */
1765 WebInspector.NetworkLogView._runningRequestFilter = function(request)
1766 {
1767 return !request.finished;
1768 }
1769
1770 /**
1771 * @param {string} value
1772 * @param {!WebInspector.NetworkRequest} request
1773 * @return {boolean}
1774 */
1775 WebInspector.NetworkLogView._requestResponseHeaderFilter = function(value, reque st)
1776 {
1777 return request.responseHeaderValue(value) !== undefined;
1778 }
1779
1780 /**
1781 * @param {string} value
1782 * @param {!WebInspector.NetworkRequest} request
1783 * @return {boolean}
1784 */
1785 WebInspector.NetworkLogView._requestMethodFilter = function(value, request)
1786 {
1787 return request.requestMethod === value;
1788 }
1789
1790 /**
1791 * @param {string} value
1792 * @param {!WebInspector.NetworkRequest} request
1793 * @return {boolean}
1794 */
1795 WebInspector.NetworkLogView._requestMimeTypeFilter = function(value, request)
1796 {
1797 return request.mimeType === value;
1798 }
1799
1800 /**
1801 * @param {string} value
1802 * @param {!WebInspector.NetworkRequest} request
1803 * @return {boolean}
1804 */
1805 WebInspector.NetworkLogView._requestSchemeFilter = function(value, request)
1806 {
1807 return request.scheme === value;
1808 }
1809
1810 /**
1811 * @param {string} value
1812 * @param {!WebInspector.NetworkRequest} request
1813 * @return {boolean}
1814 */
1815 WebInspector.NetworkLogView._requestSetCookieDomainFilter = function(value, requ est)
1816 {
1817 var cookies = request.responseCookies;
1818 for (var i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
1819 if (cookies[i].domain() === value)
1820 return false;
1821 }
1822 return false;
1823 }
1824
1825 /**
1826 * @param {string} value
1827 * @param {!WebInspector.NetworkRequest} request
1828 * @return {boolean}
1829 */
1830 WebInspector.NetworkLogView._requestSetCookieNameFilter = function(value, reques t)
1831 {
1832 var cookies = request.responseCookies;
1833 for (var i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
1834 if (cookies[i].name() === value)
1835 return false;
1836 }
1837 return false;
1838 }
1839
1840 /**
1841 * @param {string} value
1842 * @param {!WebInspector.NetworkRequest} request
1843 * @return {boolean}
1844 */
1845 WebInspector.NetworkLogView._requestSetCookieValueFilter = function(value, reque st)
1846 {
1847 var cookies = request.responseCookies;
1848 for (var i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
1849 if (cookies[i].value() === value)
1850 return false;
1851 }
1852 return false;
1853 }
1854
1855 /**
1856 * @param {string} value
1857 * @param {!WebInspector.NetworkRequest} request
1858 * @return {boolean}
1859 */
1860 WebInspector.NetworkLogView._statusCodeFilter = function(value, request)
1861 {
1862 return ("" + request.statusCode) === value;
1863 }
1864
1865 /**
1866 * @param {!WebInspector.NetworkRequest} request
1867 * @return {boolean}
1868 */
1869 WebInspector.NetworkLogView.HTTPRequestsFilter = function(request)
1870 {
1871 return request.parsedURL.isValid && (request.scheme in WebInspector.NetworkL ogView.HTTPSchemas);
1872 }
1873
1874 /**
1875 * @param {!WebInspector.NetworkRequest} request
1876 * @return {boolean}
1877 */
1878 WebInspector.NetworkLogView.NonDevToolsRequestsFilter = function(request)
1879 {
1880 return !WebInspector.NetworkManager.hasDevToolsRequestHeader(request);
1881 }
1882
1883 /**
1884 * @param {!WebInspector.NetworkRequest} request
1885 * @return {boolean}
1886 */
1887 WebInspector.NetworkLogView.FinishedRequestsFilter = function(request)
1888 {
1889 return request.finished;
1890 }
1891
1892 WebInspector.NetworkLogView.EventTypes = {
1893 ViewCleared: "ViewCleared",
1894 RowSizeChanged: "RowSizeChanged",
1895 RequestSelected: "RequestSelected",
1896 SearchCountUpdated: "SearchCountUpdated",
1897 SearchIndexUpdated: "SearchIndexUpdated"
1898 };
1899
1900 /**
1901 * @constructor
33 * @implements {WebInspector.ContextMenu.Provider} 1902 * @implements {WebInspector.ContextMenu.Provider}
34 * @implements {WebInspector.Searchable} 1903 * @implements {WebInspector.Searchable}
35 * @extends {WebInspector.Panel} 1904 * @extends {WebInspector.Panel}
36 */ 1905 */
37 WebInspector.NetworkPanel = function() 1906 WebInspector.NetworkPanel = function()
38 { 1907 {
39 WebInspector.Panel.call(this, "network"); 1908 WebInspector.Panel.call(this, "network");
40 this.registerRequiredCSS("network/networkPanel.css"); 1909 this.registerRequiredCSS("network/networkPanel.css");
41 1910
42 this._panelStatusBarElement = this.element.createChild("div", "panel-status- bar"); 1911 this._panelStatusBarElement = this.element.createChild("div", "panel-status- bar");
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 _toggleGridMode: function() 2104 _toggleGridMode: function()
236 { 2105 {
237 if (this._viewingRequestMode) { 2106 if (this._viewingRequestMode) {
238 this._viewingRequestMode = false; 2107 this._viewingRequestMode = false;
239 this.element.classList.remove("viewing-resource"); 2108 this.element.classList.remove("viewing-resource");
240 this._splitView.hideMain(); 2109 this._splitView.hideMain();
241 } 2110 }
242 2111
243 this._networkLogView.switchViewMode(true); 2112 this._networkLogView.switchViewMode(true);
244 this._networkLogView.setAllowPopover(true); 2113 this._networkLogView.setAllowPopover(true);
2114 this._networkLogView._allowRequestSelection = false;
245 }, 2115 },
246 2116
247 _toggleViewingRequestMode: function() 2117 _toggleViewingRequestMode: function()
248 { 2118 {
249 if (this._viewingRequestMode) 2119 if (this._viewingRequestMode)
250 return; 2120 return;
251 this._viewingRequestMode = true; 2121 this._viewingRequestMode = true;
252 2122
253 this.element.classList.add("viewing-resource"); 2123 this.element.classList.add("viewing-resource");
254 this._splitView.showBoth(); 2124 this._splitView.showBoth();
255 this._networkLogView.setAllowPopover(false); 2125 this._networkLogView.setAllowPopover(false);
2126 this._networkLogView._allowRequestSelection = true;
256 this._networkLogView.switchViewMode(false); 2127 this._networkLogView.switchViewMode(false);
257 }, 2128 },
258 2129
259 /** 2130 /**
260 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig 2131 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig
261 * @param {boolean} shouldJump 2132 * @param {boolean} shouldJump
262 * @param {boolean=} jumpBackwards 2133 * @param {boolean=} jumpBackwards
263 */ 2134 */
264 performSearch: function(searchConfig, shouldJump, jumpBackwards) 2135 performSearch: function(searchConfig, shouldJump, jumpBackwards)
265 { 2136 {
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 * @return {number} 2593 * @return {number}
723 */ 2594 */
724 _upperBound: function(request) 2595 _upperBound: function(request)
725 { 2596 {
726 return request.duration; 2597 return request.duration;
727 }, 2598 },
728 2599
729 __proto__: WebInspector.NetworkTimeCalculator.prototype 2600 __proto__: WebInspector.NetworkTimeCalculator.prototype
730 } 2601 }
731 2602
2603 /**
2604 * @constructor
2605 * @extends {WebInspector.SortableDataGridNode}
2606 * @param {!WebInspector.NetworkLogView} parentView
2607 * @param {!WebInspector.NetworkRequest} request
2608 */
2609 WebInspector.NetworkDataGridNode = function(parentView, request)
2610 {
2611 WebInspector.SortableDataGridNode.call(this, {});
2612 this._parentView = parentView;
2613 this._request = request;
2614 this._linkifier = new WebInspector.Linkifier();
2615 this._isFilteredOut = true;
2616 this._isMatchingSearchQuery = false;
2617 this._staleGraph = true;
2618 }
2619
2620 WebInspector.NetworkDataGridNode._hoveredRowSymbol = Symbol("hoveredRow");
2621
2622 WebInspector.NetworkDataGridNode.prototype = {
2623 /**
2624 * @return {!WebInspector.NetworkRequest}
2625 */
2626 request: function()
2627 {
2628 return this._request;
2629 },
2630
2631 /**
2632 * @override
2633 * @return {number}
2634 */
2635 nodeSelfHeight: function()
2636 {
2637 return this._parentView.rowHeight();
2638 },
2639
2640 /** override */
2641 createCells: function()
2642 {
2643 this._nameCell = null;
2644 this._timelineCell = null;
2645 this._initiatorCell = null;
2646
2647 this._element.classList.toggle("network-error-row", this._isFailed());
2648 WebInspector.SortableDataGridNode.prototype.createCells.call(this);
2649
2650 this._updateGraph();
2651 },
2652
2653 /**
2654 * @override
2655 * @param {string} columnIdentifier
2656 * @return {!Element}
2657 */
2658 createCell: function(columnIdentifier)
2659 {
2660 var cell = this.createTD(columnIdentifier);
2661 switch (columnIdentifier) {
2662 case "name": this._renderNameCell(cell); break;
2663 case "timeline": this._createTimelineBar(cell); break;
2664 case "method": cell.setTextAndTitle(this._request.requestMethod); break;
2665 case "status": this._renderStatusCell(cell); break;
2666 case "scheme": cell.setTextAndTitle(this._request.scheme); break;
2667 case "domain": cell.setTextAndTitle(this._request.domain); break;
2668 case "remoteAddress": cell.setTextAndTitle(this._request.remoteAddress() ); break;
2669 case "cookies": cell.setTextAndTitle(this._arrayLength(this._request.req uestCookies)); break;
2670 case "setCookies": cell.setTextAndTitle(this._arrayLength(this._request. responseCookies)); break;
2671 case "connectionId": cell.setTextAndTitle(this._request.connectionId); b reak;
2672 case "type": cell.setTextAndTitle(this._request.mimeType || this._reques t.requestContentType() || ""); break;
2673 case "initiator": this._renderInitiatorCell(cell); break;
2674 case "size": this._renderSizeCell(cell); break;
2675 case "time": this._renderTimeCell(cell); break;
2676 default: cell.setTextAndTitle(this._request.responseHeaderValue(columnId entifier) || ""); break;
2677 }
2678
2679 return cell;
2680 },
2681
2682 /**
2683 * @param {?Array} array
2684 * @return {string}
2685 */
2686 _arrayLength: function(array)
2687 {
2688 return array ? "" + array.length : "";
2689 },
2690
2691 /**
2692 * @override
2693 * @protected
2694 */
2695 willAttach: function()
2696 {
2697 if (this._staleGraph)
2698 this._updateGraph();
2699 if (this._initiatorCell && this._request.initiatorInfo().type === WebIns pector.NetworkRequest.InitiatorType.Script)
2700 this._initiatorCell.insertBefore(this._linkifiedInitiatorAnchor, thi s._initiatorCell.firstChild);
2701 },
2702
2703 wasDetached: function()
2704 {
2705 if (this._linkifiedInitiatorAnchor)
2706 this._linkifiedInitiatorAnchor.remove();
2707 },
2708
2709 dispose: function()
2710 {
2711 this._linkifier.reset();
2712 },
2713
2714 _onClick: function()
2715 {
2716 if (!this._parentView.allowRequestSelection())
2717 this.select();
2718 },
2719
2720 select: function()
2721 {
2722 this._parentView.dispatchEventToListeners(WebInspector.NetworkLogView.Ev entTypes.RequestSelected, this._request);
2723 WebInspector.SortableDataGridNode.prototype.select.apply(this, arguments );
2724
2725 WebInspector.notifications.dispatchEventToListeners(WebInspector.UserMet rics.UserAction, {
2726 action: WebInspector.UserMetrics.UserActionNames.NetworkRequestSelec ted,
2727 url: this._request.url
2728 });
2729 },
2730
2731 /**
2732 * @param {!RegExp=} regexp
2733 * @return {!Array.<!Object>}
2734 */
2735 highlightMatchedSubstring: function(regexp)
2736 {
2737 // Ensure element is created.
2738 this.element();
2739 var domChanges = [];
2740 var matchInfo = this._nameCell.textContent.match(regexp);
2741 if (matchInfo)
2742 WebInspector.highlightSearchResult(this._nameCell, matchInfo.index, matchInfo[0].length, domChanges);
2743 return domChanges;
2744 },
2745
2746 _openInNewTab: function()
2747 {
2748 InspectorFrontendHost.openInNewTab(this._request.url);
2749 },
2750
2751 get selectable()
2752 {
2753 return this._parentView.allowRequestSelection();
2754 },
2755
2756 /**
2757 * @param {!Element} cell
2758 */
2759 _createTimelineBar: function(cell)
2760 {
2761 cell = cell.createChild("div");
2762 this._timelineCell = cell;
2763
2764 cell.className = "network-graph-side";
2765
2766 this._barAreaElement = cell.createChild("div", "network-graph-bar-area") ;
2767 this._barAreaElement.request = this._request;
2768
2769 var type = this._request.resourceType().name();
2770 var cached = this._request.cached();
2771
2772 this._barLeftElement = this._barAreaElement.createChild("div", "network- graph-bar");
2773 this._barLeftElement.classList.add(type, "waiting");
2774 this._barLeftElement.classList.toggle("cached", cached);
2775
2776 this._barRightElement = this._barAreaElement.createChild("div", "network -graph-bar");
2777 this._barRightElement.classList.add(type);
2778 this._barRightElement.classList.toggle("cached", cached);
2779
2780 this._labelLeftElement = this._barAreaElement.createChild("div", "networ k-graph-label");
2781 this._labelLeftElement.classList.add("waiting");
2782
2783 this._labelRightElement = this._barAreaElement.createChild("div", "netwo rk-graph-label");
2784
2785 cell.addEventListener("mouseover", this._onMouseOver.bind(this), false);
2786 },
2787
2788 /**
2789 * @param {!Event} event
2790 */
2791 _onMouseOver: function(event)
2792 {
2793 this._refreshLabelPositions();
2794 this._parentView[WebInspector.NetworkDataGridNode._hoveredRowSymbol] = t his;
2795 },
2796
2797 /**
2798 * @return {boolean}
2799 */
2800 _isFailed: function()
2801 {
2802 return (this._request.failed && !this._request.statusCode) || (this._req uest.statusCode >= 400);
2803 },
2804
2805 /**
2806 * @param {!Element} cell
2807 */
2808 _renderNameCell: function(cell)
2809 {
2810 this._nameCell = cell;
2811 cell.addEventListener("click", this._onClick.bind(this), false);
2812 cell.addEventListener("dblclick", this._openInNewTab.bind(this), false);
2813 var iconElement;
2814 if (this._request.resourceType() === WebInspector.resourceTypes.Image) {
2815 var previewImage = createElementWithClass("img", "image-network-icon -preview");
2816 this._request.populateImageSource(previewImage);
2817
2818 iconElement = createElementWithClass("div", "icon");
2819 iconElement.appendChild(previewImage);
2820 } else {
2821 iconElement = createElementWithClass("img", "icon");
2822 }
2823 iconElement.classList.add(this._request.resourceType().name());
2824
2825 cell.appendChild(iconElement);
2826 cell.createTextChild(this._request.name());
2827 this._appendSubtitle(cell, this._request.path());
2828 cell.title = this._request.url;
2829 },
2830
2831 /**
2832 * @param {!Element} cell
2833 */
2834 _renderStatusCell: function(cell)
2835 {
2836 cell.classList.toggle("network-dim-cell", !this._isFailed() && (this._re quest.cached() || !this._request.statusCode));
2837
2838 if (this._request.failed && !this._request.canceled) {
2839 var failText = WebInspector.UIString("(failed)");
2840 if (this._request.localizedFailDescription) {
2841 cell.createTextChild(failText);
2842 this._appendSubtitle(cell, this._request.localizedFailDescriptio n);
2843 cell.title = failText + " " + this._request.localizedFailDescrip tion;
2844 } else
2845 cell.setTextAndTitle(failText);
2846 } else if (this._request.statusCode) {
2847 cell.createTextChild("" + this._request.statusCode);
2848 this._appendSubtitle(cell, this._request.statusText);
2849 cell.title = this._request.statusCode + " " + this._request.statusTe xt;
2850 } else if (this._request.parsedURL.isDataURL()) {
2851 cell.setTextAndTitle(WebInspector.UIString("(data)"));
2852 } else if (this._request.canceled) {
2853 cell.setTextAndTitle(WebInspector.UIString("(canceled)"));
2854 } else if (this._request.finished) {
2855 cell.setTextAndTitle(WebInspector.UIString("Finished"));
2856 } else {
2857 cell.setTextAndTitle(WebInspector.UIString("(pending)"));
2858 }
2859 },
2860
2861 /**
2862 * @param {!Element} cell
2863 */
2864 _renderInitiatorCell: function(cell)
2865 {
2866 this._initiatorCell = cell;
2867 var request = this._request;
2868 var initiator = request.initiatorInfo();
2869
2870 switch (initiator.type) {
2871 case WebInspector.NetworkRequest.InitiatorType.Parser:
2872 cell.title = initiator.url + ":" + initiator.lineNumber;
2873 cell.appendChild(WebInspector.linkifyResourceAsNode(initiator.url, i nitiator.lineNumber - 1));
2874 this._appendSubtitle(cell, WebInspector.UIString("Parser"));
2875 break;
2876
2877 case WebInspector.NetworkRequest.InitiatorType.Redirect:
2878 cell.title = initiator.url;
2879 console.assert(request.redirectSource);
2880 var redirectSource = /** @type {!WebInspector.NetworkRequest} */ (re quest.redirectSource);
2881 cell.appendChild(WebInspector.linkifyRequestAsNode(redirectSource));
2882 this._appendSubtitle(cell, WebInspector.UIString("Redirect"));
2883 break;
2884
2885 case WebInspector.NetworkRequest.InitiatorType.Script:
2886 if (!this._linkifiedInitiatorAnchor) {
2887 this._linkifiedInitiatorAnchor = this._linkifier.linkifyScriptLo cation(request.target(), null, initiator.url, initiator.lineNumber - 1, initiato r.columnNumber - 1);
2888 this._linkifiedInitiatorAnchor.title = "";
2889 }
2890 cell.appendChild(this._linkifiedInitiatorAnchor);
2891 this._appendSubtitle(cell, WebInspector.UIString("Script"));
2892 cell.classList.add("network-script-initiated");
2893 cell.request = request;
2894 break;
2895
2896 default:
2897 cell.title = "";
2898 cell.classList.add("network-dim-cell");
2899 cell.setTextAndTitle(WebInspector.UIString("Other"));
2900 }
2901 },
2902
2903 /**
2904 * @param {!Element} cell
2905 */
2906 _renderSizeCell: function(cell)
2907 {
2908 if (this._request.fetchedViaServiceWorker) {
2909 cell.setTextAndTitle(WebInspector.UIString("(from ServiceWorker)"));
2910 cell.classList.add("network-dim-cell");
2911 } else if (this._request.cached()) {
2912 cell.setTextAndTitle(WebInspector.UIString("(from cache)"));
2913 cell.classList.add("network-dim-cell");
2914 } else {
2915 var resourceSize = Number.bytesToString(this._request.resourceSize);
2916 var transferSize = Number.bytesToString(this._request.transferSize);
2917 cell.setTextAndTitle(transferSize);
2918 this._appendSubtitle(cell, resourceSize);
2919 }
2920 },
2921
2922 /**
2923 * @param {!Element} cell
2924 */
2925 _renderTimeCell: function(cell)
2926 {
2927 if (this._request.duration > 0) {
2928 cell.setTextAndTitle(Number.secondsToString(this._request.duration)) ;
2929 this._appendSubtitle(cell, Number.secondsToString(this._request.late ncy));
2930 } else {
2931 cell.classList.add("network-dim-cell");
2932 cell.setTextAndTitle(WebInspector.UIString("Pending"));
2933 }
2934 },
2935
2936 /**
2937 * @param {!Element} cellElement
2938 * @param {string} subtitleText
2939 */
2940 _appendSubtitle: function(cellElement, subtitleText)
2941 {
2942 var subtitleElement = createElement("div");
2943 subtitleElement.className = "network-cell-subtitle";
2944 subtitleElement.textContent = subtitleText;
2945 cellElement.appendChild(subtitleElement);
2946 },
2947
2948 refreshGraph: function()
2949 {
2950 if (!this._timelineCell)
2951 return;
2952 this._staleGraph = true;
2953 if (this.attached())
2954 this.dataGrid.scheduleUpdate();
2955 },
2956
2957 _updateGraph: function()
2958 {
2959 this._staleGraph = false;
2960 if (!this._timelineCell)
2961 return;
2962
2963 var calculator = this._parentView.calculator();
2964 var percentages = calculator.computeBarGraphPercentages(this._request);
2965 this._percentages = percentages;
2966
2967 this._barAreaElement.classList.remove("hidden");
2968
2969 this._barLeftElement.style.setProperty("left", percentages.start + "%");
2970 this._barLeftElement.style.setProperty("right", (100 - percentages.middl e) + "%");
2971
2972 this._barRightElement.style.setProperty("left", percentages.middle + "%" );
2973 this._barRightElement.style.setProperty("right", (100 - percentages.end) + "%");
2974
2975 var labels = calculator.computeBarGraphLabels(this._request);
2976 this._labelLeftElement.textContent = labels.left;
2977 this._labelRightElement.textContent = labels.right;
2978
2979 var tooltip = (labels.tooltip || "");
2980 this._barLeftElement.title = tooltip;
2981 this._labelLeftElement.title = tooltip;
2982 this._labelRightElement.title = tooltip;
2983 this._barRightElement.title = tooltip;
2984
2985 if (this._parentView[WebInspector.NetworkDataGridNode._hoveredRowSymbol] === this)
2986 this._refreshLabelPositions();
2987 },
2988
2989 _refreshLabelPositions: function()
2990 {
2991 if (!this._percentages)
2992 return;
2993 this._labelLeftElement.style.removeProperty("left");
2994 this._labelLeftElement.style.removeProperty("right");
2995 this._labelLeftElement.classList.remove("before");
2996 this._labelLeftElement.classList.remove("hidden");
2997
2998 this._labelRightElement.style.removeProperty("left");
2999 this._labelRightElement.style.removeProperty("right");
3000 this._labelRightElement.classList.remove("after");
3001 this._labelRightElement.classList.remove("hidden");
3002
3003 const labelPadding = 10;
3004 const barRightElementOffsetWidth = this._barRightElement.offsetWidth;
3005 const barLeftElementOffsetWidth = this._barLeftElement.offsetWidth;
3006
3007 if (this._barLeftElement) {
3008 var leftBarWidth = barLeftElementOffsetWidth - labelPadding;
3009 var rightBarWidth = (barRightElementOffsetWidth - barLeftElementOffs etWidth) - labelPadding;
3010 } else {
3011 var leftBarWidth = (barLeftElementOffsetWidth - barRightElementOffse tWidth) - labelPadding;
3012 var rightBarWidth = barRightElementOffsetWidth - labelPadding;
3013 }
3014
3015 const labelLeftElementOffsetWidth = this._labelLeftElement.offsetWidth;
3016 const labelRightElementOffsetWidth = this._labelRightElement.offsetWidth ;
3017
3018 const labelBefore = (labelLeftElementOffsetWidth > leftBarWidth);
3019 const labelAfter = (labelRightElementOffsetWidth > rightBarWidth);
3020 const graphElementOffsetWidth = this._timelineCell.offsetWidth;
3021
3022 if (labelBefore && (graphElementOffsetWidth * (this._percentages.start / 100)) < (labelLeftElementOffsetWidth + 10))
3023 var leftHidden = true;
3024
3025 if (labelAfter && (graphElementOffsetWidth * ((100 - this._percentages.e nd) / 100)) < (labelRightElementOffsetWidth + 10))
3026 var rightHidden = true;
3027
3028 if (barLeftElementOffsetWidth == barRightElementOffsetWidth) {
3029 // The left/right label data are the same, so a before/after label c an be replaced by an on-bar label.
3030 if (labelBefore && !labelAfter)
3031 leftHidden = true;
3032 else if (labelAfter && !labelBefore)
3033 rightHidden = true;
3034 }
3035
3036 if (labelBefore) {
3037 if (leftHidden)
3038 this._labelLeftElement.classList.add("hidden");
3039 this._labelLeftElement.style.setProperty("right", (100 - this._perce ntages.start) + "%");
3040 this._labelLeftElement.classList.add("before");
3041 } else {
3042 this._labelLeftElement.style.setProperty("left", this._percentages.s tart + "%");
3043 this._labelLeftElement.style.setProperty("right", (100 - this._perce ntages.middle) + "%");
3044 }
3045
3046 if (labelAfter) {
3047 if (rightHidden)
3048 this._labelRightElement.classList.add("hidden");
3049 this._labelRightElement.style.setProperty("left", this._percentages. end + "%");
3050 this._labelRightElement.classList.add("after");
3051 } else {
3052 this._labelRightElement.style.setProperty("left", this._percentages. middle + "%");
3053 this._labelRightElement.style.setProperty("right", (100 - this._perc entages.end) + "%");
3054 }
3055 },
3056
3057 __proto__: WebInspector.SortableDataGridNode.prototype
3058 }
3059
3060 /**
3061 * @param {!WebInspector.NetworkDataGridNode} a
3062 * @param {!WebInspector.NetworkDataGridNode} b
3063 * @return {number}
3064 */
3065 WebInspector.NetworkDataGridNode.NameComparator = function(a, b)
3066 {
3067 var aFileName = a._request.name();
3068 var bFileName = b._request.name();
3069 if (aFileName > bFileName)
3070 return 1;
3071 if (bFileName > aFileName)
3072 return -1;
3073 return a._request.indentityCompare(b._request);
3074 }
3075
3076 /**
3077 * @param {!WebInspector.NetworkDataGridNode} a
3078 * @param {!WebInspector.NetworkDataGridNode} b
3079 * @return {number}
3080 */
3081 WebInspector.NetworkDataGridNode.RemoteAddressComparator = function(a, b)
3082 {
3083 var aRemoteAddress = a._request.remoteAddress();
3084 var bRemoteAddress = b._request.remoteAddress();
3085 if (aRemoteAddress > bRemoteAddress)
3086 return 1;
3087 if (bRemoteAddress > aRemoteAddress)
3088 return -1;
3089 return a._request.indentityCompare(b._request);
3090 }
3091
3092 /**
3093 * @param {!WebInspector.NetworkDataGridNode} a
3094 * @param {!WebInspector.NetworkDataGridNode} b
3095 * @return {number}
3096 */
3097 WebInspector.NetworkDataGridNode.SizeComparator = function(a, b)
3098 {
3099 if (b._request.cached() && !a._request.cached())
3100 return 1;
3101 if (a._request.cached() && !b._request.cached())
3102 return -1;
3103 return (a._request.transferSize - b._request.transferSize) || a._request.ind entityCompare(b._request);
3104 }
3105
3106 /**
3107 * @param {!WebInspector.NetworkDataGridNode} a
3108 * @param {!WebInspector.NetworkDataGridNode} b
3109 * @return {number}
3110 */
3111 WebInspector.NetworkDataGridNode.InitiatorComparator = function(a, b)
3112 {
3113 var aInitiator = a._request.initiatorInfo();
3114 var bInitiator = b._request.initiatorInfo();
3115
3116 if (aInitiator.type < bInitiator.type)
3117 return -1;
3118 if (aInitiator.type > bInitiator.type)
3119 return 1;
3120
3121 if (typeof aInitiator.__source === "undefined")
3122 aInitiator.__source = WebInspector.displayNameForURL(aInitiator.url);
3123 if (typeof bInitiator.__source === "undefined")
3124 bInitiator.__source = WebInspector.displayNameForURL(bInitiator.url);
3125
3126 if (aInitiator.__source < bInitiator.__source)
3127 return -1;
3128 if (aInitiator.__source > bInitiator.__source)
3129 return 1;
3130
3131 if (aInitiator.lineNumber < bInitiator.lineNumber)
3132 return -1;
3133 if (aInitiator.lineNumber > bInitiator.lineNumber)
3134 return 1;
3135
3136 if (aInitiator.columnNumber < bInitiator.columnNumber)
3137 return -1;
3138 if (aInitiator.columnNumber > bInitiator.columnNumber)
3139 return 1;
3140
3141 return a._request.indentityCompare(b._request);
3142 }
3143
3144 /**
3145 * @param {!WebInspector.NetworkDataGridNode} a
3146 * @param {!WebInspector.NetworkDataGridNode} b
3147 * @return {number}
3148 */
3149 WebInspector.NetworkDataGridNode.RequestCookiesCountComparator = function(a, b)
3150 {
3151 var aScore = a._request.requestCookies ? a._request.requestCookies.length : 0;
3152 var bScore = b._request.requestCookies ? b._request.requestCookies.length : 0;
3153 return (aScore - bScore) || a._request.indentityCompare(b._request);
3154 }
3155
3156 /**
3157 * @param {!WebInspector.NetworkDataGridNode} a
3158 * @param {!WebInspector.NetworkDataGridNode} b
3159 * @return {number}
3160 */
3161 WebInspector.NetworkDataGridNode.ResponseCookiesCountComparator = function(a, b)
3162 {
3163 var aScore = a._request.responseCookies ? a._request.responseCookies.length : 0;
3164 var bScore = b._request.responseCookies ? b._request.responseCookies.length : 0;
3165 return (aScore - bScore) || a._request.indentityCompare(b._request);
3166 }
3167
3168 /**
3169 * @param {string} propertyName
3170 * @param {boolean} revert
3171 * @param {!WebInspector.NetworkDataGridNode} a
3172 * @param {!WebInspector.NetworkDataGridNode} b
3173 * @return {number}
3174 */
3175 WebInspector.NetworkDataGridNode.RequestPropertyComparator = function(propertyNa me, revert, a, b)
3176 {
3177 var aValue = a._request[propertyName];
3178 var bValue = b._request[propertyName];
3179 if (aValue > bValue)
3180 return revert ? -1 : 1;
3181 if (bValue > aValue)
3182 return revert ? 1 : -1;
3183 return a._request.indentityCompare(b._request);
3184 }
3185
732 WebInspector.NetworkPanel.show = function() 3186 WebInspector.NetworkPanel.show = function()
733 { 3187 {
734 WebInspector.inspectorView.setCurrentPanel(WebInspector.NetworkPanel._instan ce()); 3188 WebInspector.inspectorView.setCurrentPanel(WebInspector.NetworkPanel._instan ce());
735 } 3189 }
736 3190
737 /** 3191 /**
738 * @return {!WebInspector.NetworkPanel} 3192 * @return {!WebInspector.NetworkPanel}
739 */ 3193 */
740 WebInspector.NetworkPanel._instance = function() 3194 WebInspector.NetworkPanel._instance = function()
741 { 3195 {
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 this._writeProgress.done(); 3302 this._writeProgress.done();
849 return; 3303 return;
850 } 3304 }
851 const chunkSize = 100000; 3305 const chunkSize = 100000;
852 var text = this._text.substring(this._bytesWritten, this._bytesWritten + chunkSize); 3306 var text = this._text.substring(this._bytesWritten, this._bytesWritten + chunkSize);
853 this._bytesWritten += text.length; 3307 this._bytesWritten += text.length;
854 stream.write(text, this._writeNextChunk.bind(this)); 3308 stream.write(text, this._writeNextChunk.bind(this));
855 this._writeProgress.setWorked(this._bytesWritten); 3309 this._writeProgress.setWorked(this._bytesWritten);
856 } 3310 }
857 } 3311 }
OLDNEW
« no previous file with comments | « Source/devtools/front_end/network/NetworkLogView.js ('k') | Source/devtools/front_end/network/module.json » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698