OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |