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

Side by Side Diff: Source/devtools/front_end/timeline/TimelineTreeView.js

Issue 1312903005: DevTools: Make functions on timeline tree view point to the right source location (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 3 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
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * @constructor 6 * @constructor
7 * @extends {WebInspector.VBox} 7 * @extends {WebInspector.VBox}
8 * @param {!WebInspector.TimelineModel} model 8 * @param {!WebInspector.TimelineModel} model
9 */ 9 */
10 WebInspector.TimelineTreeView = function(model) 10 WebInspector.TimelineTreeView = function(model)
11 { 11 {
12 WebInspector.VBox.call(this); 12 WebInspector.VBox.call(this);
13 this.element.classList.add("timeline-tree-view"); 13 this.element.classList.add("timeline-tree-view");
14 14
15 this._model = model; 15 this._model = model;
16 this._linkifier = new WebInspector.Linkifier();
pfeldman 2015/08/29 00:40:45 You need to reset the linkifier upon dispose.
alph 2015/09/01 21:38:55 The tree view is never disposed. Added reset on tr
16 var columns = []; 17 var columns = [];
17 columns.push({id: "self", title: WebInspector.UIString("Self Time"), width: "120px", sort: WebInspector.DataGrid.Order.Descending, sortable: true}); 18 columns.push({id: "self", title: WebInspector.UIString("Self Time"), width: "120px", sort: WebInspector.DataGrid.Order.Descending, sortable: true});
18 columns.push({id: "total", title: WebInspector.UIString("Total Time"), width : "120px", sortable: true}); 19 columns.push({id: "total", title: WebInspector.UIString("Total Time"), width : "120px", sortable: true});
19 columns.push({id: "activity", title: WebInspector.UIString("Activity"), disc losure: true, sortable: true}); 20 columns.push({id: "activity", title: WebInspector.UIString("Activity"), disc losure: true, sortable: true});
20 21
21 var nonessentialEvents = [ 22 var nonessentialEvents = [
22 WebInspector.TimelineModel.RecordType.EventDispatch, 23 WebInspector.TimelineModel.RecordType.EventDispatch,
23 WebInspector.TimelineModel.RecordType.FunctionCall, 24 WebInspector.TimelineModel.RecordType.FunctionCall,
24 WebInspector.TimelineModel.RecordType.TimerFire 25 WebInspector.TimelineModel.RecordType.TimerFire
25 ]; 26 ];
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 if (id === this._groupBySetting.get()) 92 if (id === this._groupBySetting.get())
92 this._groupByCombobox.select(option); 93 this._groupByCombobox.select(option);
93 } 94 }
94 addGroupingOption.call(this, WebInspector.UIString("No Grouping"), WebIn spector.TimelineTreeView.GroupBy.None); 95 addGroupingOption.call(this, WebInspector.UIString("No Grouping"), WebIn spector.TimelineTreeView.GroupBy.None);
95 addGroupingOption.call(this, WebInspector.UIString("Group by Domain"), W ebInspector.TimelineTreeView.GroupBy.Domain); 96 addGroupingOption.call(this, WebInspector.UIString("Group by Domain"), W ebInspector.TimelineTreeView.GroupBy.Domain);
96 addGroupingOption.call(this, WebInspector.UIString("Group by Subdomain") , WebInspector.TimelineTreeView.GroupBy.Subdomain); 97 addGroupingOption.call(this, WebInspector.UIString("Group by Subdomain") , WebInspector.TimelineTreeView.GroupBy.Subdomain);
97 addGroupingOption.call(this, WebInspector.UIString("Group by URL"), WebI nspector.TimelineTreeView.GroupBy.URL); 98 addGroupingOption.call(this, WebInspector.UIString("Group by URL"), WebI nspector.TimelineTreeView.GroupBy.URL);
98 panelToolbar.appendToolbarItem(this._groupByCombobox); 99 panelToolbar.appendToolbarItem(this._groupByCombobox);
99 }, 100 },
100 101
102 /**
103 * @param {?string} scriptId
104 * @param {string} url
105 * @param {number} lineNumber
106 * @param {number=} columnNumber
107 * @return {!Element}
108 */
109 linkifyLocation: function(scriptId, url, lineNumber, columnNumber)
110 {
111 return this._linkifier.linkifyScriptLocation(this._model.target(), scrip tId, url, lineNumber, columnNumber);
112 },
113
101 _onTreeModeChanged: function() 114 _onTreeModeChanged: function()
102 { 115 {
103 this._refreshTree(); 116 this._refreshTree();
104 }, 117 },
105 118
106 _onGroupByChanged: function() 119 _onGroupByChanged: function()
107 { 120 {
108 this._groupBySetting.set(this._groupByCombobox.selectedOption().value); 121 this._groupBySetting.set(this._groupByCombobox.selectedOption().value);
109 this._refreshTree(); 122 this._refreshTree();
110 }, 123 },
111 124
112 _refreshTree: function() 125 _refreshTree: function()
113 { 126 {
114 this.dataGrid.rootNode().removeChildren(); 127 this.dataGrid.rootNode().removeChildren();
115 var topDown = WebInspector.TimelineModel.buildTopDownTree( 128 var topDown = WebInspector.TimelineModel.buildTopDownTree(
116 this._model.mainThreadEvents(), this._startTime, this._endTime, this ._filters, WebInspector.TimelineTreeView.eventId); 129 this._model.mainThreadEvents(), this._startTime, this._endTime, this ._filters, WebInspector.TimelineTreeView.eventId);
117 var isTopDown = this._modeCombobox.selectedOption().value === WebInspect or.TimelineTreeView.Mode.TopDown; 130 var isTopDown = this._modeCombobox.selectedOption().value === WebInspect or.TimelineTreeView.Mode.TopDown;
118 var tree = isTopDown ? this._preformTopDownTreeGrouping(topDown) : this. _buildBottomUpTree(topDown); 131 var tree = isTopDown ? this._preformTopDownTreeGrouping(topDown) : this. _buildBottomUpTree(topDown);
119 this.dataGrid.markColumnAsSortedBy(isTopDown ? "total" : "self", WebInsp ector.DataGrid.Order.Descending); 132 this.dataGrid.markColumnAsSortedBy(isTopDown ? "total" : "self", WebInsp ector.DataGrid.Order.Descending);
120 var maxSelfTime = 0; 133 var maxSelfTime = 0;
121 var maxTotalTime = 0; 134 var maxTotalTime = 0;
122 for (var child of tree.children.values()) { 135 for (var child of tree.children.values()) {
123 maxSelfTime = Math.max(maxSelfTime, child.selfTime); 136 maxSelfTime = Math.max(maxSelfTime, child.selfTime);
124 maxTotalTime = Math.max(maxTotalTime, child.totalTime); 137 maxTotalTime = Math.max(maxTotalTime, child.totalTime);
125 } 138 }
126 for (var child of tree.children.values()) { 139 for (var child of tree.children.values()) {
127 // Exclude the idle time off the total calculation. 140 // Exclude the idle time off the total calculation.
128 var gridNode = new WebInspector.TimelineTreeView.GridNode(child, top Down.totalTime, maxSelfTime, maxTotalTime); 141 var gridNode = new WebInspector.TimelineTreeView.GridNode(child, top Down.totalTime, maxSelfTime, maxTotalTime, this);
129 this.dataGrid.insertChild(gridNode); 142 this.dataGrid.insertChild(gridNode);
130 } 143 }
131 this._sortingChanged(); 144 this._sortingChanged();
132 }, 145 },
133 146
134 /** 147 /**
135 * @param {!WebInspector.TimelineModel.ProfileTreeNode} topDownTree 148 * @param {!WebInspector.TimelineModel.ProfileTreeNode} topDownTree
136 * @return {!WebInspector.TimelineModel.ProfileTreeNode} 149 * @return {!WebInspector.TimelineModel.ProfileTreeNode}
137 */ 150 */
138 _preformTopDownTreeGrouping: function(topDownTree) 151 _preformTopDownTreeGrouping: function(topDownTree)
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 { 291 {
279 if (event.name === WebInspector.TimelineModel.RecordType.JSFrame) { 292 if (event.name === WebInspector.TimelineModel.RecordType.JSFrame) {
280 var data = event.args["data"]; 293 var data = event.args["data"];
281 return "f:" + data["functionName"] + "@" + (data["scriptId"] || data["ur l"] || ""); 294 return "f:" + data["functionName"] + "@" + (data["scriptId"] || data["ur l"] || "");
282 } 295 }
283 return event.name + ":@" + WebInspector.TimelineTreeView.eventURL(event); 296 return event.name + ":@" + WebInspector.TimelineTreeView.eventURL(event);
284 } 297 }
285 298
286 /** 299 /**
287 * @param {!WebInspector.TracingModel.Event} event 300 * @param {!WebInspector.TracingModel.Event} event
301 * @return {?Object}
302 */
303 WebInspector.TimelineTreeView.eventStackFrame = function(event)
304 {
305 var data = event.args["data"] || event.args["beginData"];
306 if (data)
307 return data;
308 var topFrame = event.stackTrace && event.stackTrace[0];
309 if (topFrame)
310 return topFrame;
311 var initiator = event.initiator;
312 return initiator && initiator.stackTrace && initiator.stackTrace[0] || null;
313 }
314
315 /**
316 * @param {!WebInspector.TracingModel.Event} event
288 * @return {?string} 317 * @return {?string}
289 */ 318 */
290 WebInspector.TimelineTreeView.eventURL = function(event) 319 WebInspector.TimelineTreeView.eventURL = function(event)
291 { 320 {
292 var data = event.args["data"] || event.args["beginData"]; 321 var frame = WebInspector.TimelineTreeView.eventStackFrame(event);
293 var url = data && data["url"]; 322 return frame && frame["url"] || null;
294 if (url)
295 return url;
296 var topFrame = event.stackTrace && event.stackTrace[0];
297 url = topFrame && topFrame["url"];
298 if (url)
299 return url;
300 var initiator = event.initiator;
301 var initiatorTopFrame = initiator && initiator.stackTrace && initiator.stack Trace[0];
302 return initiatorTopFrame && initiatorTopFrame["url"] || null;
303 } 323 }
304 324
305 /** 325 /**
306 * @constructor 326 * @constructor
307 * @extends {WebInspector.SortableDataGridNode} 327 * @extends {WebInspector.SortableDataGridNode}
308 * @param {!WebInspector.TimelineModel.ProfileTreeNode} profileNode 328 * @param {!WebInspector.TimelineModel.ProfileTreeNode} profileNode
309 * @param {number} grandTotalTime 329 * @param {number} grandTotalTime
310 * @param {number} maxSelfTime 330 * @param {number} maxSelfTime
311 * @param {number} maxTotalTime 331 * @param {number} maxTotalTime
332 * @param {!WebInspector.TimelineTreeView} treeView
312 */ 333 */
313 WebInspector.TimelineTreeView.GridNode = function(profileNode, grandTotalTime, m axSelfTime, maxTotalTime) 334 WebInspector.TimelineTreeView.GridNode = function(profileNode, grandTotalTime, m axSelfTime, maxTotalTime, treeView)
314 { 335 {
315 /** 336 /**
316 * @param {number} time 337 * @param {number} time
317 * @return {string} 338 * @return {string}
318 */ 339 */
319 function formatMilliseconds(time) 340 function formatMilliseconds(time)
320 { 341 {
321 return WebInspector.UIString("%.1f\u2009ms", time); 342 return WebInspector.UIString("%.1f\u2009ms", time);
322 } 343 }
323 /** 344 /**
324 * @param {number} value 345 * @param {number} value
325 * @return {string} 346 * @return {string}
326 */ 347 */
327 function formatPercent(value) 348 function formatPercent(value)
328 { 349 {
329 return WebInspector.UIString("%.2f\u2009%%", value); 350 return WebInspector.UIString("%.2f\u2009%%", value);
330 } 351 }
331 352
332 this._populated = false; 353 this._populated = false;
333 this._profileNode = profileNode; 354 this._profileNode = profileNode;
355 this._treeView = treeView;
334 this._totalTime = grandTotalTime; 356 this._totalTime = grandTotalTime;
335 this._maxTimes = { self: maxSelfTime, total: maxTotalTime }; 357 this._maxTimes = { self: maxSelfTime, total: maxTotalTime };
336 var selfTime = profileNode.selfTime; 358 var selfTime = profileNode.selfTime;
337 var selfPercent = selfTime / grandTotalTime * 100; 359 var selfPercent = selfTime / grandTotalTime * 100;
338 var totalTime = profileNode.totalTime; 360 var totalTime = profileNode.totalTime;
339 var totalPercent = totalTime / grandTotalTime * 100; 361 var totalPercent = totalTime / grandTotalTime * 100;
340 var data = { 362 var data = {
341 "activity": profileNode.name, 363 "activity": profileNode.name,
342 "self-percent": formatPercent(selfPercent), 364 "self-percent": formatPercent(selfPercent),
343 "self": formatMilliseconds(selfTime), 365 "self": formatMilliseconds(selfTime),
(...skipping 26 matching lines...) Expand all
370 var cell = this.createTD(columnIdentifier); 392 var cell = this.createTD(columnIdentifier);
371 var container = cell.createChild("div", "name-container"); 393 var container = cell.createChild("div", "name-container");
372 var icon = container.createChild("div", "activity-icon"); 394 var icon = container.createChild("div", "activity-icon");
373 var name = container.createChild("div", "activity-name"); 395 var name = container.createChild("div", "activity-name");
374 var link = container.createChild("div", "activity-link"); 396 var link = container.createChild("div", "activity-link");
375 var event = this._profileNode.event; 397 var event = this._profileNode.event;
376 if (event) { 398 if (event) {
377 name.textContent = event.name === WebInspector.TimelineModel.RecordT ype.JSFrame 399 name.textContent = event.name === WebInspector.TimelineModel.RecordT ype.JSFrame
378 ? WebInspector.beautifyFunctionName(event.args["data"]["function Name"]) 400 ? WebInspector.beautifyFunctionName(event.args["data"]["function Name"])
379 : WebInspector.TimelineUIUtils.eventTitle(event); 401 : WebInspector.TimelineUIUtils.eventTitle(event);
380 var url = WebInspector.TimelineTreeView.eventURL(event); 402 var frame = WebInspector.TimelineTreeView.eventStackFrame(event);
403 var scriptId = frame && frame["scriptId"];
404 var url = frame && frame["url"];
405 var lineNumber = frame && frame["lineNumber"] || 0;
yurys 2015/08/29 00:44:18 Don't we start line numbering from 1 in the UI?
alph 2015/09/01 21:38:55 Done.
406 var columnNumber = frame && frame["columnNumber"];
381 if (url) 407 if (url)
382 link.appendChild(WebInspector.linkifyResourceAsNode(url)); 408 link.appendChild(this._treeView.linkifyLocation(scriptId, url, l ineNumber, columnNumber));
yurys 2015/08/29 00:44:18 When do you clear the linkifier?
alph 2015/09/01 21:38:55 Added reset on tree repopulate.
383 var category = WebInspector.TimelineUIUtils.eventStyle(event).catego ry; 409 var category = WebInspector.TimelineUIUtils.eventStyle(event).catego ry;
384 icon.style.backgroundColor = category.fillColorStop1; 410 icon.style.backgroundColor = category.fillColorStop1;
385 } else { 411 } else {
386 name.textContent = this._profileNode.name; 412 name.textContent = this._profileNode.name;
387 icon.style.backgroundColor = WebInspector.TimelineUIUtils.colorForUR L(this._profileNode.name); 413 icon.style.backgroundColor = WebInspector.TimelineUIUtils.colorForUR L(this._profileNode.name);
388 } 414 }
389 return cell; 415 return cell;
390 }, 416 },
391 417
392 /** 418 /**
(...skipping 21 matching lines...) Expand all
414 * @override 440 * @override
415 */ 441 */
416 populate: function() 442 populate: function()
417 { 443 {
418 if (this._populated) 444 if (this._populated)
419 return; 445 return;
420 this._populated = true; 446 this._populated = true;
421 if (!this._profileNode.children) 447 if (!this._profileNode.children)
422 return; 448 return;
423 for (var node of this._profileNode.children.values()) { 449 for (var node of this._profileNode.children.values()) {
424 var gridNode = new WebInspector.TimelineTreeView.GridNode(node, this ._totalTime, this._maxTimes.self, this._maxTimes.total); 450 var gridNode = new WebInspector.TimelineTreeView.GridNode(node, this ._totalTime, this._maxTimes.self, this._maxTimes.total, this._treeView);
425 this.insertChildOrdered(gridNode); 451 this.insertChildOrdered(gridNode);
426 } 452 }
427 }, 453 },
428 454
429 __proto__: WebInspector.SortableDataGridNode.prototype 455 __proto__: WebInspector.SortableDataGridNode.prototype
430 } 456 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698