OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org> |
| 4 * |
| 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions |
| 7 * are met: |
| 8 * |
| 9 * 1. Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. |
| 11 * 2. Redistributions in binary form must reproduce the above copyright |
| 12 * notice, this list of conditions and the following disclaimer in the |
| 13 * documentation and/or other materials provided with the distribution. |
| 14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of |
| 15 * its contributors may be used to endorse or promote products derived |
| 16 * from this software without specific prior written permission. |
| 17 * |
| 18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY |
| 19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY |
| 22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| 25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 28 */ |
| 29 |
| 30 WebInspector.ResourcesPanel = function() |
| 31 { |
| 32 WebInspector.Panel.call(this); |
| 33 |
| 34 this.element.addStyleClass("resources"); |
| 35 |
| 36 this.filterBarElement = document.createElement("div"); |
| 37 this.filterBarElement.id = "resources-filter"; |
| 38 this.element.appendChild(this.filterBarElement); |
| 39 |
| 40 this.viewsContainerElement = document.createElement("div"); |
| 41 this.viewsContainerElement.id = "resource-views"; |
| 42 this.element.appendChild(this.viewsContainerElement); |
| 43 |
| 44 this.containerElement = document.createElement("div"); |
| 45 this.containerElement.id = "resources-container"; |
| 46 this.containerElement.addEventListener("scroll", this._updateDividersLabelBa
rPosition.bind(this), false); |
| 47 this.element.appendChild(this.containerElement); |
| 48 |
| 49 this.sidebarElement = document.createElement("div"); |
| 50 this.sidebarElement.id = "resources-sidebar"; |
| 51 this.sidebarElement.className = "sidebar"; |
| 52 this.containerElement.appendChild(this.sidebarElement); |
| 53 |
| 54 this.sidebarResizeElement = document.createElement("div"); |
| 55 this.sidebarResizeElement.className = "sidebar-resizer-vertical"; |
| 56 this.sidebarResizeElement.addEventListener("mousedown", this._startSidebarDr
agging.bind(this), false); |
| 57 this.element.appendChild(this.sidebarResizeElement); |
| 58 |
| 59 this.containerContentElement = document.createElement("div"); |
| 60 this.containerContentElement.id = "resources-container-content"; |
| 61 this.containerElement.appendChild(this.containerContentElement); |
| 62 |
| 63 this.summaryBar = new WebInspector.SummaryBar(this.categories); |
| 64 this.summaryBar.element.id = "resources-summary"; |
| 65 this.containerContentElement.appendChild(this.summaryBar.element); |
| 66 |
| 67 this.resourcesGraphsElement = document.createElement("div"); |
| 68 this.resourcesGraphsElement.id = "resources-graphs"; |
| 69 this.containerContentElement.appendChild(this.resourcesGraphsElement); |
| 70 |
| 71 this.dividersElement = document.createElement("div"); |
| 72 this.dividersElement.id = "resources-dividers"; |
| 73 this.containerContentElement.appendChild(this.dividersElement); |
| 74 |
| 75 this.dividersLabelBarElement = document.createElement("div"); |
| 76 this.dividersLabelBarElement.id = "resources-dividers-label-bar"; |
| 77 this.containerContentElement.appendChild(this.dividersLabelBarElement); |
| 78 |
| 79 this.sidebarTreeElement = document.createElement("ol"); |
| 80 this.sidebarTreeElement.className = "sidebar-tree"; |
| 81 this.sidebarElement.appendChild(this.sidebarTreeElement); |
| 82 |
| 83 this.sidebarTree = new TreeOutline(this.sidebarTreeElement); |
| 84 |
| 85 var timeGraphItem = new WebInspector.SidebarTreeElement("resources-time-grap
h-sidebar-item", WebInspector.UIString("Time")); |
| 86 timeGraphItem.onselect = this._graphSelected.bind(this); |
| 87 |
| 88 var transferTimeCalculator = new WebInspector.ResourceTransferTimeCalculator
(); |
| 89 var transferDurationCalculator = new WebInspector.ResourceTransferDurationCa
lculator(); |
| 90 |
| 91 timeGraphItem.sortingOptions = [ |
| 92 { name: WebInspector.UIString("Sort by Start Time"), sortingFunction: We
bInspector.ResourceSidebarTreeElement.CompareByAscendingStartTime, calculator: t
ransferTimeCalculator }, |
| 93 { name: WebInspector.UIString("Sort by Response Time"), sortingFunction:
WebInspector.ResourceSidebarTreeElement.CompareByAscendingResponseReceivedTime,
calculator: transferTimeCalculator }, |
| 94 { name: WebInspector.UIString("Sort by End Time"), sortingFunction: WebI
nspector.ResourceSidebarTreeElement.CompareByAscendingEndTime, calculator: trans
ferTimeCalculator }, |
| 95 { name: WebInspector.UIString("Sort by Duration"), sortingFunction: WebI
nspector.ResourceSidebarTreeElement.CompareByDescendingDuration, calculator: tra
nsferDurationCalculator }, |
| 96 { name: WebInspector.UIString("Sort by Latency"), sortingFunction: WebIn
spector.ResourceSidebarTreeElement.CompareByDescendingLatency, calculator: trans
ferDurationCalculator }, |
| 97 ]; |
| 98 |
| 99 timeGraphItem.selectedSortingOptionIndex = 1; |
| 100 |
| 101 var sizeGraphItem = new WebInspector.SidebarTreeElement("resources-size-grap
h-sidebar-item", WebInspector.UIString("Size")); |
| 102 sizeGraphItem.onselect = this._graphSelected.bind(this); |
| 103 |
| 104 var transferSizeCalculator = new WebInspector.ResourceTransferSizeCalculator
(); |
| 105 sizeGraphItem.sortingOptions = [ |
| 106 { name: WebInspector.UIString("Sort by Size"), sortingFunction: WebInspe
ctor.ResourceSidebarTreeElement.CompareByDescendingSize, calculator: transferSiz
eCalculator }, |
| 107 ]; |
| 108 |
| 109 sizeGraphItem.selectedSortingOptionIndex = 0; |
| 110 |
| 111 this.graphsTreeElement = new WebInspector.SidebarSectionTreeElement(WebInspe
ctor.UIString("GRAPHS"), {}, true); |
| 112 this.sidebarTree.appendChild(this.graphsTreeElement); |
| 113 |
| 114 this.graphsTreeElement.appendChild(timeGraphItem); |
| 115 this.graphsTreeElement.appendChild(sizeGraphItem); |
| 116 this.graphsTreeElement.expand(); |
| 117 |
| 118 this.resourcesTreeElement = new WebInspector.SidebarSectionTreeElement(WebIn
spector.UIString("RESOURCES"), {}, true); |
| 119 this.sidebarTree.appendChild(this.resourcesTreeElement); |
| 120 |
| 121 this.resourcesTreeElement.expand(); |
| 122 |
| 123 var panelEnablerHeading = WebInspector.UIString("You need to enable resource
tracking to use this panel."); |
| 124 var panelEnablerDisclaimer = WebInspector.UIString("Enabling resource tracki
ng will reload the page and make page loading slower."); |
| 125 var panelEnablerButton = WebInspector.UIString("Enable resource tracking"); |
| 126 |
| 127 this.panelEnablerView = new WebInspector.PanelEnablerView("resources", panel
EnablerHeading, panelEnablerDisclaimer, panelEnablerButton); |
| 128 this.panelEnablerView.addEventListener("enable clicked", this._enableResourc
eTracking, this); |
| 129 |
| 130 this.element.appendChild(this.panelEnablerView.element); |
| 131 |
| 132 this.enableToggleButton = new WebInspector.StatusBarButton("", "enable-toggl
e-status-bar-item"); |
| 133 this.enableToggleButton.addEventListener("click", this._toggleResourceTracki
ng.bind(this), false); |
| 134 |
| 135 this.largerResourcesButton = new WebInspector.StatusBarButton(WebInspector.U
IString("Use small resource rows."), "resources-larger-resources-status-bar-item
"); |
| 136 this.largerResourcesButton.toggled = true; |
| 137 this.largerResourcesButton.addEventListener("click", this._toggleLargerResou
rces.bind(this), false); |
| 138 |
| 139 this.sortingSelectElement = document.createElement("select"); |
| 140 this.sortingSelectElement.className = "status-bar-item"; |
| 141 this.sortingSelectElement.addEventListener("change", this._changeSortingFunc
tion.bind(this), false); |
| 142 |
| 143 var createFilterElement = function (category) { |
| 144 var categoryElement = document.createElement("li"); |
| 145 categoryElement.category = category; |
| 146 categoryElement.addStyleClass(category); |
| 147 var label = WebInspector.UIString("All"); |
| 148 if (WebInspector.resourceCategories[category]) |
| 149 label = WebInspector.resourceCategories[category].title; |
| 150 categoryElement.appendChild(document.createTextNode(label)); |
| 151 categoryElement.addEventListener("click", this._updateFilter.bind(this),
false); |
| 152 this.filterBarElement.appendChild(categoryElement); |
| 153 return categoryElement; |
| 154 }; |
| 155 |
| 156 var allElement = createFilterElement.call(this, "all"); |
| 157 this.filter(allElement.category); |
| 158 for (var category in this.categories) |
| 159 createFilterElement.call(this, category); |
| 160 |
| 161 this.reset(); |
| 162 |
| 163 timeGraphItem.select(); |
| 164 } |
| 165 |
| 166 WebInspector.ResourcesPanel.prototype = { |
| 167 toolbarItemClass: "resources", |
| 168 |
| 169 get categories() |
| 170 { |
| 171 if (!this._categories) { |
| 172 this._categories = {documents: {color: {r: 47, g: 102, b: 236}}, sty
lesheets: {color: {r: 157, g: 231, b: 119}}, images: {color: {r: 164, g: 60, b:
255}}, scripts: {color: {r: 255, g: 121, b: 0}}, xhr: {color: {r: 231, g: 231, b
: 10}}, fonts: {color: {r: 255, g: 82, b: 62}}, other: {color: {r: 186, g: 186,
b: 186}}}; |
| 173 for (var category in this._categories) { |
| 174 this._categories[category].title = WebInspector.resourceCategori
es[category].title; |
| 175 } |
| 176 } |
| 177 return this._categories; |
| 178 }, |
| 179 |
| 180 filter: function (category) { |
| 181 if (this._filterCategory && this._filterCategory === category) |
| 182 return; |
| 183 |
| 184 if (this._filterCategory) { |
| 185 var filterElement = this.filterBarElement.getElementsByClassName(thi
s._filterCategory)[0]; |
| 186 filterElement.removeStyleClass("selected"); |
| 187 var oldClass = "filter-" + this._filterCategory; |
| 188 this.resourcesTreeElement.childrenListElement.removeStyleClass(oldCl
ass); |
| 189 this.resourcesGraphsElement.removeStyleClass(oldClass); |
| 190 } |
| 191 this._filterCategory = category; |
| 192 var filterElement = this.filterBarElement.getElementsByClassName(this._f
ilterCategory)[0]; |
| 193 filterElement.addStyleClass("selected"); |
| 194 var newClass = "filter-" + this._filterCategory; |
| 195 this.resourcesTreeElement.childrenListElement.addStyleClass(newClass); |
| 196 this.resourcesGraphsElement.addStyleClass(newClass); |
| 197 }, |
| 198 |
| 199 _updateFilter: function (e) { |
| 200 this.filter(e.target.category); |
| 201 }, |
| 202 |
| 203 get toolbarItemLabel() |
| 204 { |
| 205 return WebInspector.UIString("Resources"); |
| 206 }, |
| 207 |
| 208 get statusBarItems() |
| 209 { |
| 210 return [this.enableToggleButton.element, this.largerResourcesButton.elem
ent, this.sortingSelectElement]; |
| 211 }, |
| 212 |
| 213 show: function() |
| 214 { |
| 215 WebInspector.Panel.prototype.show.call(this); |
| 216 |
| 217 this._updateDividersLabelBarPosition(); |
| 218 this._updateSidebarWidth(); |
| 219 this.refreshIfNeeded(); |
| 220 |
| 221 var visibleView = this.visibleView; |
| 222 if (visibleView) { |
| 223 visibleView.headersVisible = true; |
| 224 visibleView.show(this.viewsContainerElement); |
| 225 } |
| 226 |
| 227 // Hide any views that are visible that are not this panel's current vis
ible view. |
| 228 // This can happen when a ResourceView is visible in the Scripts panel t
hen switched |
| 229 // to the this panel. |
| 230 var resourcesLength = this._resources.length; |
| 231 for (var i = 0; i < resourcesLength; ++i) { |
| 232 var resource = this._resources[i]; |
| 233 var view = resource._resourcesView; |
| 234 if (!view || view === visibleView) |
| 235 continue; |
| 236 view.visible = false; |
| 237 } |
| 238 }, |
| 239 |
| 240 resize: function() |
| 241 { |
| 242 this._updateGraphDividersIfNeeded(); |
| 243 |
| 244 var visibleView = this.visibleView; |
| 245 if (visibleView && "resize" in visibleView) |
| 246 visibleView.resize(); |
| 247 }, |
| 248 |
| 249 get searchableViews() |
| 250 { |
| 251 var views = []; |
| 252 |
| 253 const visibleView = this.visibleView; |
| 254 if (visibleView && visibleView.performSearch) |
| 255 views.push(visibleView); |
| 256 |
| 257 var resourcesLength = this._resources.length; |
| 258 for (var i = 0; i < resourcesLength; ++i) { |
| 259 var resource = this._resources[i]; |
| 260 if (!resource._resourcesTreeElement) |
| 261 continue; |
| 262 var resourceView = this.resourceViewForResource(resource); |
| 263 if (!resourceView.performSearch || resourceView === visibleView) |
| 264 continue; |
| 265 views.push(resourceView); |
| 266 } |
| 267 |
| 268 return views; |
| 269 }, |
| 270 |
| 271 get searchResultsSortFunction() |
| 272 { |
| 273 const resourceTreeElementSortFunction = this.sortingFunction; |
| 274 |
| 275 function sortFuction(a, b) |
| 276 { |
| 277 return resourceTreeElementSortFunction(a.resource._resourcesTreeElem
ent, b.resource._resourcesTreeElement); |
| 278 } |
| 279 |
| 280 return sortFuction; |
| 281 }, |
| 282 |
| 283 searchMatchFound: function(view, matches) |
| 284 { |
| 285 view.resource._resourcesTreeElement.searchMatches = matches; |
| 286 }, |
| 287 |
| 288 searchCanceled: function(startingNewSearch) |
| 289 { |
| 290 WebInspector.Panel.prototype.searchCanceled.call(this, startingNewSearch
); |
| 291 |
| 292 if (startingNewSearch || !this._resources) |
| 293 return; |
| 294 |
| 295 for (var i = 0; i < this._resources.length; ++i) { |
| 296 var resource = this._resources[i]; |
| 297 if (resource._resourcesTreeElement) |
| 298 resource._resourcesTreeElement.updateErrorsAndWarnings(); |
| 299 } |
| 300 }, |
| 301 |
| 302 performSearch: function(query) |
| 303 { |
| 304 for (var i = 0; i < this._resources.length; ++i) { |
| 305 var resource = this._resources[i]; |
| 306 if (resource._resourcesTreeElement) |
| 307 resource._resourcesTreeElement.resetBubble(); |
| 308 } |
| 309 |
| 310 WebInspector.Panel.prototype.performSearch.call(this, query); |
| 311 }, |
| 312 |
| 313 get visibleView() |
| 314 { |
| 315 if (this.visibleResource) |
| 316 return this.visibleResource._resourcesView; |
| 317 return null; |
| 318 }, |
| 319 |
| 320 get calculator() |
| 321 { |
| 322 return this._calculator; |
| 323 }, |
| 324 |
| 325 set calculator(x) |
| 326 { |
| 327 if (!x || this._calculator === x) |
| 328 return; |
| 329 |
| 330 this._calculator = x; |
| 331 this._calculator.reset(); |
| 332 |
| 333 this._staleResources = this._resources; |
| 334 this.refresh(); |
| 335 }, |
| 336 |
| 337 get sortingFunction() |
| 338 { |
| 339 return this._sortingFunction; |
| 340 }, |
| 341 |
| 342 set sortingFunction(x) |
| 343 { |
| 344 this._sortingFunction = x; |
| 345 this._sortResourcesIfNeeded(); |
| 346 }, |
| 347 |
| 348 get needsRefresh() |
| 349 { |
| 350 return this._needsRefresh; |
| 351 }, |
| 352 |
| 353 set needsRefresh(x) |
| 354 { |
| 355 if (this._needsRefresh === x) |
| 356 return; |
| 357 |
| 358 this._needsRefresh = x; |
| 359 |
| 360 if (x) { |
| 361 if (this.visible && !("_refreshTimeout" in this)) |
| 362 this._refreshTimeout = setTimeout(this.refresh.bind(this), 500); |
| 363 } else { |
| 364 if ("_refreshTimeout" in this) { |
| 365 clearTimeout(this._refreshTimeout); |
| 366 delete this._refreshTimeout; |
| 367 } |
| 368 } |
| 369 }, |
| 370 |
| 371 refreshIfNeeded: function() |
| 372 { |
| 373 if (this.needsRefresh) |
| 374 this.refresh(); |
| 375 }, |
| 376 |
| 377 refresh: function() |
| 378 { |
| 379 this.needsRefresh = false; |
| 380 |
| 381 var staleResourcesLength = this._staleResources.length; |
| 382 var boundariesChanged = false; |
| 383 |
| 384 for (var i = 0; i < staleResourcesLength; ++i) { |
| 385 var resource = this._staleResources[i]; |
| 386 if (!resource._resourcesTreeElement) { |
| 387 // Create the resource tree element and graph. |
| 388 resource._resourcesTreeElement = new WebInspector.ResourceSideba
rTreeElement(resource); |
| 389 resource._resourcesTreeElement._resourceGraph = new WebInspector
.ResourceGraph(resource); |
| 390 |
| 391 this.resourcesTreeElement.appendChild(resource._resourcesTreeEle
ment); |
| 392 this.resourcesGraphsElement.appendChild(resource._resourcesTreeE
lement._resourceGraph.graphElement); |
| 393 } |
| 394 |
| 395 resource._resourcesTreeElement.refresh(); |
| 396 |
| 397 if (this.calculator.updateBoundaries(resource)) |
| 398 boundariesChanged = true; |
| 399 } |
| 400 |
| 401 if (boundariesChanged) { |
| 402 // The boundaries changed, so all resource graphs are stale. |
| 403 this._staleResources = this._resources; |
| 404 staleResourcesLength = this._staleResources.length; |
| 405 } |
| 406 |
| 407 for (var i = 0; i < staleResourcesLength; ++i) |
| 408 this._staleResources[i]._resourcesTreeElement._resourceGraph.refresh
(this.calculator); |
| 409 |
| 410 this._staleResources = []; |
| 411 |
| 412 this._updateGraphDividersIfNeeded(); |
| 413 this._sortResourcesIfNeeded(); |
| 414 this._updateSummaryGraph(); |
| 415 }, |
| 416 |
| 417 resourceTrackingWasEnabled: function() |
| 418 { |
| 419 this.reset(); |
| 420 }, |
| 421 |
| 422 resourceTrackingWasDisabled: function() |
| 423 { |
| 424 this.reset(); |
| 425 }, |
| 426 |
| 427 reset: function() |
| 428 { |
| 429 this.closeVisibleResource(); |
| 430 |
| 431 this.containerElement.scrollTop = 0; |
| 432 |
| 433 delete this.currentQuery; |
| 434 this.searchCanceled(); |
| 435 |
| 436 if (this._calculator) |
| 437 this._calculator.reset(); |
| 438 |
| 439 if (this._resources) { |
| 440 var resourcesLength = this._resources.length; |
| 441 for (var i = 0; i < resourcesLength; ++i) { |
| 442 var resource = this._resources[i]; |
| 443 |
| 444 resource.warnings = 0; |
| 445 resource.errors = 0; |
| 446 |
| 447 delete resource._resourcesTreeElement; |
| 448 delete resource._resourcesView; |
| 449 } |
| 450 } |
| 451 |
| 452 this._resources = []; |
| 453 this._staleResources = []; |
| 454 |
| 455 this.resourcesTreeElement.removeChildren(); |
| 456 this.viewsContainerElement.removeChildren(); |
| 457 this.resourcesGraphsElement.removeChildren(); |
| 458 this.summaryBar.reset(); |
| 459 |
| 460 this._updateGraphDividersIfNeeded(true); |
| 461 |
| 462 if (InspectorController.resourceTrackingEnabled()) { |
| 463 this.enableToggleButton.title = WebInspector.UIString("Resource trac
king enabled. Click to disable."); |
| 464 this.enableToggleButton.toggled = true; |
| 465 this.largerResourcesButton.visible = true; |
| 466 this.sortingSelectElement.removeStyleClass("hidden"); |
| 467 this.panelEnablerView.visible = false; |
| 468 } else { |
| 469 this.enableToggleButton.title = WebInspector.UIString("Resource trac
king disabled. Click to enable."); |
| 470 this.enableToggleButton.toggled = false; |
| 471 this.largerResourcesButton.visible = false; |
| 472 this.sortingSelectElement.addStyleClass("hidden"); |
| 473 this.panelEnablerView.visible = true; |
| 474 } |
| 475 }, |
| 476 |
| 477 addResource: function(resource) |
| 478 { |
| 479 this._resources.push(resource); |
| 480 this.refreshResource(resource); |
| 481 }, |
| 482 |
| 483 removeResource: function(resource) |
| 484 { |
| 485 if (this.visibleView === resource._resourcesView) |
| 486 this.closeVisibleResource(); |
| 487 |
| 488 this._resources.remove(resource, true); |
| 489 |
| 490 if (resource._resourcesTreeElement) { |
| 491 this.resourcesTreeElement.removeChild(resource._resourcesTreeElement
); |
| 492 this.resourcesGraphsElement.removeChild(resource._resourcesTreeEleme
nt._resourceGraph.graphElement); |
| 493 } |
| 494 |
| 495 resource.warnings = 0; |
| 496 resource.errors = 0; |
| 497 |
| 498 delete resource._resourcesTreeElement; |
| 499 delete resource._resourcesView; |
| 500 |
| 501 this._adjustScrollPosition(); |
| 502 }, |
| 503 |
| 504 addMessageToResource: function(resource, msg) |
| 505 { |
| 506 if (!resource) |
| 507 return; |
| 508 |
| 509 switch (msg.level) { |
| 510 case WebInspector.ConsoleMessage.MessageLevel.Warning: |
| 511 resource.warnings += msg.repeatDelta; |
| 512 break; |
| 513 case WebInspector.ConsoleMessage.MessageLevel.Error: |
| 514 resource.errors += msg.repeatDelta; |
| 515 break; |
| 516 } |
| 517 |
| 518 if (!this.currentQuery && resource._resourcesTreeElement) |
| 519 resource._resourcesTreeElement.updateErrorsAndWarnings(); |
| 520 |
| 521 var view = this.resourceViewForResource(resource); |
| 522 if (view.addMessage) |
| 523 view.addMessage(msg); |
| 524 }, |
| 525 |
| 526 clearMessages: function() |
| 527 { |
| 528 var resourcesLength = this._resources.length; |
| 529 for (var i = 0; i < resourcesLength; ++i) { |
| 530 var resource = this._resources[i]; |
| 531 resource.warnings = 0; |
| 532 resource.errors = 0; |
| 533 |
| 534 if (!this.currentQuery && resource._resourcesTreeElement) |
| 535 resource._resourcesTreeElement.updateErrorsAndWarnings(); |
| 536 |
| 537 var view = resource._resourcesView; |
| 538 if (!view || !view.clearMessages) |
| 539 continue; |
| 540 view.clearMessages(); |
| 541 } |
| 542 }, |
| 543 |
| 544 refreshResource: function(resource) |
| 545 { |
| 546 this._staleResources.push(resource); |
| 547 this.needsRefresh = true; |
| 548 }, |
| 549 |
| 550 recreateViewForResourceIfNeeded: function(resource) |
| 551 { |
| 552 if (!resource || !resource._resourcesView) |
| 553 return; |
| 554 |
| 555 var newView = this._createResourceView(resource); |
| 556 if (newView.prototype === resource._resourcesView.prototype) |
| 557 return; |
| 558 |
| 559 resource.warnings = 0; |
| 560 resource.errors = 0; |
| 561 |
| 562 if (!this.currentQuery && resource._resourcesTreeElement) |
| 563 resource._resourcesTreeElement.updateErrorsAndWarnings(); |
| 564 |
| 565 var oldView = resource._resourcesView; |
| 566 |
| 567 resource._resourcesView.detach(); |
| 568 delete resource._resourcesView; |
| 569 |
| 570 resource._resourcesView = newView; |
| 571 |
| 572 newView.headersVisible = oldView.headersVisible; |
| 573 |
| 574 if (oldView.visible && oldView.element.parentNode) |
| 575 newView.show(oldView.element.parentNode); |
| 576 }, |
| 577 |
| 578 showResource: function(resource, line) |
| 579 { |
| 580 if (!resource) |
| 581 return; |
| 582 |
| 583 this.containerElement.addStyleClass("viewing-resource"); |
| 584 |
| 585 if (this.visibleResource && this.visibleResource._resourcesView) |
| 586 this.visibleResource._resourcesView.hide(); |
| 587 |
| 588 var view = this.resourceViewForResource(resource); |
| 589 view.headersVisible = true; |
| 590 view.show(this.viewsContainerElement); |
| 591 |
| 592 if (line) { |
| 593 if (view.revealLine) |
| 594 view.revealLine(line); |
| 595 if (view.highlightLine) |
| 596 view.highlightLine(line); |
| 597 } |
| 598 |
| 599 if (resource._resourcesTreeElement) { |
| 600 resource._resourcesTreeElement.reveal(); |
| 601 resource._resourcesTreeElement.select(true); |
| 602 } |
| 603 |
| 604 this.visibleResource = resource; |
| 605 |
| 606 this._updateSidebarWidth(); |
| 607 }, |
| 608 |
| 609 showView: function(view) |
| 610 { |
| 611 if (!view) |
| 612 return; |
| 613 this.showResource(view.resource); |
| 614 }, |
| 615 |
| 616 closeVisibleResource: function() |
| 617 { |
| 618 this.containerElement.removeStyleClass("viewing-resource"); |
| 619 this._updateDividersLabelBarPosition(); |
| 620 |
| 621 if (this.visibleResource && this.visibleResource._resourcesView) |
| 622 this.visibleResource._resourcesView.hide(); |
| 623 delete this.visibleResource; |
| 624 |
| 625 if (this._lastSelectedGraphTreeElement) |
| 626 this._lastSelectedGraphTreeElement.select(true); |
| 627 |
| 628 this._updateSidebarWidth(); |
| 629 }, |
| 630 |
| 631 resourceViewForResource: function(resource) |
| 632 { |
| 633 if (!resource) |
| 634 return null; |
| 635 if (!resource._resourcesView) |
| 636 resource._resourcesView = this._createResourceView(resource); |
| 637 return resource._resourcesView; |
| 638 }, |
| 639 |
| 640 sourceFrameForResource: function(resource) |
| 641 { |
| 642 var view = this.resourceViewForResource(resource); |
| 643 if (!view) |
| 644 return null; |
| 645 |
| 646 if (!view.setupSourceFrameIfNeeded) |
| 647 return null; |
| 648 |
| 649 // Setting up the source frame requires that we be attached. |
| 650 if (!this.element.parentNode) |
| 651 this.attach(); |
| 652 |
| 653 view.setupSourceFrameIfNeeded(); |
| 654 return view.sourceFrame; |
| 655 }, |
| 656 |
| 657 handleKeyEvent: function(event) |
| 658 { |
| 659 this.sidebarTree.handleKeyEvent(event); |
| 660 }, |
| 661 |
| 662 _sortResourcesIfNeeded: function() |
| 663 { |
| 664 var sortedElements = [].concat(this.resourcesTreeElement.children); |
| 665 sortedElements.sort(this.sortingFunction); |
| 666 |
| 667 var sortedElementsLength = sortedElements.length; |
| 668 for (var i = 0; i < sortedElementsLength; ++i) { |
| 669 var treeElement = sortedElements[i]; |
| 670 if (treeElement === this.resourcesTreeElement.children[i]) |
| 671 continue; |
| 672 |
| 673 var wasSelected = treeElement.selected; |
| 674 this.resourcesTreeElement.removeChild(treeElement); |
| 675 this.resourcesTreeElement.insertChild(treeElement, i); |
| 676 if (wasSelected) |
| 677 treeElement.select(true); |
| 678 |
| 679 var graphElement = treeElement._resourceGraph.graphElement; |
| 680 this.resourcesGraphsElement.insertBefore(graphElement, this.resource
sGraphsElement.children[i]); |
| 681 } |
| 682 }, |
| 683 |
| 684 _updateGraphDividersIfNeeded: function(force) |
| 685 { |
| 686 if (!this.visible) { |
| 687 this.needsRefresh = true; |
| 688 return; |
| 689 } |
| 690 |
| 691 if (document.body.offsetWidth <= 0) { |
| 692 // The stylesheet hasn't loaded yet or the window is closed, |
| 693 // so we can't calculate what is need. Return early. |
| 694 return; |
| 695 } |
| 696 |
| 697 var dividerCount = Math.round(this.dividersElement.offsetWidth / 64); |
| 698 var slice = this.calculator.boundarySpan / dividerCount; |
| 699 if (!force && this._currentDividerSlice === slice) |
| 700 return; |
| 701 |
| 702 this._currentDividerSlice = slice; |
| 703 |
| 704 this.dividersElement.removeChildren(); |
| 705 this.dividersLabelBarElement.removeChildren(); |
| 706 |
| 707 for (var i = 1; i <= dividerCount; ++i) { |
| 708 var divider = document.createElement("div"); |
| 709 divider.className = "resources-divider"; |
| 710 if (i === dividerCount) |
| 711 divider.addStyleClass("last"); |
| 712 divider.style.left = ((i / dividerCount) * 100) + "%"; |
| 713 |
| 714 this.dividersElement.appendChild(divider.cloneNode()); |
| 715 |
| 716 var label = document.createElement("div"); |
| 717 label.className = "resources-divider-label"; |
| 718 if (!isNaN(slice)) |
| 719 label.textContent = this.calculator.formatValue(slice * i); |
| 720 divider.appendChild(label); |
| 721 |
| 722 this.dividersLabelBarElement.appendChild(divider); |
| 723 } |
| 724 }, |
| 725 |
| 726 _updateSummaryGraph: function() |
| 727 { |
| 728 this.summaryBar.update(this._resources); |
| 729 }, |
| 730 |
| 731 _updateDividersLabelBarPosition: function() |
| 732 { |
| 733 var scrollTop = this.containerElement.scrollTop; |
| 734 var dividersTop = (scrollTop < this.summaryBar.element.offsetHeight ? th
is.summaryBar.element.offsetHeight : scrollTop); |
| 735 this.dividersElement.style.top = scrollTop + "px"; |
| 736 this.dividersLabelBarElement.style.top = dividersTop + "px"; |
| 737 }, |
| 738 |
| 739 _graphSelected: function(treeElement) |
| 740 { |
| 741 if (this._lastSelectedGraphTreeElement) |
| 742 this._lastSelectedGraphTreeElement.selectedSortingOptionIndex = this
.sortingSelectElement.selectedIndex; |
| 743 |
| 744 this._lastSelectedGraphTreeElement = treeElement; |
| 745 |
| 746 this.sortingSelectElement.removeChildren(); |
| 747 for (var i = 0; i < treeElement.sortingOptions.length; ++i) { |
| 748 var sortingOption = treeElement.sortingOptions[i]; |
| 749 var option = document.createElement("option"); |
| 750 option.label = sortingOption.name; |
| 751 option.sortingFunction = sortingOption.sortingFunction; |
| 752 option.calculator = sortingOption.calculator; |
| 753 this.sortingSelectElement.appendChild(option); |
| 754 } |
| 755 |
| 756 this.sortingSelectElement.selectedIndex = treeElement.selectedSortingOpt
ionIndex; |
| 757 this._changeSortingFunction(); |
| 758 |
| 759 this.closeVisibleResource(); |
| 760 this.containerElement.scrollTop = 0; |
| 761 }, |
| 762 |
| 763 _toggleLargerResources: function() |
| 764 { |
| 765 if (!this.resourcesTreeElement._childrenListNode) |
| 766 return; |
| 767 |
| 768 this.resourcesTreeElement.smallChildren = !this.resourcesTreeElement.sma
llChildren; |
| 769 |
| 770 if (this.resourcesTreeElement.smallChildren) { |
| 771 this.resourcesGraphsElement.addStyleClass("small"); |
| 772 this.largerResourcesButton.title = WebInspector.UIString("Use large
resource rows."); |
| 773 this.largerResourcesButton.toggled = false; |
| 774 this._adjustScrollPosition(); |
| 775 } else { |
| 776 this.resourcesGraphsElement.removeStyleClass("small"); |
| 777 this.largerResourcesButton.title = WebInspector.UIString("Use small
resource rows."); |
| 778 this.largerResourcesButton.toggled = true; |
| 779 } |
| 780 }, |
| 781 |
| 782 _adjustScrollPosition: function() |
| 783 { |
| 784 // Prevent the container from being scrolled off the end. |
| 785 if ((this.containerElement.scrollTop + this.containerElement.offsetHeigh
t) > this.sidebarElement.offsetHeight) |
| 786 this.containerElement.scrollTop = (this.sidebarElement.offsetHeight
- this.containerElement.offsetHeight); |
| 787 }, |
| 788 |
| 789 _changeSortingFunction: function() |
| 790 { |
| 791 var selectedOption = this.sortingSelectElement[this.sortingSelectElement
.selectedIndex]; |
| 792 this.sortingFunction = selectedOption.sortingFunction; |
| 793 this.calculator = this.summaryBar.calculator = selectedOption.calculator
; |
| 794 }, |
| 795 |
| 796 _createResourceView: function(resource) |
| 797 { |
| 798 switch (resource.category) { |
| 799 case WebInspector.resourceCategories.documents: |
| 800 case WebInspector.resourceCategories.stylesheets: |
| 801 case WebInspector.resourceCategories.scripts: |
| 802 case WebInspector.resourceCategories.xhr: |
| 803 return new WebInspector.SourceView(resource); |
| 804 case WebInspector.resourceCategories.images: |
| 805 return new WebInspector.ImageView(resource); |
| 806 case WebInspector.resourceCategories.fonts: |
| 807 return new WebInspector.FontView(resource); |
| 808 default: |
| 809 return new WebInspector.ResourceView(resource); |
| 810 } |
| 811 }, |
| 812 |
| 813 _startSidebarDragging: function(event) |
| 814 { |
| 815 WebInspector.elementDragStart(this.sidebarResizeElement, this._sidebarDr
agging.bind(this), this._endSidebarDragging.bind(this), event, "col-resize"); |
| 816 }, |
| 817 |
| 818 _sidebarDragging: function(event) |
| 819 { |
| 820 this._updateSidebarWidth(event.pageX); |
| 821 |
| 822 event.preventDefault(); |
| 823 }, |
| 824 |
| 825 _endSidebarDragging: function(event) |
| 826 { |
| 827 WebInspector.elementDragEnd(event); |
| 828 }, |
| 829 |
| 830 _updateSidebarWidth: function(width) |
| 831 { |
| 832 if (this.sidebarElement.offsetWidth <= 0) { |
| 833 // The stylesheet hasn't loaded yet or the window is closed, |
| 834 // so we can't calculate what is need. Return early. |
| 835 return; |
| 836 } |
| 837 |
| 838 if (!("_currentSidebarWidth" in this)) |
| 839 this._currentSidebarWidth = this.sidebarElement.offsetWidth; |
| 840 |
| 841 if (typeof width === "undefined") |
| 842 width = this._currentSidebarWidth; |
| 843 |
| 844 width = Number.constrain(width, Preferences.minSidebarWidth, window.inne
rWidth / 2); |
| 845 |
| 846 this._currentSidebarWidth = width; |
| 847 |
| 848 if (this.visibleResource) { |
| 849 this.containerElement.style.width = width + "px"; |
| 850 this.sidebarElement.style.removeProperty("width"); |
| 851 } else { |
| 852 this.sidebarElement.style.width = width + "px"; |
| 853 this.containerElement.style.removeProperty("width"); |
| 854 } |
| 855 |
| 856 this.containerContentElement.style.left = width + "px"; |
| 857 this.viewsContainerElement.style.left = width + "px"; |
| 858 this.sidebarResizeElement.style.left = (width - 3) + "px"; |
| 859 |
| 860 this._updateGraphDividersIfNeeded(); |
| 861 |
| 862 var visibleView = this.visibleView; |
| 863 if (visibleView && "resize" in visibleView) |
| 864 visibleView.resize(); |
| 865 }, |
| 866 |
| 867 _enableResourceTracking: function() |
| 868 { |
| 869 if (InspectorController.resourceTrackingEnabled()) |
| 870 return; |
| 871 this._toggleResourceTracking(this.panelEnablerView.alwaysEnabled); |
| 872 }, |
| 873 |
| 874 _toggleResourceTracking: function(optionalAlways) |
| 875 { |
| 876 if (InspectorController.resourceTrackingEnabled()) { |
| 877 this.largerResourcesButton.visible = false; |
| 878 this.sortingSelectElement.visible = false; |
| 879 InspectorController.disableResourceTracking(true); |
| 880 } else { |
| 881 this.largerResourcesButton.visible = true; |
| 882 this.sortingSelectElement.visible = true; |
| 883 InspectorController.enableResourceTracking(!!optionalAlways); |
| 884 } |
| 885 } |
| 886 } |
| 887 |
| 888 WebInspector.ResourcesPanel.prototype.__proto__ = WebInspector.Panel.prototype; |
| 889 |
| 890 WebInspector.ResourceCalculator = function() |
| 891 { |
| 892 } |
| 893 |
| 894 WebInspector.ResourceCalculator.prototype = { |
| 895 computeSummaryValues: function(resources) |
| 896 { |
| 897 var total = 0; |
| 898 var categoryValues = {}; |
| 899 |
| 900 var resourcesLength = resources.length; |
| 901 for (var i = 0; i < resourcesLength; ++i) { |
| 902 var resource = resources[i]; |
| 903 var value = this._value(resource); |
| 904 if (typeof value === "undefined") |
| 905 continue; |
| 906 if (!(resource.category.name in categoryValues)) |
| 907 categoryValues[resource.category.name] = 0; |
| 908 categoryValues[resource.category.name] += value; |
| 909 total += value; |
| 910 } |
| 911 |
| 912 return {categoryValues: categoryValues, total: total}; |
| 913 }, |
| 914 |
| 915 computeBarGraphPercentages: function(resource) |
| 916 { |
| 917 return {start: 0, middle: 0, end: (this._value(resource) / this.boundary
Span) * 100}; |
| 918 }, |
| 919 |
| 920 computeBarGraphLabels: function(resource) |
| 921 { |
| 922 const label = this.formatValue(this._value(resource)); |
| 923 var tooltip = label; |
| 924 if (resource.cached) |
| 925 tooltip = WebInspector.UIString("%s (from cache)", tooltip); |
| 926 return {left: label, right: label, tooltip: tooltip}; |
| 927 }, |
| 928 |
| 929 get boundarySpan() |
| 930 { |
| 931 return this.maximumBoundary - this.minimumBoundary; |
| 932 }, |
| 933 |
| 934 updateBoundaries: function(resource) |
| 935 { |
| 936 this.minimumBoundary = 0; |
| 937 |
| 938 var value = this._value(resource); |
| 939 if (typeof this.maximumBoundary === "undefined" || value > this.maximumB
oundary) { |
| 940 this.maximumBoundary = value; |
| 941 return true; |
| 942 } |
| 943 |
| 944 return false; |
| 945 }, |
| 946 |
| 947 reset: function() |
| 948 { |
| 949 delete this.minimumBoundary; |
| 950 delete this.maximumBoundary; |
| 951 }, |
| 952 |
| 953 _value: function(resource) |
| 954 { |
| 955 return 0; |
| 956 }, |
| 957 |
| 958 formatValue: function(value) |
| 959 { |
| 960 return value.toString(); |
| 961 } |
| 962 } |
| 963 |
| 964 WebInspector.ResourceTimeCalculator = function(startAtZero) |
| 965 { |
| 966 WebInspector.ResourceCalculator.call(this); |
| 967 this.startAtZero = startAtZero; |
| 968 } |
| 969 |
| 970 WebInspector.ResourceTimeCalculator.prototype = { |
| 971 computeSummaryValues: function(resources) |
| 972 { |
| 973 var resourcesByCategory = {}; |
| 974 var resourcesLength = resources.length; |
| 975 for (var i = 0; i < resourcesLength; ++i) { |
| 976 var resource = resources[i]; |
| 977 if (!(resource.category.name in resourcesByCategory)) |
| 978 resourcesByCategory[resource.category.name] = []; |
| 979 resourcesByCategory[resource.category.name].push(resource); |
| 980 } |
| 981 |
| 982 var earliestStart; |
| 983 var latestEnd; |
| 984 var categoryValues = {}; |
| 985 for (var category in resourcesByCategory) { |
| 986 resourcesByCategory[category].sort(WebInspector.Resource.CompareByTi
me); |
| 987 categoryValues[category] = 0; |
| 988 |
| 989 var segment = {start: -1, end: -1}; |
| 990 |
| 991 var categoryResources = resourcesByCategory[category]; |
| 992 var resourcesLength = categoryResources.length; |
| 993 for (var i = 0; i < resourcesLength; ++i) { |
| 994 var resource = categoryResources[i]; |
| 995 if (resource.startTime === -1 || resource.endTime === -1) |
| 996 continue; |
| 997 |
| 998 if (typeof earliestStart === "undefined") |
| 999 earliestStart = resource.startTime; |
| 1000 else |
| 1001 earliestStart = Math.min(earliestStart, resource.startTime); |
| 1002 |
| 1003 if (typeof latestEnd === "undefined") |
| 1004 latestEnd = resource.endTime; |
| 1005 else |
| 1006 latestEnd = Math.max(latestEnd, resource.endTime); |
| 1007 |
| 1008 if (resource.startTime <= segment.end) { |
| 1009 segment.end = Math.max(segment.end, resource.endTime); |
| 1010 continue; |
| 1011 } |
| 1012 |
| 1013 categoryValues[category] += segment.end - segment.start; |
| 1014 |
| 1015 segment.start = resource.startTime; |
| 1016 segment.end = resource.endTime; |
| 1017 } |
| 1018 |
| 1019 // Add the last segment |
| 1020 categoryValues[category] += segment.end - segment.start; |
| 1021 } |
| 1022 |
| 1023 return {categoryValues: categoryValues, total: latestEnd - earliestStart
}; |
| 1024 }, |
| 1025 |
| 1026 computeBarGraphPercentages: function(resource) |
| 1027 { |
| 1028 if (resource.startTime !== -1) |
| 1029 var start = ((resource.startTime - this.minimumBoundary) / this.boun
darySpan) * 100; |
| 1030 else |
| 1031 var start = 0; |
| 1032 |
| 1033 if (resource.responseReceivedTime !== -1) |
| 1034 var middle = ((resource.responseReceivedTime - this.minimumBoundary)
/ this.boundarySpan) * 100; |
| 1035 else |
| 1036 var middle = (this.startAtZero ? start : 100); |
| 1037 |
| 1038 if (resource.endTime !== -1) |
| 1039 var end = ((resource.endTime - this.minimumBoundary) / this.boundary
Span) * 100; |
| 1040 else |
| 1041 var end = (this.startAtZero ? middle : 100); |
| 1042 |
| 1043 if (this.startAtZero) { |
| 1044 end -= start; |
| 1045 middle -= start; |
| 1046 start = 0; |
| 1047 } |
| 1048 |
| 1049 return {start: start, middle: middle, end: end}; |
| 1050 }, |
| 1051 |
| 1052 computeBarGraphLabels: function(resource) |
| 1053 { |
| 1054 var leftLabel = ""; |
| 1055 if (resource.latency > 0) |
| 1056 leftLabel = this.formatValue(resource.latency); |
| 1057 |
| 1058 var rightLabel = ""; |
| 1059 if (resource.responseReceivedTime !== -1 && resource.endTime !== -1) |
| 1060 rightLabel = this.formatValue(resource.endTime - resource.responseRe
ceivedTime); |
| 1061 |
| 1062 if (leftLabel && rightLabel) { |
| 1063 var total = this.formatValue(resource.duration); |
| 1064 var tooltip = WebInspector.UIString("%s latency, %s download (%s tot
al)", leftLabel, rightLabel, total); |
| 1065 } else if (leftLabel) |
| 1066 var tooltip = WebInspector.UIString("%s latency", leftLabel); |
| 1067 else if (rightLabel) |
| 1068 var tooltip = WebInspector.UIString("%s download", rightLabel); |
| 1069 |
| 1070 if (resource.cached) |
| 1071 tooltip = WebInspector.UIString("%s (from cache)", tooltip); |
| 1072 |
| 1073 return {left: leftLabel, right: rightLabel, tooltip: tooltip}; |
| 1074 }, |
| 1075 |
| 1076 updateBoundaries: function(resource) |
| 1077 { |
| 1078 var didChange = false; |
| 1079 |
| 1080 var lowerBound; |
| 1081 if (this.startAtZero) |
| 1082 lowerBound = 0; |
| 1083 else |
| 1084 lowerBound = this._lowerBound(resource); |
| 1085 |
| 1086 if (lowerBound !== -1 && (typeof this.minimumBoundary === "undefined" ||
lowerBound < this.minimumBoundary)) { |
| 1087 this.minimumBoundary = lowerBound; |
| 1088 didChange = true; |
| 1089 } |
| 1090 |
| 1091 var upperBound = this._upperBound(resource); |
| 1092 if (upperBound !== -1 && (typeof this.maximumBoundary === "undefined" ||
upperBound > this.maximumBoundary)) { |
| 1093 this.maximumBoundary = upperBound; |
| 1094 didChange = true; |
| 1095 } |
| 1096 |
| 1097 return didChange; |
| 1098 }, |
| 1099 |
| 1100 formatValue: function(value) |
| 1101 { |
| 1102 return Number.secondsToString(value, WebInspector.UIString.bind(WebInspe
ctor)); |
| 1103 }, |
| 1104 |
| 1105 _lowerBound: function(resource) |
| 1106 { |
| 1107 return 0; |
| 1108 }, |
| 1109 |
| 1110 _upperBound: function(resource) |
| 1111 { |
| 1112 return 0; |
| 1113 }, |
| 1114 } |
| 1115 |
| 1116 WebInspector.ResourceTimeCalculator.prototype.__proto__ = WebInspector.ResourceC
alculator.prototype; |
| 1117 |
| 1118 WebInspector.ResourceTransferTimeCalculator = function() |
| 1119 { |
| 1120 WebInspector.ResourceTimeCalculator.call(this, false); |
| 1121 } |
| 1122 |
| 1123 WebInspector.ResourceTransferTimeCalculator.prototype = { |
| 1124 formatValue: function(value) |
| 1125 { |
| 1126 return Number.secondsToString(value, WebInspector.UIString.bind(WebInspe
ctor)); |
| 1127 }, |
| 1128 |
| 1129 _lowerBound: function(resource) |
| 1130 { |
| 1131 return resource.startTime; |
| 1132 }, |
| 1133 |
| 1134 _upperBound: function(resource) |
| 1135 { |
| 1136 return resource.endTime; |
| 1137 } |
| 1138 } |
| 1139 |
| 1140 WebInspector.ResourceTransferTimeCalculator.prototype.__proto__ = WebInspector.R
esourceTimeCalculator.prototype; |
| 1141 |
| 1142 WebInspector.ResourceTransferDurationCalculator = function() |
| 1143 { |
| 1144 WebInspector.ResourceTimeCalculator.call(this, true); |
| 1145 } |
| 1146 |
| 1147 WebInspector.ResourceTransferDurationCalculator.prototype = { |
| 1148 formatValue: function(value) |
| 1149 { |
| 1150 return Number.secondsToString(value, WebInspector.UIString.bind(WebInspe
ctor)); |
| 1151 }, |
| 1152 |
| 1153 _upperBound: function(resource) |
| 1154 { |
| 1155 return resource.duration; |
| 1156 } |
| 1157 } |
| 1158 |
| 1159 WebInspector.ResourceTransferDurationCalculator.prototype.__proto__ = WebInspect
or.ResourceTimeCalculator.prototype; |
| 1160 |
| 1161 WebInspector.ResourceTransferSizeCalculator = function() |
| 1162 { |
| 1163 WebInspector.ResourceCalculator.call(this); |
| 1164 } |
| 1165 |
| 1166 WebInspector.ResourceTransferSizeCalculator.prototype = { |
| 1167 _value: function(resource) |
| 1168 { |
| 1169 return resource.contentLength; |
| 1170 }, |
| 1171 |
| 1172 formatValue: function(value) |
| 1173 { |
| 1174 return Number.bytesToString(value, WebInspector.UIString.bind(WebInspect
or)); |
| 1175 } |
| 1176 } |
| 1177 |
| 1178 WebInspector.ResourceTransferSizeCalculator.prototype.__proto__ = WebInspector.R
esourceCalculator.prototype; |
| 1179 |
| 1180 WebInspector.ResourceSidebarTreeElement = function(resource) |
| 1181 { |
| 1182 this.resource = resource; |
| 1183 |
| 1184 this.createIconElement(); |
| 1185 |
| 1186 WebInspector.SidebarTreeElement.call(this, "resource-sidebar-tree-item", "",
"", resource); |
| 1187 |
| 1188 this.refreshTitles(); |
| 1189 } |
| 1190 |
| 1191 WebInspector.ResourceSidebarTreeElement.prototype = { |
| 1192 onattach: function() |
| 1193 { |
| 1194 WebInspector.SidebarTreeElement.prototype.onattach.call(this); |
| 1195 |
| 1196 var link = document.createElement("a"); |
| 1197 link.href = this.resource.url; |
| 1198 link.className = "invisible"; |
| 1199 while (this._listItemNode.firstChild) |
| 1200 link.appendChild(this._listItemNode.firstChild); |
| 1201 this._listItemNode.appendChild(link); |
| 1202 this._listItemNode.addStyleClass("resources-category-" + this.resource.c
ategory.name); |
| 1203 }, |
| 1204 |
| 1205 onselect: function() |
| 1206 { |
| 1207 WebInspector.panels.resources.showResource(this.resource); |
| 1208 }, |
| 1209 |
| 1210 ondblclick: function(treeElement, event) |
| 1211 { |
| 1212 InjectedScriptAccess.openInInspectedWindow(this.resource.url); |
| 1213 }, |
| 1214 |
| 1215 get mainTitle() |
| 1216 { |
| 1217 return this.resource.displayName; |
| 1218 }, |
| 1219 |
| 1220 set mainTitle(x) |
| 1221 { |
| 1222 // Do nothing. |
| 1223 }, |
| 1224 |
| 1225 get subtitle() |
| 1226 { |
| 1227 var subtitle = this.resource.displayDomain; |
| 1228 |
| 1229 if (this.resource.path && this.resource.lastPathComponent) { |
| 1230 var lastPathComponentIndex = this.resource.path.lastIndexOf("/" + th
is.resource.lastPathComponent); |
| 1231 if (lastPathComponentIndex != -1) |
| 1232 subtitle += this.resource.path.substring(0, lastPathComponentInd
ex); |
| 1233 } |
| 1234 |
| 1235 return subtitle; |
| 1236 }, |
| 1237 |
| 1238 set subtitle(x) |
| 1239 { |
| 1240 // Do nothing. |
| 1241 }, |
| 1242 |
| 1243 get selectable() |
| 1244 { |
| 1245 return WebInspector.panels.resources._filterCategory == "all" || WebInsp
ector.panels.resources._filterCategory == this.resource.category.name; |
| 1246 }, |
| 1247 |
| 1248 createIconElement: function() |
| 1249 { |
| 1250 var previousIconElement = this.iconElement; |
| 1251 |
| 1252 if (this.resource.category === WebInspector.resourceCategories.images) { |
| 1253 var previewImage = document.createElement("img"); |
| 1254 previewImage.className = "image-resource-icon-preview"; |
| 1255 previewImage.src = this.resource.url; |
| 1256 |
| 1257 this.iconElement = document.createElement("div"); |
| 1258 this.iconElement.className = "icon"; |
| 1259 this.iconElement.appendChild(previewImage); |
| 1260 } else { |
| 1261 this.iconElement = document.createElement("img"); |
| 1262 this.iconElement.className = "icon"; |
| 1263 } |
| 1264 |
| 1265 if (previousIconElement) |
| 1266 previousIconElement.parentNode.replaceChild(this.iconElement, previo
usIconElement); |
| 1267 }, |
| 1268 |
| 1269 refresh: function() |
| 1270 { |
| 1271 this.refreshTitles(); |
| 1272 |
| 1273 if (!this._listItemNode.hasStyleClass("resources-category-" + this.resou
rce.category.name)) { |
| 1274 this._listItemNode.removeMatchingStyleClasses("resources-category-\\
w+"); |
| 1275 this._listItemNode.addStyleClass("resources-category-" + this.resour
ce.category.name); |
| 1276 |
| 1277 this.createIconElement(); |
| 1278 } |
| 1279 }, |
| 1280 |
| 1281 resetBubble: function() |
| 1282 { |
| 1283 this.bubbleText = ""; |
| 1284 this.bubbleElement.removeStyleClass("search-matches"); |
| 1285 this.bubbleElement.removeStyleClass("warning"); |
| 1286 this.bubbleElement.removeStyleClass("error"); |
| 1287 }, |
| 1288 |
| 1289 set searchMatches(matches) |
| 1290 { |
| 1291 this.resetBubble(); |
| 1292 |
| 1293 if (!matches) |
| 1294 return; |
| 1295 |
| 1296 this.bubbleText = matches; |
| 1297 this.bubbleElement.addStyleClass("search-matches"); |
| 1298 }, |
| 1299 |
| 1300 updateErrorsAndWarnings: function() |
| 1301 { |
| 1302 this.resetBubble(); |
| 1303 |
| 1304 if (this.resource.warnings || this.resource.errors) |
| 1305 this.bubbleText = (this.resource.warnings + this.resource.errors); |
| 1306 |
| 1307 if (this.resource.warnings) |
| 1308 this.bubbleElement.addStyleClass("warning"); |
| 1309 |
| 1310 if (this.resource.errors) |
| 1311 this.bubbleElement.addStyleClass("error"); |
| 1312 } |
| 1313 } |
| 1314 |
| 1315 WebInspector.ResourceSidebarTreeElement.CompareByAscendingStartTime = function(a
, b) |
| 1316 { |
| 1317 return WebInspector.Resource.CompareByStartTime(a.resource, b.resource) |
| 1318 || WebInspector.Resource.CompareByEndTime(a.resource, b.resource) |
| 1319 || WebInspector.Resource.CompareByResponseReceivedTime(a.resource, b.res
ource); |
| 1320 } |
| 1321 |
| 1322 WebInspector.ResourceSidebarTreeElement.CompareByAscendingResponseReceivedTime =
function(a, b) |
| 1323 { |
| 1324 return WebInspector.Resource.CompareByResponseReceivedTime(a.resource, b.res
ource) |
| 1325 || WebInspector.Resource.CompareByStartTime(a.resource, b.resource) |
| 1326 || WebInspector.Resource.CompareByEndTime(a.resource, b.resource); |
| 1327 } |
| 1328 |
| 1329 WebInspector.ResourceSidebarTreeElement.CompareByAscendingEndTime = function(a,
b) |
| 1330 { |
| 1331 return WebInspector.Resource.CompareByEndTime(a.resource, b.resource) |
| 1332 || WebInspector.Resource.CompareByStartTime(a.resource, b.resource) |
| 1333 || WebInspector.Resource.CompareByResponseReceivedTime(a.resource, b.res
ource); |
| 1334 } |
| 1335 |
| 1336 WebInspector.ResourceSidebarTreeElement.CompareByDescendingDuration = function(a
, b) |
| 1337 { |
| 1338 return -1 * WebInspector.Resource.CompareByDuration(a.resource, b.resource); |
| 1339 } |
| 1340 |
| 1341 WebInspector.ResourceSidebarTreeElement.CompareByDescendingLatency = function(a,
b) |
| 1342 { |
| 1343 return -1 * WebInspector.Resource.CompareByLatency(a.resource, b.resource); |
| 1344 } |
| 1345 |
| 1346 WebInspector.ResourceSidebarTreeElement.CompareByDescendingSize = function(a, b) |
| 1347 { |
| 1348 return -1 * WebInspector.Resource.CompareBySize(a.resource, b.resource); |
| 1349 } |
| 1350 |
| 1351 WebInspector.ResourceSidebarTreeElement.prototype.__proto__ = WebInspector.Sideb
arTreeElement.prototype; |
| 1352 |
| 1353 WebInspector.ResourceGraph = function(resource) |
| 1354 { |
| 1355 this.resource = resource; |
| 1356 |
| 1357 this._graphElement = document.createElement("div"); |
| 1358 this._graphElement.className = "resources-graph-side"; |
| 1359 this._graphElement.addEventListener("mouseover", this.refreshLabelPositions.
bind(this), false); |
| 1360 |
| 1361 if (resource.cached) |
| 1362 this._graphElement.addStyleClass("resource-cached"); |
| 1363 |
| 1364 this._barAreaElement = document.createElement("div"); |
| 1365 this._barAreaElement.className = "resources-graph-bar-area hidden"; |
| 1366 this._graphElement.appendChild(this._barAreaElement); |
| 1367 |
| 1368 this._barLeftElement = document.createElement("div"); |
| 1369 this._barLeftElement.className = "resources-graph-bar waiting"; |
| 1370 this._barAreaElement.appendChild(this._barLeftElement); |
| 1371 |
| 1372 this._barRightElement = document.createElement("div"); |
| 1373 this._barRightElement.className = "resources-graph-bar"; |
| 1374 this._barAreaElement.appendChild(this._barRightElement); |
| 1375 |
| 1376 this._labelLeftElement = document.createElement("div"); |
| 1377 this._labelLeftElement.className = "resources-graph-label waiting"; |
| 1378 this._barAreaElement.appendChild(this._labelLeftElement); |
| 1379 |
| 1380 this._labelRightElement = document.createElement("div"); |
| 1381 this._labelRightElement.className = "resources-graph-label"; |
| 1382 this._barAreaElement.appendChild(this._labelRightElement); |
| 1383 |
| 1384 this._graphElement.addStyleClass("resources-category-" + resource.category.n
ame); |
| 1385 } |
| 1386 |
| 1387 WebInspector.ResourceGraph.prototype = { |
| 1388 get graphElement() |
| 1389 { |
| 1390 return this._graphElement; |
| 1391 }, |
| 1392 |
| 1393 refreshLabelPositions: function() |
| 1394 { |
| 1395 this._labelLeftElement.style.removeProperty("left"); |
| 1396 this._labelLeftElement.style.removeProperty("right"); |
| 1397 this._labelLeftElement.removeStyleClass("before"); |
| 1398 this._labelLeftElement.removeStyleClass("hidden"); |
| 1399 |
| 1400 this._labelRightElement.style.removeProperty("left"); |
| 1401 this._labelRightElement.style.removeProperty("right"); |
| 1402 this._labelRightElement.removeStyleClass("after"); |
| 1403 this._labelRightElement.removeStyleClass("hidden"); |
| 1404 |
| 1405 const labelPadding = 10; |
| 1406 const rightBarWidth = (this._barRightElement.offsetWidth - labelPadding)
; |
| 1407 const leftBarWidth = ((this._barLeftElement.offsetWidth - this._barRight
Element.offsetWidth) - labelPadding); |
| 1408 |
| 1409 var labelBefore = (this._labelLeftElement.offsetWidth > leftBarWidth); |
| 1410 var labelAfter = (this._labelRightElement.offsetWidth > rightBarWidth); |
| 1411 |
| 1412 if (labelBefore) { |
| 1413 if ((this._graphElement.offsetWidth * (this._percentages.start / 100
)) < (this._labelLeftElement.offsetWidth + 10)) |
| 1414 this._labelLeftElement.addStyleClass("hidden"); |
| 1415 this._labelLeftElement.style.setProperty("right", (100 - this._perce
ntages.start) + "%"); |
| 1416 this._labelLeftElement.addStyleClass("before"); |
| 1417 } else { |
| 1418 this._labelLeftElement.style.setProperty("left", this._percentages.s
tart + "%"); |
| 1419 this._labelLeftElement.style.setProperty("right", (100 - this._perce
ntages.middle) + "%"); |
| 1420 } |
| 1421 |
| 1422 if (labelAfter) { |
| 1423 if ((this._graphElement.offsetWidth * ((100 - this._percentages.end)
/ 100)) < (this._labelRightElement.offsetWidth + 10)) |
| 1424 this._labelRightElement.addStyleClass("hidden"); |
| 1425 this._labelRightElement.style.setProperty("left", this._percentages.
end + "%"); |
| 1426 this._labelRightElement.addStyleClass("after"); |
| 1427 } else { |
| 1428 this._labelRightElement.style.setProperty("left", this._percentages.
middle + "%"); |
| 1429 this._labelRightElement.style.setProperty("right", (100 - this._perc
entages.end) + "%"); |
| 1430 } |
| 1431 }, |
| 1432 |
| 1433 refresh: function(calculator) |
| 1434 { |
| 1435 var percentages = calculator.computeBarGraphPercentages(this.resource); |
| 1436 var labels = calculator.computeBarGraphLabels(this.resource); |
| 1437 |
| 1438 this._percentages = percentages; |
| 1439 |
| 1440 this._barAreaElement.removeStyleClass("hidden"); |
| 1441 |
| 1442 if (!this._graphElement.hasStyleClass("resources-category-" + this.resou
rce.category.name)) { |
| 1443 this._graphElement.removeMatchingStyleClasses("resources-category-\\
w+"); |
| 1444 this._graphElement.addStyleClass("resources-category-" + this.resour
ce.category.name); |
| 1445 } |
| 1446 |
| 1447 this._barLeftElement.style.setProperty("left", percentages.start + "%"); |
| 1448 this._barLeftElement.style.setProperty("right", (100 - percentages.end)
+ "%"); |
| 1449 |
| 1450 this._barRightElement.style.setProperty("left", percentages.middle + "%"
); |
| 1451 this._barRightElement.style.setProperty("right", (100 - percentages.end)
+ "%"); |
| 1452 |
| 1453 this._labelLeftElement.textContent = labels.left; |
| 1454 this._labelRightElement.textContent = labels.right; |
| 1455 |
| 1456 var tooltip = (labels.tooltip || ""); |
| 1457 this._barLeftElement.title = tooltip; |
| 1458 this._labelLeftElement.title = tooltip; |
| 1459 this._labelRightElement.title = tooltip; |
| 1460 this._barRightElement.title = tooltip; |
| 1461 } |
| 1462 } |
OLD | NEW |