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

Side by Side Diff: resources/inspector/ResourcesPanel.js

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

Powered by Google App Engine
This is Rietveld 408576698