Index: Source/devtools/front_end/timeline/TimelineView.js |
diff --git a/Source/devtools/front_end/timeline/TimelineView.js b/Source/devtools/front_end/timeline/TimelineView.js |
index bf2c6dcfe4ad2e4b13def948e3ed2aa24b904f42..00fa1764fabca19bf90b2e3c21c092b4c1a499ab 100644 |
--- a/Source/devtools/front_end/timeline/TimelineView.js |
+++ b/Source/devtools/front_end/timeline/TimelineView.js |
@@ -46,6 +46,7 @@ WebInspector.TimelineView = function(delegate, model) |
this._presentationModel = new WebInspector.TimelinePresentationModel(model); |
this._calculator = new WebInspector.TimelineCalculator(model); |
this._linkifier = new WebInspector.Linkifier(); |
+ this._frameStripByFrame = new Map(); |
this._boundariesAreValid = true; |
this._scrollTop = 0; |
@@ -142,16 +143,18 @@ WebInspector.TimelineView.prototype = { |
_updateFrameBars: function(frames) |
{ |
var clientWidth = this._graphRowsElementWidth; |
- if (this._frameContainer) |
+ if (this._frameContainer) { |
this._frameContainer.removeChildren(); |
- else { |
+ } else { |
const frameContainerBorderWidth = 1; |
this._frameContainer = document.createElement("div"); |
this._frameContainer.classList.add("fill"); |
this._frameContainer.classList.add("timeline-frame-container"); |
this._frameContainer.style.height = WebInspector.TimelinePanel.rowHeight + frameContainerBorderWidth + "px"; |
this._frameContainer.addEventListener("dblclick", this._onFrameDoubleClicked.bind(this), false); |
+ this._frameContainer.addEventListener("click", this._onFrameClicked.bind(this), false); |
} |
+ this._frameStripByFrame.clear(); |
var dividers = []; |
@@ -167,6 +170,7 @@ WebInspector.TimelineView.prototype = { |
frameStrip.style.left = actualStart + "px"; |
frameStrip.style.width = width + "px"; |
frameStrip._frame = frame; |
+ this._frameStripByFrame.put(frame, frameStrip); |
const minWidthForFrameInfo = 60; |
if (width > minWidthForFrameInfo) |
@@ -192,6 +196,14 @@ WebInspector.TimelineView.prototype = { |
this._delegate.requestWindowTimes(frameBar._frame.startTime, frameBar._frame.endTime); |
}, |
+ _onFrameClicked: function(event) |
+ { |
+ var frameBar = event.target.enclosingNodeOrSelfWithClass("timeline-frame-strip"); |
+ if (!frameBar) |
+ return; |
+ this._delegate.select(WebInspector.TimelineSelection.fromFrame(frameBar._frame)); |
+ }, |
+ |
/** |
* @param {!WebInspector.TimelineModel.Record} record |
*/ |
@@ -312,12 +324,17 @@ WebInspector.TimelineView.prototype = { |
this._scheduleRefresh(preserveBoundaries, userGesture); |
}, |
+ _clearSelection: function() |
+ { |
+ this._delegate.select(null); |
+ }, |
+ |
/** |
* @param {?WebInspector.TimelinePresentationModel.Record} presentationRecord |
*/ |
_selectRecord: function(presentationRecord) |
{ |
- if (presentationRecord && presentationRecord.coalesced()) { |
+ if (presentationRecord.coalesced()) { |
// Presentation record does not have model record to highlight. |
this._innerSetSelectedRecord(presentationRecord); |
var aggregatedStats = {}; |
@@ -332,15 +349,28 @@ WebInspector.TimelineView.prototype = { |
this._delegate.showInDetails(WebInspector.TimelineUIUtils.recordStyle(presentationRecord.record()).title, pieChart); |
return; |
} |
- this._delegate.selectRecord(presentationRecord ? presentationRecord.record() : null); |
+ this._delegate.select(WebInspector.TimelineSelection.fromRecord(presentationRecord.record())); |
}, |
/** |
- * @param {?WebInspector.TimelineModel.Record} record |
+ * @param {?WebInspector.TimelineSelection} selection |
*/ |
- setSelectedRecord: function(record) |
+ setSelection: function(selection) |
{ |
- this._innerSetSelectedRecord(this._presentationModel.toPresentationRecord(record)); |
+ if (!selection) { |
+ this._innerSetSelectedRecord(null); |
+ this._setSelectedFrame(null); |
+ return; |
+ } |
+ if (selection.type() === WebInspector.TimelineSelection.Type.Record) { |
+ var record = /** @type {!WebInspector.TimelineModel.Record} */ (selection.object()); |
+ this._innerSetSelectedRecord(this._presentationModel.toPresentationRecord(record)); |
+ this._setSelectedFrame(null); |
+ } else if (selection.type() === WebInspector.TimelineSelection.Type.Frame) { |
+ var frame = /** @type {!WebInspector.TimelineFrame} */ (selection.object()); |
+ this._innerSetSelectedRecord(null); |
+ this._setSelectedFrame(frame); |
+ } |
}, |
/** |
@@ -371,6 +401,22 @@ WebInspector.TimelineView.prototype = { |
}, |
/** |
+ * @param {?WebInspector.TimelineFrame} frame |
+ */ |
+ _setSelectedFrame: function(frame) |
+ { |
+ if (this._lastSelectedFrame === frame) |
+ return; |
+ var oldStripElement = this._lastSelectedFrame && this._frameStripByFrame.get(this._lastSelectedFrame); |
+ if (oldStripElement) |
+ oldStripElement.classList.remove("selected"); |
+ var newStripElement = frame && this._frameStripByFrame.get(frame); |
+ if (newStripElement) |
+ newStripElement.classList.add("selected"); |
+ this._lastSelectedFrame = frame; |
+ }, |
+ |
+ /** |
* @param {number} startTime |
* @param {number} endTime |
*/ |
@@ -381,7 +427,7 @@ WebInspector.TimelineView.prototype = { |
this._presentationModel.setWindowTimes(startTime, endTime); |
this._automaticallySizeWindow = false; |
this._invalidateAndScheduleRefresh(false, true); |
- this._selectRecord(null); |
+ this._clearSelection(); |
}, |
/** |
@@ -487,7 +533,7 @@ WebInspector.TimelineView.prototype = { |
var lastVisibleLine = Math.max(0, Math.floor((visibleBottom - headerHeight) / rowHeight)); |
if (this._automaticallySizeWindow && recordsInWindow.length > lastVisibleLine) { |
this._automaticallySizeWindow = false; |
- this._selectRecord(null); |
+ this._clearSelection(); |
// If we're at the top, always use real timeline start as a left window bound so that expansion arrow padding logic works. |
var windowStartTime = startIndex ? recordsInWindow[startIndex].record().startTime() : this._model.minimumRecordTime(); |
var windowEndTime = recordsInWindow[Math.max(0, lastVisibleLine - 1)].record().endTime(); |
@@ -670,7 +716,7 @@ WebInspector.TimelineView.prototype = { |
var anchor = element.enclosingNodeOrSelfWithClass("timeline-graph-bar"); |
if (anchor && anchor._tasksInfo) |
return anchor; |
- return element.enclosingNodeOrSelfWithClass("timeline-frame-strip"); |
+ return null; |
}, |
_mouseOut: function() |
@@ -802,17 +848,9 @@ WebInspector.TimelineView.prototype = { |
*/ |
_showPopover: function(anchor, popover) |
{ |
- if (anchor.classList.contains("timeline-frame-strip")) { |
- var frame = anchor._frame; |
- popover.show(WebInspector.TimelineUIUtils.generatePopupContentForFrame(frame), anchor); |
- } else if (anchor._tasksInfo) { |
- popover.show(WebInspector.TimelineUIUtils.generateMainThreadBarPopupContent(this._model, anchor._tasksInfo), anchor, null, null, WebInspector.Popover.Orientation.Bottom); |
- } |
- |
- function showCallback(popupContent) |
- { |
- popover.show(popupContent, anchor); |
- } |
+ if (!anchor._tasksInfo) |
+ return; |
+ popover.show(WebInspector.TimelineUIUtils.generateMainThreadBarPopupContent(this._model, anchor._tasksInfo), anchor, null, null, WebInspector.Popover.Orientation.Bottom); |
}, |
_closeRecordDetails: function() |