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

Side by Side Diff: chrome/resources/Inspector/ResourcesPanel.js

Issue 334023: Remove Inspector directory in prep for ref build rev. (Closed) Base URL: http://src.chromium.org/svn/trunk/deps/reference_builds/
Patch Set: Created 11 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/resources/Inspector/ResourceView.js ('k') | chrome/resources/Inspector/ScriptsPanel.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Anthony Ricaud (rik24d@gmail.com)
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.viewsContainerElement = document.createElement("div");
37 this.viewsContainerElement.id = "resource-views";
38 this.element.appendChild(this.viewsContainerElement);
39
40 this.containerElement = document.createElement("div");
41 this.containerElement.id = "resources-container";
42 this.containerElement.addEventListener("scroll", this._updateDividersLabelBa rPosition.bind(this), false);
43 this.element.appendChild(this.containerElement);
44
45 this.sidebarElement = document.createElement("div");
46 this.sidebarElement.id = "resources-sidebar";
47 this.sidebarElement.className = "sidebar";
48 this.containerElement.appendChild(this.sidebarElement);
49
50 this.sidebarResizeElement = document.createElement("div");
51 this.sidebarResizeElement.className = "sidebar-resizer-vertical";
52 this.sidebarResizeElement.addEventListener("mousedown", this._startSidebarDr agging.bind(this), false);
53 this.element.appendChild(this.sidebarResizeElement);
54
55 this.containerContentElement = document.createElement("div");
56 this.containerContentElement.id = "resources-container-content";
57 this.containerElement.appendChild(this.containerContentElement);
58
59 this.summaryElement = document.createElement("div");
60 this.summaryElement.id = "resources-summary";
61 this.containerContentElement.appendChild(this.summaryElement);
62
63 this.resourcesGraphsElement = document.createElement("div");
64 this.resourcesGraphsElement.id = "resources-graphs";
65 this.containerContentElement.appendChild(this.resourcesGraphsElement);
66
67 this.dividersElement = document.createElement("div");
68 this.dividersElement.id = "resources-dividers";
69 this.containerContentElement.appendChild(this.dividersElement);
70
71 this.dividersLabelBarElement = document.createElement("div");
72 this.dividersLabelBarElement.id = "resources-dividers-label-bar";
73 this.containerContentElement.appendChild(this.dividersLabelBarElement);
74
75 this.summaryGraphElement = document.createElement("canvas");
76 this.summaryGraphElement.setAttribute("width", "450");
77 this.summaryGraphElement.setAttribute("height", "38");
78 this.summaryGraphElement.id = "resources-summary-graph";
79 this.summaryElement.appendChild(this.summaryGraphElement);
80
81 this.legendElement = document.createElement("div");
82 this.legendElement.id = "resources-graph-legend";
83 this.summaryElement.appendChild(this.legendElement);
84
85 this.sidebarTreeElement = document.createElement("ol");
86 this.sidebarTreeElement.className = "sidebar-tree";
87 this.sidebarElement.appendChild(this.sidebarTreeElement);
88
89 this.sidebarTree = new TreeOutline(this.sidebarTreeElement);
90
91 var timeGraphItem = new WebInspector.SidebarTreeElement("resources-time-grap h-sidebar-item", WebInspector.UIString("Time"));
92 timeGraphItem.onselect = this._graphSelected.bind(this);
93
94 var transferTimeCalculator = new WebInspector.ResourceTransferTimeCalculator ();
95 var transferDurationCalculator = new WebInspector.ResourceTransferDurationCa lculator();
96
97 timeGraphItem.sortingOptions = [
98 { name: WebInspector.UIString("Sort by Start Time"), sortingFunction: We bInspector.ResourceSidebarTreeElement.CompareByAscendingStartTime, calculator: t ransferTimeCalculator },
99 { name: WebInspector.UIString("Sort by Response Time"), sortingFunction: WebInspector.ResourceSidebarTreeElement.CompareByAscendingResponseReceivedTime, calculator: transferTimeCalculator },
100 { name: WebInspector.UIString("Sort by End Time"), sortingFunction: WebI nspector.ResourceSidebarTreeElement.CompareByAscendingEndTime, calculator: trans ferTimeCalculator },
101 { name: WebInspector.UIString("Sort by Duration"), sortingFunction: WebI nspector.ResourceSidebarTreeElement.CompareByDescendingDuration, calculator: tra nsferDurationCalculator },
102 { name: WebInspector.UIString("Sort by Latency"), sortingFunction: WebIn spector.ResourceSidebarTreeElement.CompareByDescendingLatency, calculator: trans ferDurationCalculator },
103 ];
104
105 timeGraphItem.selectedSortingOptionIndex = 1;
106
107 var sizeGraphItem = new WebInspector.SidebarTreeElement("resources-size-grap h-sidebar-item", WebInspector.UIString("Size"));
108 sizeGraphItem.onselect = this._graphSelected.bind(this);
109
110 var transferSizeCalculator = new WebInspector.ResourceTransferSizeCalculator ();
111 sizeGraphItem.sortingOptions = [
112 { name: WebInspector.UIString("Sort by Size"), sortingFunction: WebInspe ctor.ResourceSidebarTreeElement.CompareByDescendingSize, calculator: transferSiz eCalculator },
113 ];
114
115 sizeGraphItem.selectedSortingOptionIndex = 0;
116
117 this.graphsTreeElement = new WebInspector.SidebarSectionTreeElement(WebInspe ctor.UIString("GRAPHS"), {}, true);
118 this.sidebarTree.appendChild(this.graphsTreeElement);
119
120 this.graphsTreeElement.appendChild(timeGraphItem);
121 this.graphsTreeElement.appendChild(sizeGraphItem);
122 this.graphsTreeElement.expand();
123
124 this.resourcesTreeElement = new WebInspector.SidebarSectionTreeElement(WebIn spector.UIString("RESOURCES"), {}, true);
125 this.sidebarTree.appendChild(this.resourcesTreeElement);
126
127 this.resourcesTreeElement.expand();
128
129 this.largerResourcesButton = document.createElement("button");
130 this.largerResourcesButton.id = "resources-larger-resources-status-bar-item" ;
131 this.largerResourcesButton.className = "status-bar-item toggled-on";
132 this.largerResourcesButton.title = WebInspector.UIString("Use small resource rows.");
133 this.largerResourcesButton.addEventListener("click", this._toggleLargerResou rces.bind(this), false);
134
135 this.sortingSelectElement = document.createElement("select");
136 this.sortingSelectElement.className = "status-bar-item";
137 this.sortingSelectElement.addEventListener("change", this._changeSortingFunc tion.bind(this), false);
138
139 this.reset();
140
141 timeGraphItem.select();
142 }
143
144 WebInspector.ResourcesPanel.prototype = {
145 toolbarItemClass: "resources",
146
147 get toolbarItemLabel()
148 {
149 return WebInspector.UIString("Resources");
150 },
151
152 get statusBarItems()
153 {
154 return [this.largerResourcesButton, this.sortingSelectElement];
155 },
156
157 show: function()
158 {
159 WebInspector.Panel.prototype.show.call(this);
160
161 this._updateDividersLabelBarPosition();
162 this._updateSidebarWidth();
163 this.refreshIfNeeded();
164
165 var visibleView = this.visibleView;
166 if (visibleView) {
167 visibleView.headersVisible = true;
168 visibleView.show(this.viewsContainerElement);
169 }
170
171 // Hide any views that are visible that are not this panel's current vis ible view.
172 // This can happen when a ResourceView is visible in the Scripts panel t hen switched
173 // to the this panel.
174 var resourcesLength = this._resources.length;
175 for (var i = 0; i < resourcesLength; ++i) {
176 var resource = this._resources[i];
177 var view = resource._resourcesView;
178 if (!view || view === visibleView)
179 continue;
180 view.visible = false;
181 }
182 },
183
184 resize: function()
185 {
186 this._updateGraphDividersIfNeeded();
187
188 var visibleView = this.visibleView;
189 if (visibleView && "resize" in visibleView)
190 visibleView.resize();
191 },
192
193 get searchableViews()
194 {
195 var views = [];
196
197 const visibleView = this.visibleView;
198 if (visibleView && visibleView.performSearch)
199 views.push(visibleView);
200
201 var resourcesLength = this._resources.length;
202 for (var i = 0; i < resourcesLength; ++i) {
203 var resource = this._resources[i];
204 if (!resource._resourcesTreeElement)
205 continue;
206 var resourceView = this.resourceViewForResource(resource);
207 if (!resourceView.performSearch || resourceView === visibleView)
208 continue;
209 views.push(resourceView);
210 }
211
212 return views;
213 },
214
215 get searchResultsSortFunction()
216 {
217 const resourceTreeElementSortFunction = this.sortingFunction;
218
219 function sortFuction(a, b)
220 {
221 return resourceTreeElementSortFunction(a.resource._resourcesTreeElem ent, b.resource._resourcesTreeElement);
222 }
223
224 return sortFuction;
225 },
226
227 searchMatchFound: function(view, matches)
228 {
229 view.resource._resourcesTreeElement.searchMatches = matches;
230 },
231
232 searchCanceled: function(startingNewSearch)
233 {
234 WebInspector.Panel.prototype.searchCanceled.call(this, startingNewSearch );
235
236 if (startingNewSearch || !this._resources)
237 return;
238
239 for (var i = 0; i < this._resources.length; ++i) {
240 var resource = this._resources[i];
241 if (resource._resourcesTreeElement)
242 resource._resourcesTreeElement.updateErrorsAndWarnings();
243 }
244 },
245
246 performSearch: function(query)
247 {
248 for (var i = 0; i < this._resources.length; ++i) {
249 var resource = this._resources[i];
250 if (resource._resourcesTreeElement)
251 resource._resourcesTreeElement.resetBubble();
252 }
253
254 WebInspector.Panel.prototype.performSearch.call(this, query);
255 },
256
257 get visibleView()
258 {
259 if (this.visibleResource)
260 return this.visibleResource._resourcesView;
261 return null;
262 },
263
264 get calculator()
265 {
266 return this._calculator;
267 },
268
269 set calculator(x)
270 {
271 if (!x || this._calculator === x)
272 return;
273
274 this._calculator = x;
275 this._calculator.reset();
276
277 this._staleResources = this._resources;
278 this.refresh();
279 },
280
281 get sortingFunction()
282 {
283 return this._sortingFunction;
284 },
285
286 set sortingFunction(x)
287 {
288 this._sortingFunction = x;
289 this._sortResourcesIfNeeded();
290 },
291
292 get needsRefresh()
293 {
294 return this._needsRefresh;
295 },
296
297 set needsRefresh(x)
298 {
299 if (this._needsRefresh === x)
300 return;
301
302 this._needsRefresh = x;
303
304 if (x) {
305 if (this.visible && !("_refreshTimeout" in this))
306 this._refreshTimeout = setTimeout(this.refresh.bind(this), 500);
307 } else {
308 if ("_refreshTimeout" in this) {
309 clearTimeout(this._refreshTimeout);
310 delete this._refreshTimeout;
311 }
312 }
313 },
314
315 refreshIfNeeded: function()
316 {
317 if (this.needsRefresh)
318 this.refresh();
319 },
320
321 refresh: function()
322 {
323 this.needsRefresh = false;
324
325 var staleResourcesLength = this._staleResources.length;
326 var boundariesChanged = false;
327
328 for (var i = 0; i < staleResourcesLength; ++i) {
329 var resource = this._staleResources[i];
330 if (!resource._resourcesTreeElement) {
331 // Create the resource tree element and graph.
332 resource._resourcesTreeElement = new WebInspector.ResourceSideba rTreeElement(resource);
333 resource._resourcesTreeElement._resourceGraph = new WebInspector .ResourceGraph(resource);
334
335 this.resourcesTreeElement.appendChild(resource._resourcesTreeEle ment);
336 this.resourcesGraphsElement.appendChild(resource._resourcesTreeE lement._resourceGraph.graphElement);
337 }
338
339 resource._resourcesTreeElement.refresh();
340
341 if (this.calculator.updateBoundaries(resource))
342 boundariesChanged = true;
343 }
344
345 if (boundariesChanged) {
346 // The boundaries changed, so all resource graphs are stale.
347 this._staleResources = this._resources;
348 staleResourcesLength = this._staleResources.length;
349 }
350
351 for (var i = 0; i < staleResourcesLength; ++i)
352 this._staleResources[i]._resourcesTreeElement._resourceGraph.refresh (this.calculator);
353
354 this._staleResources = [];
355
356 this._updateGraphDividersIfNeeded();
357 this._sortResourcesIfNeeded();
358 this._updateSummaryGraph();
359 },
360
361 reset: function()
362 {
363 this.closeVisibleResource();
364
365 this.containerElement.scrollTop = 0;
366
367 delete this.currentQuery;
368 this.searchCanceled();
369
370 if (this._calculator)
371 this._calculator.reset();
372
373 if (this._resources) {
374 var resourcesLength = this._resources.length;
375 for (var i = 0; i < resourcesLength; ++i) {
376 var resource = this._resources[i];
377
378 resource.warnings = 0;
379 resource.errors = 0;
380
381 delete resource._resourcesTreeElement;
382 delete resource._resourcesView;
383 }
384 }
385
386 this._resources = [];
387 this._staleResources = [];
388
389 this.resourcesTreeElement.removeChildren();
390 this.viewsContainerElement.removeChildren();
391 this.resourcesGraphsElement.removeChildren();
392 this.legendElement.removeChildren();
393
394 this._updateGraphDividersIfNeeded(true);
395
396 this._drawSummaryGraph(); // draws an empty graph
397 },
398
399 addResource: function(resource)
400 {
401 this._resources.push(resource);
402 this.refreshResource(resource);
403 },
404
405 removeResource: function(resource)
406 {
407 if (this.visibleView === resource._resourcesView)
408 this.closeVisibleResource();
409
410 this._resources.remove(resource, true);
411
412 if (resource._resourcesTreeElement) {
413 this.resourcesTreeElement.removeChild(resource._resourcesTreeElement );
414 this.resourcesGraphsElement.removeChild(resource._resourcesTreeEleme nt._resourceGraph.graphElement);
415 }
416
417 resource.warnings = 0;
418 resource.errors = 0;
419
420 delete resource._resourcesTreeElement;
421 delete resource._resourcesView;
422
423 this._adjustScrollPosition();
424 },
425
426 addMessageToResource: function(resource, msg)
427 {
428 if (!resource)
429 return;
430
431 switch (msg.level) {
432 case WebInspector.ConsoleMessage.MessageLevel.Warning:
433 resource.warnings += msg.repeatDelta;
434 break;
435 case WebInspector.ConsoleMessage.MessageLevel.Error:
436 resource.errors += msg.repeatDelta;
437 break;
438 }
439
440 if (!this.currentQuery && resource._resourcesTreeElement)
441 resource._resourcesTreeElement.updateErrorsAndWarnings();
442
443 var view = this.resourceViewForResource(resource);
444 if (view.addMessage)
445 view.addMessage(msg);
446 },
447
448 clearMessages: function()
449 {
450 var resourcesLength = this._resources.length;
451 for (var i = 0; i < resourcesLength; ++i) {
452 var resource = this._resources[i];
453 resource.warnings = 0;
454 resource.errors = 0;
455
456 if (!this.currentQuery && resource._resourcesTreeElement)
457 resource._resourcesTreeElement.updateErrorsAndWarnings();
458
459 var view = resource._resourcesView;
460 if (!view || !view.clearMessages)
461 continue;
462 view.clearMessages();
463 }
464 },
465
466 refreshResource: function(resource)
467 {
468 this._staleResources.push(resource);
469 this.needsRefresh = true;
470 },
471
472 recreateViewForResourceIfNeeded: function(resource)
473 {
474 if (!resource || !resource._resourcesView)
475 return;
476
477 var newView = this._createResourceView(resource);
478 if (newView.prototype === resource._resourcesView.prototype)
479 return;
480
481 resource.warnings = 0;
482 resource.errors = 0;
483
484 if (!this.currentQuery && resource._resourcesTreeElement)
485 resource._resourcesTreeElement.updateErrorsAndWarnings();
486
487 var oldView = resource._resourcesView;
488
489 resource._resourcesView.detach();
490 delete resource._resourcesView;
491
492 resource._resourcesView = newView;
493
494 newView.headersVisible = oldView.headersVisible;
495
496 if (oldView.visible && oldView.element.parentNode)
497 newView.show(oldView.element.parentNode);
498 },
499
500 showResource: function(resource, line)
501 {
502 if (!resource)
503 return;
504
505 this.containerElement.addStyleClass("viewing-resource");
506
507 if (this.visibleResource && this.visibleResource._resourcesView)
508 this.visibleResource._resourcesView.hide();
509
510 var view = this.resourceViewForResource(resource);
511 view.headersVisible = true;
512 view.show(this.viewsContainerElement);
513
514 if (line) {
515 if (view.revealLine)
516 view.revealLine(line);
517 if (view.highlightLine)
518 view.highlightLine(line);
519 }
520
521 if (resource._resourcesTreeElement) {
522 resource._resourcesTreeElement.reveal();
523 resource._resourcesTreeElement.select(true);
524 }
525
526 this.visibleResource = resource;
527
528 this._updateSidebarWidth();
529 },
530
531 showView: function(view)
532 {
533 if (!view)
534 return;
535 this.showResource(view.resource);
536 },
537
538 closeVisibleResource: function()
539 {
540 this.containerElement.removeStyleClass("viewing-resource");
541 this._updateDividersLabelBarPosition();
542
543 if (this.visibleResource && this.visibleResource._resourcesView)
544 this.visibleResource._resourcesView.hide();
545 delete this.visibleResource;
546
547 if (this._lastSelectedGraphTreeElement)
548 this._lastSelectedGraphTreeElement.select(true);
549
550 this._updateSidebarWidth();
551 },
552
553 resourceViewForResource: function(resource)
554 {
555 if (!resource)
556 return null;
557 if (!resource._resourcesView)
558 resource._resourcesView = this._createResourceView(resource);
559 return resource._resourcesView;
560 },
561
562 sourceFrameForResource: function(resource)
563 {
564 var view = this.resourceViewForResource(resource);
565 if (!view)
566 return null;
567
568 if (!view.setupSourceFrameIfNeeded)
569 return null;
570
571 // Setting up the source frame requires that we be attached.
572 if (!this.element.parentNode)
573 this.attach();
574
575 view.setupSourceFrameIfNeeded();
576 return view.sourceFrame;
577 },
578
579 handleKeyEvent: function(event)
580 {
581 this.sidebarTree.handleKeyEvent(event);
582 },
583
584 _makeLegendElement: function(label, value, color)
585 {
586 var legendElement = document.createElement("label");
587 legendElement.className = "resources-graph-legend-item";
588
589 if (color) {
590 var swatch = document.createElement("canvas");
591 swatch.className = "resources-graph-legend-swatch";
592 swatch.setAttribute("width", "13");
593 swatch.setAttribute("height", "24");
594
595 legendElement.appendChild(swatch);
596
597 this._drawSwatch(swatch, color);
598 }
599
600 var labelElement = document.createElement("div");
601 labelElement.className = "resources-graph-legend-label";
602 legendElement.appendChild(labelElement);
603
604 var headerElement = document.createElement("div");
605 var headerElement = document.createElement("div");
606 headerElement.className = "resources-graph-legend-header";
607 headerElement.textContent = label;
608 labelElement.appendChild(headerElement);
609
610 var valueElement = document.createElement("div");
611 valueElement.className = "resources-graph-legend-value";
612 valueElement.textContent = value;
613 labelElement.appendChild(valueElement);
614
615 return legendElement;
616 },
617
618 _sortResourcesIfNeeded: function()
619 {
620 var sortedElements = [].concat(this.resourcesTreeElement.children);
621 sortedElements.sort(this.sortingFunction);
622
623 var sortedElementsLength = sortedElements.length;
624 for (var i = 0; i < sortedElementsLength; ++i) {
625 var treeElement = sortedElements[i];
626 if (treeElement === this.resourcesTreeElement.children[i])
627 continue;
628
629 var wasSelected = treeElement.selected;
630 this.resourcesTreeElement.removeChild(treeElement);
631 this.resourcesTreeElement.insertChild(treeElement, i);
632 if (wasSelected)
633 treeElement.select(true);
634
635 var graphElement = treeElement._resourceGraph.graphElement;
636 this.resourcesGraphsElement.insertBefore(graphElement, this.resource sGraphsElement.children[i]);
637 }
638 },
639
640 _updateGraphDividersIfNeeded: function(force)
641 {
642 if (!this.visible) {
643 this.needsRefresh = true;
644 return;
645 }
646
647 if (document.body.offsetWidth <= 0) {
648 // The stylesheet hasn't loaded yet or the window is closed,
649 // so we can't calculate what is need. Return early.
650 return;
651 }
652
653 var dividerCount = Math.round(this.dividersElement.offsetWidth / 64);
654 var slice = this.calculator.boundarySpan / dividerCount;
655 if (!force && this._currentDividerSlice === slice)
656 return;
657
658 this._currentDividerSlice = slice;
659
660 this.dividersElement.removeChildren();
661 this.dividersLabelBarElement.removeChildren();
662
663 for (var i = 1; i <= dividerCount; ++i) {
664 var divider = document.createElement("div");
665 divider.className = "resources-divider";
666 if (i === dividerCount)
667 divider.addStyleClass("last");
668 divider.style.left = ((i / dividerCount) * 100) + "%";
669
670 this.dividersElement.appendChild(divider.cloneNode());
671
672 var label = document.createElement("div");
673 label.className = "resources-divider-label";
674 if (!isNaN(slice))
675 label.textContent = this.calculator.formatValue(slice * i);
676 divider.appendChild(label);
677
678 this.dividersLabelBarElement.appendChild(divider);
679 }
680 },
681
682 _fadeOutRect: function(ctx, x, y, w, h, a1, a2)
683 {
684 ctx.save();
685
686 var gradient = ctx.createLinearGradient(x, y, x, y + h);
687 gradient.addColorStop(0.0, "rgba(0, 0, 0, " + (1.0 - a1) + ")");
688 gradient.addColorStop(0.8, "rgba(0, 0, 0, " + (1.0 - a2) + ")");
689 gradient.addColorStop(1.0, "rgba(0, 0, 0, 1.0)");
690
691 ctx.globalCompositeOperation = "destination-out";
692
693 ctx.fillStyle = gradient;
694 ctx.fillRect(x, y, w, h);
695
696 ctx.restore();
697 },
698
699 _drawSwatch: function(canvas, color)
700 {
701 var ctx = canvas.getContext("2d");
702
703 function drawSwatchSquare() {
704 ctx.fillStyle = color;
705 ctx.fillRect(0, 0, 13, 13);
706
707 var gradient = ctx.createLinearGradient(0, 0, 13, 13);
708 gradient.addColorStop(0.0, "rgba(255, 255, 255, 0.2)");
709 gradient.addColorStop(1.0, "rgba(255, 255, 255, 0.0)");
710
711 ctx.fillStyle = gradient;
712 ctx.fillRect(0, 0, 13, 13);
713
714 gradient = ctx.createLinearGradient(13, 13, 0, 0);
715 gradient.addColorStop(0.0, "rgba(0, 0, 0, 0.2)");
716 gradient.addColorStop(1.0, "rgba(0, 0, 0, 0.0)");
717
718 ctx.fillStyle = gradient;
719 ctx.fillRect(0, 0, 13, 13);
720
721 ctx.strokeStyle = "rgba(0, 0, 0, 0.6)";
722 ctx.strokeRect(0.5, 0.5, 12, 12);
723 }
724
725 ctx.clearRect(0, 0, 13, 24);
726
727 drawSwatchSquare();
728
729 ctx.save();
730
731 ctx.translate(0, 25);
732 ctx.scale(1, -1);
733
734 drawSwatchSquare();
735
736 ctx.restore();
737
738 this._fadeOutRect(ctx, 0, 13, 13, 13, 0.5, 0.0);
739 },
740
741 _drawSummaryGraph: function(segments)
742 {
743 if (!this.summaryGraphElement)
744 return;
745
746 if (!segments || !segments.length) {
747 segments = [{color: "white", value: 1}];
748 this._showingEmptySummaryGraph = true;
749 } else
750 delete this._showingEmptySummaryGraph;
751
752 // Calculate the total of all segments.
753 var total = 0;
754 for (var i = 0; i < segments.length; ++i)
755 total += segments[i].value;
756
757 // Calculate the percentage of each segment, rounded to the nearest perc ent.
758 var percents = segments.map(function(s) { return Math.max(Math.round(100 * s.value / total), 1) });
759
760 // Calculate the total percentage.
761 var percentTotal = 0;
762 for (var i = 0; i < percents.length; ++i)
763 percentTotal += percents[i];
764
765 // Make sure our percentage total is not greater-than 100, it can be gre ater
766 // if we rounded up for a few segments.
767 while (percentTotal > 100) {
768 for (var i = 0; i < percents.length && percentTotal > 100; ++i) {
769 if (percents[i] > 1) {
770 --percents[i];
771 --percentTotal;
772 }
773 }
774 }
775
776 // Make sure our percentage total is not less-than 100, it can be less
777 // if we rounded down for a few segments.
778 while (percentTotal < 100) {
779 for (var i = 0; i < percents.length && percentTotal < 100; ++i) {
780 ++percents[i];
781 ++percentTotal;
782 }
783 }
784
785 var ctx = this.summaryGraphElement.getContext("2d");
786
787 var x = 0;
788 var y = 0;
789 var w = 450;
790 var h = 19;
791 var r = (h / 2);
792
793 function drawPillShadow()
794 {
795 // This draws a line with a shadow that is offset away from the line . The line is stroked
796 // twice with different X shadow offsets to give more feathered edge s. Later we erase the
797 // line with destination-out 100% transparent black, leaving only th e shadow. This only
798 // works if nothing has been drawn into the canvas yet.
799
800 ctx.beginPath();
801 ctx.moveTo(x + 4, y + h - 3 - 0.5);
802 ctx.lineTo(x + w - 4, y + h - 3 - 0.5);
803 ctx.closePath();
804
805 ctx.save();
806
807 ctx.shadowBlur = 2;
808 ctx.shadowColor = "rgba(0, 0, 0, 0.5)";
809 ctx.shadowOffsetX = 3;
810 ctx.shadowOffsetY = 5;
811
812 ctx.strokeStyle = "white";
813 ctx.lineWidth = 1;
814
815 ctx.stroke();
816
817 ctx.shadowOffsetX = -3;
818
819 ctx.stroke();
820
821 ctx.restore();
822
823 ctx.save();
824
825 ctx.globalCompositeOperation = "destination-out";
826 ctx.strokeStyle = "rgba(0, 0, 0, 1)";
827 ctx.lineWidth = 1;
828
829 ctx.stroke();
830
831 ctx.restore();
832 }
833
834 function drawPill()
835 {
836 // Make a rounded rect path.
837 ctx.beginPath();
838 ctx.moveTo(x, y + r);
839 ctx.lineTo(x, y + h - r);
840 ctx.quadraticCurveTo(x, y + h, x + r, y + h);
841 ctx.lineTo(x + w - r, y + h);
842 ctx.quadraticCurveTo(x + w, y + h, x + w, y + h - r);
843 ctx.lineTo(x + w, y + r);
844 ctx.quadraticCurveTo(x + w, y, x + w - r, y);
845 ctx.lineTo(x + r, y);
846 ctx.quadraticCurveTo(x, y, x, y + r);
847 ctx.closePath();
848
849 // Clip to the rounded rect path.
850 ctx.save();
851 ctx.clip();
852
853 // Fill the segments with the associated color.
854 var previousSegmentsWidth = 0;
855 for (var i = 0; i < segments.length; ++i) {
856 var segmentWidth = Math.round(w * percents[i] / 100);
857 ctx.fillStyle = segments[i].color;
858 ctx.fillRect(x + previousSegmentsWidth, y, segmentWidth, h);
859 previousSegmentsWidth += segmentWidth;
860 }
861
862 // Draw the segment divider lines.
863 ctx.lineWidth = 1;
864 for (var i = 1; i < 20; ++i) {
865 ctx.beginPath();
866 ctx.moveTo(x + (i * Math.round(w / 20)) + 0.5, y);
867 ctx.lineTo(x + (i * Math.round(w / 20)) + 0.5, y + h);
868 ctx.closePath();
869
870 ctx.strokeStyle = "rgba(0, 0, 0, 0.2)";
871 ctx.stroke();
872
873 ctx.beginPath();
874 ctx.moveTo(x + (i * Math.round(w / 20)) + 1.5, y);
875 ctx.lineTo(x + (i * Math.round(w / 20)) + 1.5, y + h);
876 ctx.closePath();
877
878 ctx.strokeStyle = "rgba(255, 255, 255, 0.2)";
879 ctx.stroke();
880 }
881
882 // Draw the pill shading.
883 var lightGradient = ctx.createLinearGradient(x, y, x, y + (h / 1.5)) ;
884 lightGradient.addColorStop(0.0, "rgba(220, 220, 220, 0.6)");
885 lightGradient.addColorStop(0.4, "rgba(220, 220, 220, 0.2)");
886 lightGradient.addColorStop(1.0, "rgba(255, 255, 255, 0.0)");
887
888 var darkGradient = ctx.createLinearGradient(x, y + (h / 3), x, y + h );
889 darkGradient.addColorStop(0.0, "rgba(0, 0, 0, 0.0)");
890 darkGradient.addColorStop(0.8, "rgba(0, 0, 0, 0.2)");
891 darkGradient.addColorStop(1.0, "rgba(0, 0, 0, 0.5)");
892
893 ctx.fillStyle = darkGradient;
894 ctx.fillRect(x, y, w, h);
895
896 ctx.fillStyle = lightGradient;
897 ctx.fillRect(x, y, w, h);
898
899 ctx.restore();
900 }
901
902 ctx.clearRect(x, y, w, (h * 2));
903
904 drawPillShadow();
905 drawPill();
906
907 ctx.save();
908
909 ctx.translate(0, (h * 2) + 1);
910 ctx.scale(1, -1);
911
912 drawPill();
913
914 ctx.restore();
915
916 this._fadeOutRect(ctx, x, y + h + 1, w, h, 0.5, 0.0);
917 },
918
919 _updateSummaryGraph: function()
920 {
921 var graphInfo = this.calculator.computeSummaryValues(this._resources);
922
923 var categoryOrder = ["documents", "stylesheets", "images", "scripts", "x hr", "fonts", "other"];
924 var categoryColors = {documents: {r: 47, g: 102, b: 236}, stylesheets: { r: 157, g: 231, b: 119}, images: {r: 164, g: 60, b: 255}, scripts: {r: 255, g: 1 21, b: 0}, xhr: {r: 231, g: 231, b: 10}, fonts: {r: 255, g: 82, b: 62}, other: { r: 186, g: 186, b: 186}};
925 var fillSegments = [];
926
927 this.legendElement.removeChildren();
928
929 for (var i = 0; i < categoryOrder.length; ++i) {
930 var category = categoryOrder[i];
931 var size = graphInfo.categoryValues[category];
932 if (!size)
933 continue;
934
935 var color = categoryColors[category];
936 var colorString = "rgb(" + color.r + ", " + color.g + ", " + color.b + ")";
937
938 var fillSegment = {color: colorString, value: size};
939 fillSegments.push(fillSegment);
940
941 var legendLabel = this._makeLegendElement(WebInspector.resourceCateg ories[category].title, this.calculator.formatValue(size), colorString);
942 this.legendElement.appendChild(legendLabel);
943 }
944
945 if (graphInfo.total) {
946 var totalLegendLabel = this._makeLegendElement(WebInspector.UIString ("Total"), this.calculator.formatValue(graphInfo.total));
947 totalLegendLabel.addStyleClass("total");
948 this.legendElement.appendChild(totalLegendLabel);
949 }
950
951 this._drawSummaryGraph(fillSegments);
952 },
953
954 _updateDividersLabelBarPosition: function()
955 {
956 var scrollTop = this.containerElement.scrollTop;
957 var dividersTop = (scrollTop < this.summaryElement.offsetHeight ? this.s ummaryElement.offsetHeight : scrollTop);
958 this.dividersElement.style.top = scrollTop + "px";
959 this.dividersLabelBarElement.style.top = dividersTop + "px";
960 },
961
962 _graphSelected: function(treeElement)
963 {
964 if (this._lastSelectedGraphTreeElement)
965 this._lastSelectedGraphTreeElement.selectedSortingOptionIndex = this .sortingSelectElement.selectedIndex;
966
967 this._lastSelectedGraphTreeElement = treeElement;
968
969 this.sortingSelectElement.removeChildren();
970 for (var i = 0; i < treeElement.sortingOptions.length; ++i) {
971 var sortingOption = treeElement.sortingOptions[i];
972 var option = document.createElement("option");
973 option.label = sortingOption.name;
974 option.sortingFunction = sortingOption.sortingFunction;
975 option.calculator = sortingOption.calculator;
976 this.sortingSelectElement.appendChild(option);
977 }
978
979 this.sortingSelectElement.selectedIndex = treeElement.selectedSortingOpt ionIndex;
980 this._changeSortingFunction();
981
982 this.closeVisibleResource();
983 this.containerElement.scrollTop = 0;
984 },
985
986 _toggleLargerResources: function()
987 {
988 if (!this.resourcesTreeElement._childrenListNode)
989 return;
990
991 this.resourcesTreeElement.smallChildren = !this.resourcesTreeElement.sma llChildren;
992
993 if (this.resourcesTreeElement.smallChildren) {
994 this.resourcesGraphsElement.addStyleClass("small");
995 this.largerResourcesButton.title = WebInspector.UIString("Use large resource rows.");
996 this.largerResourcesButton.removeStyleClass("toggled-on");
997 this._adjustScrollPosition();
998 } else {
999 this.resourcesGraphsElement.removeStyleClass("small");
1000 this.largerResourcesButton.title = WebInspector.UIString("Use small resource rows.");
1001 this.largerResourcesButton.addStyleClass("toggled-on");
1002 }
1003 },
1004
1005 _adjustScrollPosition: function()
1006 {
1007 // Prevent the container from being scrolled off the end.
1008 if ((this.containerElement.scrollTop + this.containerElement.offsetHeigh t) > this.sidebarElement.offsetHeight)
1009 this.containerElement.scrollTop = (this.sidebarElement.offsetHeight - this.containerElement.offsetHeight);
1010 },
1011
1012 _changeSortingFunction: function()
1013 {
1014 var selectedOption = this.sortingSelectElement[this.sortingSelectElement .selectedIndex];
1015 this.sortingFunction = selectedOption.sortingFunction;
1016 this.calculator = selectedOption.calculator;
1017 },
1018
1019 _createResourceView: function(resource)
1020 {
1021 switch (resource.category) {
1022 case WebInspector.resourceCategories.documents:
1023 case WebInspector.resourceCategories.stylesheets:
1024 case WebInspector.resourceCategories.scripts:
1025 case WebInspector.resourceCategories.xhr:
1026 return new WebInspector.SourceView(resource);
1027 case WebInspector.resourceCategories.images:
1028 return new WebInspector.ImageView(resource);
1029 case WebInspector.resourceCategories.fonts:
1030 return new WebInspector.FontView(resource);
1031 default:
1032 return new WebInspector.ResourceView(resource);
1033 }
1034 },
1035
1036 _startSidebarDragging: function(event)
1037 {
1038 WebInspector.elementDragStart(this.sidebarResizeElement, this._sidebarDr agging.bind(this), this._endSidebarDragging.bind(this), event, "col-resize");
1039 },
1040
1041 _sidebarDragging: function(event)
1042 {
1043 this._updateSidebarWidth(event.pageX);
1044
1045 event.preventDefault();
1046 },
1047
1048 _endSidebarDragging: function(event)
1049 {
1050 WebInspector.elementDragEnd(event);
1051 },
1052
1053 _updateSidebarWidth: function(width)
1054 {
1055 if (this.sidebarElement.offsetWidth <= 0) {
1056 // The stylesheet hasn't loaded yet or the window is closed,
1057 // so we can't calculate what is need. Return early.
1058 return;
1059 }
1060
1061 if (!("_currentSidebarWidth" in this))
1062 this._currentSidebarWidth = this.sidebarElement.offsetWidth;
1063
1064 if (typeof width === "undefined")
1065 width = this._currentSidebarWidth;
1066
1067 width = Number.constrain(width, Preferences.minSidebarWidth, window.inne rWidth / 2);
1068
1069 this._currentSidebarWidth = width;
1070
1071 if (this.visibleResource) {
1072 this.containerElement.style.width = width + "px";
1073 this.sidebarElement.style.removeProperty("width");
1074 } else {
1075 this.sidebarElement.style.width = width + "px";
1076 this.containerElement.style.removeProperty("width");
1077 }
1078
1079 this.containerContentElement.style.left = width + "px";
1080 this.viewsContainerElement.style.left = width + "px";
1081 this.sidebarResizeElement.style.left = (width - 3) + "px";
1082
1083 this._updateGraphDividersIfNeeded();
1084
1085 var visibleView = this.visibleView;
1086 if (visibleView && "resize" in visibleView)
1087 visibleView.resize();
1088 }
1089 }
1090
1091 WebInspector.ResourcesPanel.prototype.__proto__ = WebInspector.Panel.prototype;
1092
1093 WebInspector.ResourceCalculator = function()
1094 {
1095 }
1096
1097 WebInspector.ResourceCalculator.prototype = {
1098 computeSummaryValues: function(resources)
1099 {
1100 var total = 0;
1101 var categoryValues = {};
1102
1103 var resourcesLength = resources.length;
1104 for (var i = 0; i < resourcesLength; ++i) {
1105 var resource = resources[i];
1106 var value = this._value(resource);
1107 if (typeof value === "undefined")
1108 continue;
1109 if (!(resource.category.name in categoryValues))
1110 categoryValues[resource.category.name] = 0;
1111 categoryValues[resource.category.name] += value;
1112 total += value;
1113 }
1114
1115 return {categoryValues: categoryValues, total: total};
1116 },
1117
1118 computeBarGraphPercentages: function(resource)
1119 {
1120 return {start: 0, middle: 0, end: (this._value(resource) / this.boundary Span) * 100};
1121 },
1122
1123 computeBarGraphLabels: function(resource)
1124 {
1125 const label = this.formatValue(this._value(resource));
1126 var tooltip = label;
1127 if (resource.cached)
1128 tooltip = WebInspector.UIString("%s (from cache)", tooltip);
1129 return {left: label, right: label, tooltip: tooltip};
1130 },
1131
1132 get boundarySpan()
1133 {
1134 return this.maximumBoundary - this.minimumBoundary;
1135 },
1136
1137 updateBoundaries: function(resource)
1138 {
1139 this.minimumBoundary = 0;
1140
1141 var value = this._value(resource);
1142 if (typeof this.maximumBoundary === "undefined" || value > this.maximumB oundary) {
1143 this.maximumBoundary = value;
1144 return true;
1145 }
1146
1147 return false;
1148 },
1149
1150 reset: function()
1151 {
1152 delete this.minimumBoundary;
1153 delete this.maximumBoundary;
1154 },
1155
1156 _value: function(resource)
1157 {
1158 return 0;
1159 },
1160
1161 formatValue: function(value)
1162 {
1163 return value.toString();
1164 }
1165 }
1166
1167 WebInspector.ResourceTimeCalculator = function(startAtZero)
1168 {
1169 WebInspector.ResourceCalculator.call(this);
1170 this.startAtZero = startAtZero;
1171 }
1172
1173 WebInspector.ResourceTimeCalculator.prototype = {
1174 computeSummaryValues: function(resources)
1175 {
1176 var resourcesByCategory = {};
1177 var resourcesLength = resources.length;
1178 for (var i = 0; i < resourcesLength; ++i) {
1179 var resource = resources[i];
1180 if (!(resource.category.name in resourcesByCategory))
1181 resourcesByCategory[resource.category.name] = [];
1182 resourcesByCategory[resource.category.name].push(resource);
1183 }
1184
1185 var earliestStart;
1186 var latestEnd;
1187 var categoryValues = {};
1188 for (var category in resourcesByCategory) {
1189 resourcesByCategory[category].sort(WebInspector.Resource.CompareByTi me);
1190 categoryValues[category] = 0;
1191
1192 var segment = {start: -1, end: -1};
1193
1194 var categoryResources = resourcesByCategory[category];
1195 var resourcesLength = categoryResources.length;
1196 for (var i = 0; i < resourcesLength; ++i) {
1197 var resource = categoryResources[i];
1198 if (resource.startTime === -1 || resource.endTime === -1)
1199 continue;
1200
1201 if (typeof earliestStart === "undefined")
1202 earliestStart = resource.startTime;
1203 else
1204 earliestStart = Math.min(earliestStart, resource.startTime);
1205
1206 if (typeof latestEnd === "undefined")
1207 latestEnd = resource.endTime;
1208 else
1209 latestEnd = Math.max(latestEnd, resource.endTime);
1210
1211 if (resource.startTime <= segment.end) {
1212 segment.end = Math.max(segment.end, resource.endTime);
1213 continue;
1214 }
1215
1216 categoryValues[category] += segment.end - segment.start;
1217
1218 segment.start = resource.startTime;
1219 segment.end = resource.endTime;
1220 }
1221
1222 // Add the last segment
1223 categoryValues[category] += segment.end - segment.start;
1224 }
1225
1226 return {categoryValues: categoryValues, total: latestEnd - earliestStart };
1227 },
1228
1229 computeBarGraphPercentages: function(resource)
1230 {
1231 if (resource.startTime !== -1)
1232 var start = ((resource.startTime - this.minimumBoundary) / this.boun darySpan) * 100;
1233 else
1234 var start = 0;
1235
1236 if (resource.responseReceivedTime !== -1)
1237 var middle = ((resource.responseReceivedTime - this.minimumBoundary) / this.boundarySpan) * 100;
1238 else
1239 var middle = (this.startAtZero ? start : 100);
1240
1241 if (resource.endTime !== -1)
1242 var end = ((resource.endTime - this.minimumBoundary) / this.boundary Span) * 100;
1243 else
1244 var end = (this.startAtZero ? middle : 100);
1245
1246 if (this.startAtZero) {
1247 end -= start;
1248 middle -= start;
1249 start = 0;
1250 }
1251
1252 return {start: start, middle: middle, end: end};
1253 },
1254
1255 computeBarGraphLabels: function(resource)
1256 {
1257 var leftLabel = "";
1258 if (resource.latency > 0)
1259 leftLabel = this.formatValue(resource.latency);
1260
1261 var rightLabel = "";
1262 if (resource.responseReceivedTime !== -1 && resource.endTime !== -1)
1263 rightLabel = this.formatValue(resource.endTime - resource.responseRe ceivedTime);
1264
1265 if (leftLabel && rightLabel) {
1266 var total = this.formatValue(resource.duration);
1267 var tooltip = WebInspector.UIString("%s latency, %s download (%s tot al)", leftLabel, rightLabel, total);
1268 } else if (leftLabel)
1269 var tooltip = WebInspector.UIString("%s latency", leftLabel);
1270 else if (rightLabel)
1271 var tooltip = WebInspector.UIString("%s download", rightLabel);
1272
1273 if (resource.cached)
1274 tooltip = WebInspector.UIString("%s (from cache)", tooltip);
1275
1276 return {left: leftLabel, right: rightLabel, tooltip: tooltip};
1277 },
1278
1279 updateBoundaries: function(resource)
1280 {
1281 var didChange = false;
1282
1283 var lowerBound;
1284 if (this.startAtZero)
1285 lowerBound = 0;
1286 else
1287 lowerBound = this._lowerBound(resource);
1288
1289 if (lowerBound !== -1 && (typeof this.minimumBoundary === "undefined" || lowerBound < this.minimumBoundary)) {
1290 this.minimumBoundary = lowerBound;
1291 didChange = true;
1292 }
1293
1294 var upperBound = this._upperBound(resource);
1295 if (upperBound !== -1 && (typeof this.maximumBoundary === "undefined" || upperBound > this.maximumBoundary)) {
1296 this.maximumBoundary = upperBound;
1297 didChange = true;
1298 }
1299
1300 return didChange;
1301 },
1302
1303 formatValue: function(value)
1304 {
1305 return Number.secondsToString(value, WebInspector.UIString.bind(WebInspe ctor));
1306 },
1307
1308 _lowerBound: function(resource)
1309 {
1310 return 0;
1311 },
1312
1313 _upperBound: function(resource)
1314 {
1315 return 0;
1316 },
1317 }
1318
1319 WebInspector.ResourceTimeCalculator.prototype.__proto__ = WebInspector.ResourceC alculator.prototype;
1320
1321 WebInspector.ResourceTransferTimeCalculator = function()
1322 {
1323 WebInspector.ResourceTimeCalculator.call(this, false);
1324 }
1325
1326 WebInspector.ResourceTransferTimeCalculator.prototype = {
1327 formatValue: function(value)
1328 {
1329 return Number.secondsToString(value, WebInspector.UIString.bind(WebInspe ctor));
1330 },
1331
1332 _lowerBound: function(resource)
1333 {
1334 return resource.startTime;
1335 },
1336
1337 _upperBound: function(resource)
1338 {
1339 return resource.endTime;
1340 }
1341 }
1342
1343 WebInspector.ResourceTransferTimeCalculator.prototype.__proto__ = WebInspector.R esourceTimeCalculator.prototype;
1344
1345 WebInspector.ResourceTransferDurationCalculator = function()
1346 {
1347 WebInspector.ResourceTimeCalculator.call(this, true);
1348 }
1349
1350 WebInspector.ResourceTransferDurationCalculator.prototype = {
1351 formatValue: function(value)
1352 {
1353 return Number.secondsToString(value, WebInspector.UIString.bind(WebInspe ctor));
1354 },
1355
1356 _upperBound: function(resource)
1357 {
1358 return resource.duration;
1359 }
1360 }
1361
1362 WebInspector.ResourceTransferDurationCalculator.prototype.__proto__ = WebInspect or.ResourceTimeCalculator.prototype;
1363
1364 WebInspector.ResourceTransferSizeCalculator = function()
1365 {
1366 WebInspector.ResourceCalculator.call(this);
1367 }
1368
1369 WebInspector.ResourceTransferSizeCalculator.prototype = {
1370 _value: function(resource)
1371 {
1372 return resource.contentLength;
1373 },
1374
1375 formatValue: function(value)
1376 {
1377 return Number.bytesToString(value, WebInspector.UIString.bind(WebInspect or));
1378 }
1379 }
1380
1381 WebInspector.ResourceTransferSizeCalculator.prototype.__proto__ = WebInspector.R esourceCalculator.prototype;
1382
1383 WebInspector.ResourceSidebarTreeElement = function(resource)
1384 {
1385 this.resource = resource;
1386
1387 this.createIconElement();
1388
1389 WebInspector.SidebarTreeElement.call(this, "resource-sidebar-tree-item", "", "", resource);
1390
1391 this.refreshTitles();
1392 }
1393
1394 WebInspector.ResourceSidebarTreeElement.prototype = {
1395 onattach: function()
1396 {
1397 WebInspector.SidebarTreeElement.prototype.onattach.call(this);
1398
1399 this._listItemNode.addStyleClass("resources-category-" + this.resource.c ategory.name);
1400 },
1401
1402 onselect: function()
1403 {
1404 WebInspector.panels.resources.showResource(this.resource);
1405 },
1406
1407 get mainTitle()
1408 {
1409 return this.resource.displayName;
1410 },
1411
1412 set mainTitle(x)
1413 {
1414 // Do nothing.
1415 },
1416
1417 get subtitle()
1418 {
1419 var subtitle = this.resource.displayDomain;
1420
1421 if (this.resource.path && this.resource.lastPathComponent) {
1422 var lastPathComponentIndex = this.resource.path.lastIndexOf("/" + th is.resource.lastPathComponent);
1423 if (lastPathComponentIndex != -1)
1424 subtitle += this.resource.path.substring(0, lastPathComponentInd ex);
1425 }
1426
1427 return subtitle;
1428 },
1429
1430 set subtitle(x)
1431 {
1432 // Do nothing.
1433 },
1434
1435 createIconElement: function()
1436 {
1437 var previousIconElement = this.iconElement;
1438
1439 if (this.resource.category === WebInspector.resourceCategories.images) {
1440 var previewImage = document.createElement("img");
1441 previewImage.className = "image-resource-icon-preview";
1442 previewImage.src = this.resource.url;
1443
1444 this.iconElement = document.createElement("div");
1445 this.iconElement.className = "icon";
1446 this.iconElement.appendChild(previewImage);
1447 } else {
1448 this.iconElement = document.createElement("img");
1449 this.iconElement.className = "icon";
1450 }
1451
1452 if (previousIconElement)
1453 previousIconElement.parentNode.replaceChild(this.iconElement, previo usIconElement);
1454 },
1455
1456 refresh: function()
1457 {
1458 this.refreshTitles();
1459
1460 if (!this._listItemNode.hasStyleClass("resources-category-" + this.resou rce.category.name)) {
1461 this._listItemNode.removeMatchingStyleClasses("resources-category-\\ w+");
1462 this._listItemNode.addStyleClass("resources-category-" + this.resour ce.category.name);
1463
1464 this.createIconElement();
1465 }
1466 },
1467
1468 resetBubble: function()
1469 {
1470 this.bubbleText = "";
1471 this.bubbleElement.removeStyleClass("search-matches");
1472 this.bubbleElement.removeStyleClass("warning");
1473 this.bubbleElement.removeStyleClass("error");
1474 },
1475
1476 set searchMatches(matches)
1477 {
1478 this.resetBubble();
1479
1480 if (!matches)
1481 return;
1482
1483 this.bubbleText = matches;
1484 this.bubbleElement.addStyleClass("search-matches");
1485 },
1486
1487 updateErrorsAndWarnings: function()
1488 {
1489 this.resetBubble();
1490
1491 if (this.resource.warnings || this.resource.errors)
1492 this.bubbleText = (this.resource.warnings + this.resource.errors);
1493
1494 if (this.resource.warnings)
1495 this.bubbleElement.addStyleClass("warning");
1496
1497 if (this.resource.errors)
1498 this.bubbleElement.addStyleClass("error");
1499 }
1500 }
1501
1502 WebInspector.ResourceSidebarTreeElement.CompareByAscendingStartTime = function(a , b)
1503 {
1504 return WebInspector.Resource.CompareByStartTime(a.resource, b.resource)
1505 || WebInspector.Resource.CompareByEndTime(a.resource, b.resource)
1506 || WebInspector.Resource.CompareByResponseReceivedTime(a.resource, b.res ource);
1507 }
1508
1509 WebInspector.ResourceSidebarTreeElement.CompareByAscendingResponseReceivedTime = function(a, b)
1510 {
1511 return WebInspector.Resource.CompareByResponseReceivedTime(a.resource, b.res ource)
1512 || WebInspector.Resource.CompareByStartTime(a.resource, b.resource)
1513 || WebInspector.Resource.CompareByEndTime(a.resource, b.resource);
1514 }
1515
1516 WebInspector.ResourceSidebarTreeElement.CompareByAscendingEndTime = function(a, b)
1517 {
1518 return WebInspector.Resource.CompareByEndTime(a.resource, b.resource)
1519 || WebInspector.Resource.CompareByStartTime(a.resource, b.resource)
1520 || WebInspector.Resource.CompareByResponseReceivedTime(a.resource, b.res ource);
1521 }
1522
1523 WebInspector.ResourceSidebarTreeElement.CompareByDescendingDuration = function(a , b)
1524 {
1525 return -1 * WebInspector.Resource.CompareByDuration(a.resource, b.resource);
1526 }
1527
1528 WebInspector.ResourceSidebarTreeElement.CompareByDescendingLatency = function(a, b)
1529 {
1530 return -1 * WebInspector.Resource.CompareByLatency(a.resource, b.resource);
1531 }
1532
1533 WebInspector.ResourceSidebarTreeElement.CompareByDescendingSize = function(a, b)
1534 {
1535 return -1 * WebInspector.Resource.CompareBySize(a.resource, b.resource);
1536 }
1537
1538 WebInspector.ResourceSidebarTreeElement.prototype.__proto__ = WebInspector.Sideb arTreeElement.prototype;
1539
1540 WebInspector.ResourceGraph = function(resource)
1541 {
1542 this.resource = resource;
1543
1544 this._graphElement = document.createElement("div");
1545 this._graphElement.className = "resources-graph-side";
1546 this._graphElement.addEventListener("mouseover", this.refreshLabelPositions. bind(this), false);
1547
1548 if (resource.cached)
1549 this._graphElement.addStyleClass("resource-cached");
1550
1551 this._barAreaElement = document.createElement("div");
1552 this._barAreaElement.className = "resources-graph-bar-area hidden";
1553 this._graphElement.appendChild(this._barAreaElement);
1554
1555 this._barLeftElement = document.createElement("div");
1556 this._barLeftElement.className = "resources-graph-bar waiting";
1557 this._barAreaElement.appendChild(this._barLeftElement);
1558
1559 this._barRightElement = document.createElement("div");
1560 this._barRightElement.className = "resources-graph-bar";
1561 this._barAreaElement.appendChild(this._barRightElement);
1562
1563 this._labelLeftElement = document.createElement("div");
1564 this._labelLeftElement.className = "resources-graph-label waiting";
1565 this._barAreaElement.appendChild(this._labelLeftElement);
1566
1567 this._labelRightElement = document.createElement("div");
1568 this._labelRightElement.className = "resources-graph-label";
1569 this._barAreaElement.appendChild(this._labelRightElement);
1570
1571 this._graphElement.addStyleClass("resources-category-" + resource.category.n ame);
1572 }
1573
1574 WebInspector.ResourceGraph.prototype = {
1575 get graphElement()
1576 {
1577 return this._graphElement;
1578 },
1579
1580 refreshLabelPositions: function()
1581 {
1582 this._labelLeftElement.style.removeProperty("left");
1583 this._labelLeftElement.style.removeProperty("right");
1584 this._labelLeftElement.removeStyleClass("before");
1585 this._labelLeftElement.removeStyleClass("hidden");
1586
1587 this._labelRightElement.style.removeProperty("left");
1588 this._labelRightElement.style.removeProperty("right");
1589 this._labelRightElement.removeStyleClass("after");
1590 this._labelRightElement.removeStyleClass("hidden");
1591
1592 const labelPadding = 10;
1593 const rightBarWidth = (this._barRightElement.offsetWidth - labelPadding) ;
1594 const leftBarWidth = ((this._barLeftElement.offsetWidth - this._barRight Element.offsetWidth) - labelPadding);
1595
1596 var labelBefore = (this._labelLeftElement.offsetWidth > leftBarWidth);
1597 var labelAfter = (this._labelRightElement.offsetWidth > rightBarWidth);
1598
1599 if (labelBefore) {
1600 if ((this._graphElement.offsetWidth * (this._percentages.start / 100 )) < (this._labelLeftElement.offsetWidth + 10))
1601 this._labelLeftElement.addStyleClass("hidden");
1602 this._labelLeftElement.style.setProperty("right", (100 - this._perce ntages.start) + "%");
1603 this._labelLeftElement.addStyleClass("before");
1604 } else {
1605 this._labelLeftElement.style.setProperty("left", this._percentages.s tart + "%");
1606 this._labelLeftElement.style.setProperty("right", (100 - this._perce ntages.middle) + "%");
1607 }
1608
1609 if (labelAfter) {
1610 if ((this._graphElement.offsetWidth * ((100 - this._percentages.end) / 100)) < (this._labelRightElement.offsetWidth + 10))
1611 this._labelRightElement.addStyleClass("hidden");
1612 this._labelRightElement.style.setProperty("left", this._percentages. end + "%");
1613 this._labelRightElement.addStyleClass("after");
1614 } else {
1615 this._labelRightElement.style.setProperty("left", this._percentages. middle + "%");
1616 this._labelRightElement.style.setProperty("right", (100 - this._perc entages.end) + "%");
1617 }
1618 },
1619
1620 refresh: function(calculator)
1621 {
1622 var percentages = calculator.computeBarGraphPercentages(this.resource);
1623 var labels = calculator.computeBarGraphLabels(this.resource);
1624
1625 this._percentages = percentages;
1626
1627 this._barAreaElement.removeStyleClass("hidden");
1628
1629 if (!this._graphElement.hasStyleClass("resources-category-" + this.resou rce.category.name)) {
1630 this._graphElement.removeMatchingStyleClasses("resources-category-\\ w+");
1631 this._graphElement.addStyleClass("resources-category-" + this.resour ce.category.name);
1632 }
1633
1634 this._barLeftElement.style.setProperty("left", percentages.start + "%");
1635 this._barLeftElement.style.setProperty("right", (100 - percentages.end) + "%");
1636
1637 this._barRightElement.style.setProperty("left", percentages.middle + "%" );
1638 this._barRightElement.style.setProperty("right", (100 - percentages.end) + "%");
1639
1640 this._labelLeftElement.textContent = labels.left;
1641 this._labelRightElement.textContent = labels.right;
1642
1643 var tooltip = (labels.tooltip || "");
1644 this._barLeftElement.title = tooltip;
1645 this._labelLeftElement.title = tooltip;
1646 this._labelRightElement.title = tooltip;
1647 this._barRightElement.title = tooltip;
1648 }
1649 }
OLDNEW
« no previous file with comments | « chrome/resources/Inspector/ResourceView.js ('k') | chrome/resources/Inspector/ScriptsPanel.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698