| Index: third_party/WebKit/Source/devtools/front_end/network/NetworkLogView.js
|
| diff --git a/third_party/WebKit/Source/devtools/front_end/network/NetworkLogView.js b/third_party/WebKit/Source/devtools/front_end/network/NetworkLogView.js
|
| index 94e5a12bd03adc9f4e0b3d4006fda86f79eb30c8..9bc25e2dd7a2b13d1e19418f5e1726090404c029 100644
|
| --- a/third_party/WebKit/Source/devtools/front_end/network/NetworkLogView.js
|
| +++ b/third_party/WebKit/Source/devtools/front_end/network/NetworkLogView.js
|
| @@ -80,16 +80,19 @@ Network.NetworkLogView = class extends UI.VBox {
|
| /** @type {number} */
|
| this._mainRequestDOMContentLoadedTime = -1;
|
| this._matchedRequestCount = 0;
|
| + /** @type {!Array<!Array<!Object>>} */
|
| this._highlightedSubstringChanges = [];
|
|
|
| /** @type {!Array.<!Network.NetworkLogView.Filter>} */
|
| this._filters = [];
|
| /** @type {?Network.NetworkLogView.Filter} */
|
| this._timeFilter = null;
|
| + /** @type {?Network.NetworkDataGridNode} */
|
| this._hoveredNode = null;
|
|
|
| - this._currentMatchedRequestNode = null;
|
| - this._currentMatchedRequestIndex = -1;
|
| + /** @type {?Network.NetworkDataGridNode} */
|
| + this._currentMatchedNode = null;
|
| + this._currentMatchedNodeIndex = -1;
|
|
|
| /** @type {!Components.Linkifier} */
|
| this.linkifier = new Components.Linkifier();
|
| @@ -506,8 +509,9 @@ Network.NetworkLogView = class extends UI.VBox {
|
| _setupDataGrid() {
|
| /** @type {!UI.SortableDataGrid} */
|
| this._dataGrid = this._columns.dataGrid();
|
| + var contextHandler = this.handleContextMenuForNode.bind(this);
|
| this._dataGrid.setRowContextMenuCallback(
|
| - (contextMenu, node) => this.handleContextMenuForRequest(contextMenu, node.request()));
|
| + (contextMenu, node) => contextHandler(contextMenu, /** @type {!Network.NetworkDataGridNode} */ (node)));
|
| this._dataGrid.setStickToBottom(true);
|
| this._dataGrid.setName('networkLog');
|
| this._dataGrid.setResizeMethod(UI.DataGrid.ResizeMethod.Last);
|
| @@ -525,6 +529,7 @@ Network.NetworkLogView = class extends UI.VBox {
|
| this._dataGrid.dataGridNodeFromNode(/** @type {!Node} */ (event.target)));
|
| var highlightInitiatorChain = event.shiftKey;
|
| this._setHoveredNode(node, highlightInitiatorChain);
|
| + // TODO(allada) Support groupping initiator chain instead of first request.
|
| this._highlightInitiatorChain((highlightInitiatorChain && node) ? node.request() : null);
|
| }
|
|
|
| @@ -567,6 +572,7 @@ Network.NetworkLogView = class extends UI.VBox {
|
| * @param {?SDK.NetworkRequest} request
|
| */
|
| _highlightInitiatorChain(request) {
|
| + // TODO(allada) This should be converted into Node instead of request.
|
| if (this._requestWithHighlightedInitiators === request)
|
| return;
|
| this._requestWithHighlightedInitiators = request;
|
| @@ -784,8 +790,15 @@ Network.NetworkLogView = class extends UI.VBox {
|
| /**
|
| * @return {!Array<!Network.NetworkDataGridNode>}
|
| */
|
| - flatNodesList() {
|
| - return this._dataGrid.rootNode().flattenChildren();
|
| + flattenVisibleNodes() {
|
| + return /** @type {!Array<!Network.NetworkDataGridNode>} */ (this._dataGrid.rootNode().flattenChildren());
|
| + }
|
| +
|
| + /**
|
| + * @return {!Array<!Network.NetworkDataGridNode>}
|
| + */
|
| + flattenAllNodes() {
|
| + return /** @type {!Array<!Network.NetworkDataGridNode>} */ (this._dataGrid.rootNode().flattenChildren(true));
|
| }
|
|
|
| _refresh() {
|
| @@ -833,18 +846,21 @@ Network.NetworkLogView = class extends UI.VBox {
|
| this._durationCalculator.updateBoundaries(request);
|
| }
|
|
|
| - for (var i = 0; i < nodesToInsert.length; ++i) {
|
| - var node = nodesToInsert[i];
|
| - var request = node.request();
|
| + for (var node of nodesToInsert) {
|
| dataGrid.insertChild(node);
|
| - node[Network.NetworkLogView._isMatchingSearchQuerySymbol] = this._matchRequest(request);
|
| + var matched = this._nodeHasDirectMatch(node);
|
| + node[Network.NetworkLogView._isMatchingSearchQuerySymbol] = matched;
|
| + var parent = /** @type {?Network.NetworkDataGridNode} */ (node.parent);
|
| + while (matched && parent && !parent[Network.NetworkLogView._isMatchingSearchQuerySymbol]) {
|
| + parent[Network.NetworkLogView._isMatchingSearchQuerySymbol] = true;
|
| + parent = /** @type {?Network.NetworkDataGridNode} */ (parent.parent);
|
| + }
|
| }
|
|
|
| for (var node of nodesToRefresh)
|
| node.refresh();
|
|
|
| - this._highlightNthMatchedRequestForSearch(
|
| - this._updateMatchCountAndFindMatchIndex(this._currentMatchedRequestNode), false);
|
| + this._highlightNthMatchedNodeForSearch(this._updateMatchCountAndFindMatchIndex(this._currentMatchedNode), false);
|
|
|
| this._staleRequestIds = {};
|
| this._updateSummaryBar();
|
| @@ -914,15 +930,15 @@ Network.NetworkLogView = class extends UI.VBox {
|
| // In case of redirect request id is reassigned to a redirected
|
| // request and we need to update _nodesByRequestId and search results.
|
| var originalRequestNode = this._nodesByRequestId.get(request.requestId);
|
| - if (originalRequestNode)
|
| - this._nodesByRequestId.set(originalRequestNode.request().requestId, originalRequestNode);
|
| + var originalRequest = originalRequestNode ? originalRequestNode.request() : null;
|
| + if (originalRequest)
|
| + this._nodesByRequestId.set(originalRequest.requestId, originalRequestNode);
|
| +
|
| this._nodesByRequestId.set(request.requestId, node);
|
|
|
| // Pull all the redirects of the main request upon commit load.
|
| - if (request.redirects) {
|
| - for (var i = 0; i < request.redirects.length; ++i)
|
| - this._refreshRequest(request.redirects[i]);
|
| - }
|
| + if (request.redirects)
|
| + request.redirects.forEach(this._refreshRequest.bind(this));
|
|
|
| this._refreshRequest(request);
|
| }
|
| @@ -1033,9 +1049,13 @@ Network.NetworkLogView = class extends UI.VBox {
|
|
|
| /**
|
| * @param {!UI.ContextMenu} contextMenu
|
| - * @param {!SDK.NetworkRequest} request
|
| + * @param {!Network.NetworkDataGridNode} node
|
| */
|
| - handleContextMenuForRequest(contextMenu, request) {
|
| + handleContextMenuForNode(contextMenu, node) {
|
| + // TODO(allada) Support groupped items context menu.
|
| + var request = node.request();
|
| + if (!request)
|
| + return;
|
| contextMenu.appendApplicableItems(request);
|
| var copyMenu = contextMenu.appendSubMenuItem(Common.UIString('Copy'));
|
| if (request) {
|
| @@ -1104,11 +1124,15 @@ Network.NetworkLogView = class extends UI.VBox {
|
| }
|
| }
|
|
|
| + /**
|
| + * @return {!Array<!SDK.NetworkRequest>}
|
| + */
|
| + _allRequests() {
|
| + return this.flattenAllNodes().map(node => node.request()).filter(request => !!request);
|
| + }
|
| +
|
| _harRequests() {
|
| - var requests = this._nodesByRequestId.valuesArray().map(function(node) {
|
| - return node.request();
|
| - });
|
| - var httpRequests = requests.filter(Network.NetworkLogView.HTTPRequestsFilter);
|
| + var httpRequests = this._allRequests().filter(Network.NetworkLogView.HTTPRequestsFilter);
|
| return httpRequests.filter(Network.NetworkLogView.FinishedRequestsFilter);
|
| }
|
|
|
| @@ -1151,17 +1175,14 @@ Network.NetworkLogView = class extends UI.VBox {
|
| * @param {string} platform
|
| */
|
| _copyCurlCommand(request, platform) {
|
| - InspectorFrontendHost.copyText(this._generateCurlCommand(request, platform));
|
| + InspectorFrontendHost.copyText(this._generateCurlCommand(platform, request));
|
| }
|
|
|
| /**
|
| * @param {string} platform
|
| */
|
| _copyAllCurlCommand(platform) {
|
| - var requests = this._nodesByRequestId.valuesArray().map(node => node.request());
|
| - var commands = [];
|
| - for (var request of requests)
|
| - commands.push(this._generateCurlCommand(request, platform));
|
| + var commands = this._allRequests().map(this._generateCurlCommand.bind(this, platform));
|
| if (platform === 'win')
|
| InspectorFrontendHost.copyText(commands.join(' &\r\n'));
|
| else
|
| @@ -1200,21 +1221,24 @@ Network.NetworkLogView = class extends UI.VBox {
|
| }
|
|
|
| /**
|
| - * @param {!SDK.NetworkRequest} request
|
| + * @param {!Network.NetworkDataGridNode} node
|
| * @return {boolean}
|
| */
|
| - _matchRequest(request) {
|
| + _nodeHasDirectMatch(node) {
|
| var re = this._searchRegex;
|
| if (!re)
|
| return false;
|
|
|
| + var request = node.request();
|
| var text = this._networkLogLargeRowsSetting.get() ? request.path() + '/' + request.name() : request.name();
|
| - return re.test(text);
|
| + if (re.test(text))
|
| + return true;
|
| + return false;
|
| }
|
|
|
| _clearSearchMatchedList() {
|
| this._matchedRequestCount = -1;
|
| - this._currentMatchedRequestNode = null;
|
| + this._currentMatchedNode = null;
|
| this._removeAllHighlights();
|
| }
|
|
|
| @@ -1226,43 +1250,41 @@ Network.NetworkLogView = class extends UI.VBox {
|
| }
|
|
|
| dataGridSorted() {
|
| - this._highlightNthMatchedRequestForSearch(
|
| - this._updateMatchCountAndFindMatchIndex(this._currentMatchedRequestNode), false);
|
| + this._highlightNthMatchedNodeForSearch(this._updateMatchCountAndFindMatchIndex(this._currentMatchedNode), false);
|
| }
|
|
|
| /**
|
| * @param {number} n
|
| * @param {boolean} reveal
|
| */
|
| - _highlightNthMatchedRequestForSearch(n, reveal) {
|
| + _highlightNthMatchedNodeForSearch(n, reveal) {
|
| this._removeAllHighlights();
|
|
|
| - /** @type {!Array.<!Network.NetworkDataGridNode>} */
|
| - var nodes = this._dataGrid.rootNode().children;
|
| var matchCount = 0;
|
| + var request = null;
|
| var node = null;
|
| - for (var i = 0; i < nodes.length; ++i) {
|
| - if (nodes[i][Network.NetworkLogView._isMatchingSearchQuerySymbol]) {
|
| - if (matchCount === n) {
|
| - node = nodes[i];
|
| - break;
|
| - }
|
| - matchCount++;
|
| + for (node of this.flattenAllNodes()) {
|
| + if (!node[Network.NetworkLogView._isMatchingSearchQuerySymbol])
|
| + continue;
|
| + if (matchCount === n) {
|
| + // TODO(allada) This should support multiple requests.
|
| + request = node.request();
|
| + break;
|
| }
|
| + matchCount++;
|
| }
|
| - if (!node) {
|
| - this._currentMatchedRequestNode = null;
|
| + if (!request || !node) {
|
| + this._currentMatchedNode = null;
|
| return;
|
| }
|
|
|
| - var request = node.request();
|
| if (reveal)
|
| Common.Revealer.reveal(request);
|
| var highlightedSubstringChanges = node.highlightMatchedSubstring(this._searchRegex);
|
| this._highlightedSubstringChanges.push(highlightedSubstringChanges);
|
|
|
| - this._currentMatchedRequestNode = node;
|
| - this._currentMatchedRequestIndex = n;
|
| + this._currentMatchedNode = node;
|
| + this._currentMatchedNodeIndex = n;
|
| this.dispatchEventToListeners(Network.NetworkLogView.Events.SearchIndexUpdated, n);
|
| }
|
|
|
| @@ -1274,18 +1296,25 @@ Network.NetworkLogView = class extends UI.VBox {
|
| */
|
| performSearch(searchConfig, shouldJump, jumpBackwards) {
|
| var query = searchConfig.query;
|
| - var currentMatchedRequestNode = this._currentMatchedRequestNode;
|
| + var currentMatchedNode = this._currentMatchedNode;
|
| this._clearSearchMatchedList();
|
| this._searchRegex = createPlainTextSearchRegex(query, 'i');
|
|
|
| - /** @type {!Array.<!Network.NetworkDataGridNode>} */
|
| - var nodes = this._dataGrid.rootNode().children;
|
| - for (var i = 0; i < nodes.length; ++i)
|
| - nodes[i][Network.NetworkLogView._isMatchingSearchQuerySymbol] = this._matchRequest(nodes[i].request());
|
| - var newMatchedRequestIndex = this._updateMatchCountAndFindMatchIndex(currentMatchedRequestNode);
|
| - if (!newMatchedRequestIndex && jumpBackwards)
|
| - newMatchedRequestIndex = this._matchedRequestCount - 1;
|
| - this._highlightNthMatchedRequestForSearch(newMatchedRequestIndex, shouldJump);
|
| + var node = this._dataGrid.rootNode();
|
| + while ((node = /** @type {?Network.NetworkDataGridNode} */ (node.traverseNextNode(false)))) {
|
| + var matched = this._nodeHasDirectMatch(node);
|
| + node[Network.NetworkLogView._isMatchingSearchQuerySymbol] = matched;
|
| + var parent = /** @type {?Network.NetworkDataGridNode} */ (node.parent);
|
| + while (matched && parent && parent[Network.NetworkLogView._isMatchingSearchQuerySymbol] === false) {
|
| + parent[Network.NetworkLogView._isMatchingSearchQuerySymbol] = true;
|
| + parent = /** @type {?Network.NetworkDataGridNode} */ (parent.parent);
|
| + }
|
| + }
|
| +
|
| + var newMatchedIndex = this._updateMatchCountAndFindMatchIndex(currentMatchedNode);
|
| + if (!newMatchedIndex && jumpBackwards)
|
| + newMatchedIndex = this._matchedRequestCount - 1;
|
| + this._highlightNthMatchedNodeForSearch(newMatchedIndex, shouldJump);
|
| }
|
|
|
| /**
|
| @@ -1310,7 +1339,7 @@ Network.NetworkLogView = class extends UI.VBox {
|
| */
|
| _updateMatchCountAndFindMatchIndex(node) {
|
| /** @type {!Array.<!Network.NetworkDataGridNode>} */
|
| - var nodes = this._dataGrid.rootNode().children;
|
| + var nodes = this.flattenAllNodes();
|
| var matchCount = 0;
|
| var matchIndex = 0;
|
| for (var i = 0; i < nodes.length; ++i) {
|
| @@ -1340,21 +1369,21 @@ Network.NetworkLogView = class extends UI.VBox {
|
| * @return {boolean}
|
| */
|
| _applyFilter(node) {
|
| - var request = node.request();
|
| - if (this._timeFilter && !this._timeFilter(request))
|
| - return false;
|
| - var categoryName = request.resourceType().category().title;
|
| - if (!this._resourceCategoryFilterUI.accept(categoryName))
|
| - return false;
|
| - if (this._dataURLFilterUI.checked() && request.parsedURL.isDataURL())
|
| - return false;
|
| - if (request.statusText === 'Service Worker Fallback Required')
|
| - return false;
|
| - for (var i = 0; i < this._filters.length; ++i) {
|
| - if (!this._filters[i](request))
|
| - return false;
|
| + for (var request of node.requests()) {
|
| + if (this._timeFilter && !this._timeFilter(request))
|
| + continue;
|
| + var categoryName = request.resourceType().category().title;
|
| + if (!this._resourceCategoryFilterUI.accept(categoryName))
|
| + continue;
|
| + if (this._dataURLFilterUI.checked() && request.parsedURL.isDataURL())
|
| + continue;
|
| + if (request.statusText === 'Service Worker Fallback Required')
|
| + continue;
|
| + if (this._filters.some(filter => !filter(request)))
|
| + continue;
|
| + return true;
|
| }
|
| - return true;
|
| + return false;
|
| }
|
|
|
| /**
|
| @@ -1495,8 +1524,8 @@ Network.NetworkLogView = class extends UI.VBox {
|
| jumpToPreviousSearchResult() {
|
| if (!this._matchedRequestCount)
|
| return;
|
| - var index = this._normalizeSearchResultIndex(this._currentMatchedRequestIndex - 1);
|
| - this._highlightNthMatchedRequestForSearch(index, true);
|
| + var index = this._normalizeSearchResultIndex(this._currentMatchedNodeIndex - 1);
|
| + this._highlightNthMatchedNodeForSearch(index, true);
|
| }
|
|
|
| /**
|
| @@ -1505,8 +1534,8 @@ Network.NetworkLogView = class extends UI.VBox {
|
| jumpToNextSearchResult() {
|
| if (!this._matchedRequestCount)
|
| return;
|
| - var index = this._normalizeSearchResultIndex(this._currentMatchedRequestIndex + 1);
|
| - this._highlightNthMatchedRequestForSearch(index, true);
|
| + var index = this._normalizeSearchResultIndex(this._currentMatchedNodeIndex + 1);
|
| + this._highlightNthMatchedNodeForSearch(index, true);
|
| }
|
|
|
| /**
|
| @@ -1547,11 +1576,11 @@ Network.NetworkLogView = class extends UI.VBox {
|
| }
|
|
|
| /**
|
| - * @param {!SDK.NetworkRequest} request
|
| * @param {string} platform
|
| + * @param {!SDK.NetworkRequest} request
|
| * @return {string}
|
| */
|
| - _generateCurlCommand(request, platform) {
|
| + _generateCurlCommand(platform, request) {
|
| var command = ['curl'];
|
| // These headers are derived from URL (except "version") and would be added by cURL anyway.
|
| var ignoredHeaders = {'host': 1, 'method': 1, 'path': 1, 'scheme': 1, 'version': 1};
|
|
|