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