* @implements {WebInspector.TimelineModeView}
* @param {!WebInspector.TimelineModeViewDelegate} delegate
* @param {!WebInspector.TimelineModel} model
+ * @param {!WebInspector.TimelineUIUtils} uiUtils
*/
-WebInspector.TimelineView = function(delegate, model)
+WebInspector.TimelineView = function(delegate, model, uiUtils)
{
WebInspector.HBox.call(this);
this.element.classList.add("timeline-view");
this._delegate = delegate;
this._model = model;
- this._presentationModel = new WebInspector.TimelinePresentationModel(model);
+ this._uiUtils = uiUtils;
+ this._presentationModel = new WebInspector.TimelinePresentationModel(model, uiUtils);
this._calculator = new WebInspector.TimelineCalculator(model);
this._linkifier = new WebInspector.Linkifier();
this._frameStripByFrame = new Map();
// Create gpu tasks containers.
this._cpuBarsElement = this._headerElement.createChild("div", "timeline-utilization-strip");
- if (WebInspector.experimentsSettings.gpuTimeline.isEnabled())
+ if (Runtime.experiments.isEnabled("gpuTimeline"))
this._gpuBarsElement = this._headerElement.createChild("div", "timeline-utilization-strip gpu");
this._popoverHelper = new WebInspector.PopoverHelper(this.element, this._getPopoverAnchor.bind(this), this._showPopover.bind(this));
WebInspector.TimelineView.prototype = {
/**
- * @param {?WebInspector.TimelineFrameModel} frameModel
+ * @param {?WebInspector.TimelineFrameModelBase} frameModel
*/
setFrameModel: function(frameModel)
{
for (var i = 0; i < eventDividerRecords.length; ++i) {
var record = eventDividerRecords[i];
- var positions = this._calculator.computeBarGraphWindowPosition(record);
- var dividerPosition = Math.round(positions.left);
+ var position = this._calculator.computePosition(record.startTime());
+ var dividerPosition = Math.round(position);
if (dividerPosition < 0 || dividerPosition >= clientWidth || dividers[dividerPosition])
continue;
- var divider = WebInspector.TimelineUIUtils.createEventDivider(record.type(), WebInspector.TimelineUIUtils.recordTitle(record, this._model));
+ var title = this._uiUtils.titleForRecord(record);
+ var divider = this._uiUtils.createEventDivider(record.type(), title);
divider.style.left = dividerPosition + "px";
dividers[dividerPosition] = divider;
}
this._frameContainer.removeChildren();
} else {
const frameContainerBorderWidth = 1;
- this._frameContainer = document.createElement("div");
- this._frameContainer.classList.add("fill");
- this._frameContainer.classList.add("timeline-frame-container");
+ this._frameContainer = document.createElementWithClass("div", "fill 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);
var frameStart = this._calculator.computePosition(frame.startTime);
var frameEnd = this._calculator.computePosition(frame.endTime);
- var frameStrip = document.createElement("div");
- frameStrip.className = "timeline-frame-strip";
+ var frameStrip = document.createElementWithClass("div", "timeline-frame-strip");
var actualStart = Math.max(frameStart, 0);
var width = frameEnd - actualStart;
frameStrip.style.left = actualStart + "px";
frameStrip.style.width = width + "px";
frameStrip._frame = frame;
- this._frameStripByFrame.put(frame, frameStrip);
+ this._frameStripByFrame.set(frame, frameStrip);
const minWidthForFrameInfo = 60;
if (width > minWidthForFrameInfo)
this._frameContainer.appendChild(frameStrip);
if (actualStart > 0) {
- var frameMarker = WebInspector.TimelineUIUtils.createEventDivider(WebInspector.TimelineModel.RecordType.BeginFrame);
+ var frameMarker = this._uiUtils.createBeginFrameDivider();
frameMarker.style.left = frameStart + "px";
dividers.push(frameMarker);
}
_resetView: function()
{
- this._windowStartTime = -1;
- this._windowEndTime = -1;
+ this._windowStartTime = 0;
+ this._windowEndTime = 0;
this._boundariesAreValid = false;
this._adjustScrollPosition(0);
this._linkifier.reset();
*/
refreshRecords: function(textFilter)
{
- this._presentationModel.reset();
- var records = this._model.records();
- for (var i = 0; i < records.length; ++i)
- this.addRecord(records[i]);
this._automaticallySizeWindow = false;
this._presentationModel.setTextFilter(textFilter);
this._invalidateAndScheduleRefresh(false, true);
WebInspector.View.prototype.willHide.call(this);
},
+ wasShown: function()
+ {
+ this._presentationModel.refreshRecords();
+ WebInspector.HBox.prototype.wasShown.call(this);
+ },
+
_onScroll: function(event)
{
this._closeRecordDetails();
var aggregatedStats = {};
var presentationChildren = presentationRecord.presentationChildren();
for (var i = 0; i < presentationChildren.length; ++i)
- WebInspector.TimelineUIUtils.aggregateTimeByCategory(aggregatedStats, presentationChildren[i].record().aggregatedStats);
- var idle = presentationRecord.record().endTime() - presentationRecord.record().startTime();
+ this._uiUtils.aggregateTimeForRecord(aggregatedStats, presentationChildren[i].record());
+ var idle = presentationRecord.endTime() - presentationRecord.startTime();
for (var category in aggregatedStats)
idle -= aggregatedStats[category];
aggregatedStats["idle"] = idle;
var pieChart = WebInspector.TimelineUIUtils.generatePieChart(aggregatedStats);
- this._delegate.showInDetails(WebInspector.TimelineUIUtils.recordStyle(presentationRecord.record()).title, pieChart);
+ var title = this._uiUtils.titleForRecord(presentationRecord.record());
+ this._delegate.showInDetails(title, pieChart);
return;
}
this._delegate.select(WebInspector.TimelineSelection.fromRecord(presentationRecord.record()));
clearTimeout(this._refreshTimeout);
delete this._refreshTimeout;
}
- var windowStartTime = this._windowStartTime;
- var windowEndTime = this._windowEndTime;
+ var windowStartTime = this._windowStartTime || this._model.minimumRecordTime();
+ var windowEndTime = this._windowEndTime || this._model.maximumRecordTime();
this._timelinePaddingLeft = this._expandOffset;
- if (windowStartTime === -1)
- windowStartTime = this._model.minimumRecordTime();
- if (windowEndTime === -1)
- windowEndTime = this._model.maximumRecordTime();
this._calculator.setWindow(windowStartTime, windowEndTime);
this._calculator.setDisplayWindow(this._timelinePaddingLeft, this._graphRowsElementWidth);
this._automaticallySizeWindow = false;
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();
+ var windowStartTime = startIndex ? recordsInWindow[startIndex].startTime() : this._model.minimumRecordTime();
+ var windowEndTime = recordsInWindow[Math.max(0, lastVisibleLine - 1)].endTime();
this._delegate.requestWindowTimes(windowStartTime, windowEndTime);
recordsInWindow = this._presentationModel.filteredRecords();
endIndex = Math.min(recordsInWindow.length, lastVisibleLine);
var lastChildIndex = i + record.visibleChildrenCount();
if (lastChildIndex >= startIndex && lastChildIndex < endIndex) {
var expandElement = new WebInspector.TimelineExpandableElement(this._expandElements);
- var positions = this._calculator.computeBarGraphWindowPosition(record.record());
+ var positions = this._calculator.computeBarGraphWindowPosition(record);
expandElement._update(record, i, positions.left - this._expandOffset, positions.width);
}
} else {
this._graphRowsElement.appendChild(graphRowElement);
}
- listRowElement.row.update(record, visibleTop, this._model.loadedFromFile());
- graphRowElement.row.update(record, this._calculator, this._expandOffset, i);
+ listRowElement.row.update(record, visibleTop, this._uiUtils);
+ graphRowElement.row.update(record, this._calculator, this._expandOffset, i, this._uiUtils);
if (this._lastSelectedRecord === record) {
listRowElement.row.renderAsSelected(true);
graphRowElement.row.renderAsSelected(true);
_refreshAllUtilizationBars: function()
{
this._refreshUtilizationBars(WebInspector.UIString("CPU"), this._model.mainThreadTasks(), this._cpuBarsElement);
- if (WebInspector.experimentsSettings.gpuTimeline.isEnabled())
+ if (Runtime.experiments.isEnabled("gpuTimeline"))
this._refreshUtilizationBars(WebInspector.UIString("GPU"), this._model.gpuThreadTasks(), this._gpuBarsElement);
},
var taskIndex = insertionIndexForObjectInListSortedByFunction(startTime, tasks, compareEndTime);
var foreignStyle = "gpu-task-foreign";
- var element = container.firstChild;
+ var element = /** @type {?Element} */ (container.firstChild);
var lastElement;
var lastLeft;
var lastRight;
lastLeft = left;
lastRight = right;
lastElement = element;
- element = element.nextSibling;
+ element = /** @type {?Element} */ (element.nextSibling);
}
if (lastElement)
this._containerElement.scrollTop = (totalHeight - this._containerElement.offsetHeight);
},
- _getPopoverAnchor: function(element)
+ /**
+ * @param {!Element} element
+ * @param {!Event} event
+ * @return {!Element|!AnchorBox|undefined}
+ */
+ _getPopoverAnchor: function(element, event)
{
var anchor = element.enclosingNodeOrSelfWithClass("timeline-graph-bar");
if (anchor && anchor._tasksInfo)
return anchor;
- return null;
},
_mouseOut: function()
},
/**
- * @param {?Event} e
+ * @param {!Event} e
*/
_mouseMove: function(e)
{
var rowElement = e.target.enclosingNodeOrSelfWithClass("timeline-tree-item");
- if (rowElement && rowElement.row && rowElement.row._record.record().highlightQuad)
- this._highlightQuad(rowElement.row._record.record());
- else
+ if (!this._highlightQuad(rowElement))
this._hideQuadHighlight();
var taskBarElement = e.target.enclosingNodeOrSelfWithClass("timeline-graph-bar");
},
/**
- * @param {?Event} event
+ * @param {!Event} event
*/
_keyDown: function(event)
{
},
/**
- * @param {!WebInspector.TimelineModel.Record} record
+ * @param {?Element} rowElement
+ * @return {boolean}
*/
- _highlightQuad: function(record)
+ _highlightQuad: function(rowElement)
{
+ if (!rowElement || !rowElement.row)
+ return false;
+ var presentationRecord = rowElement.row._record;
+ if (presentationRecord.coalesced())
+ return false;
+ var record = presentationRecord.record();
if (this._highlightedQuadRecord === record)
- return;
+ return true;
+
+ var quad = this._uiUtils.highlightQuadForRecord(record);
+ var target = record.target();
+ if (!quad || !target)
+ return false;
this._highlightedQuadRecord = record;
- var quad = record.highlightQuad;
- record.target().domAgent().highlightQuad(quad, WebInspector.Color.PageHighlight.Content.toProtocolRGBA(), WebInspector.Color.PageHighlight.ContentOutline.toProtocolRGBA());
+ target.domAgent().highlightQuad(quad, WebInspector.Color.PageHighlight.Content.toProtocolRGBA(), WebInspector.Color.PageHighlight.ContentOutline.toProtocolRGBA());
+ return true;
},
_hideQuadHighlight: function()
{
- if (this._highlightedQuadRecord) {
- this._highlightedQuadRecord.target().domAgent().hideHighlight();
+ var target = this._highlightedQuadRecord ? this._highlightedQuadRecord.target() : null;
+ if (target)
+ target.domAgent().hideHighlight();
+
+ if (this._highlightedQuadRecord)
delete this._highlightedQuadRecord;
- }
},
/**
},
/**
- * @param {!WebInspector.TimelineModel.Record} record
+ * @param {!WebInspector.TimelinePresentationModel.Record} record
* @return {!{start: number, end: number, cpuWidth: number}}
*/
computeBarGraphPercentages: function(record)
},
/**
- * @param {!WebInspector.TimelineModel.Record} record
+ * @param {!WebInspector.TimelinePresentationModel.Record} record
* @return {!{left: number, width: number, cpuWidth: number}}
*/
computeBarGraphWindowPosition: function(record)
/**
* @param {!WebInspector.TimelinePresentationModel.Record} presentationRecord
* @param {number} offset
- * @param {boolean} loadedFromFile
+ * @param {!WebInspector.TimelineUIUtils} uiUtils
*/
- update: function(presentationRecord, offset, loadedFromFile)
+ update: function(presentationRecord, offset, uiUtils)
{
this._record = presentationRecord;
var record = presentationRecord.record();
this._offset = offset;
- this.element.className = "timeline-tree-item timeline-category-" + record.category().name;
+ this.element.className = "timeline-tree-item timeline-category-" + uiUtils.categoryForRecord(record).name;
var paddingLeft = 5;
var step = -3;
for (var currentRecord = presentationRecord.presentationParent() ? presentationRecord.presentationParent().presentationParent() : null; currentRecord; currentRecord = currentRecord.presentationParent())
paddingLeft += 12 / (Math.max(1, step++));
this.element.style.paddingLeft = paddingLeft + "px";
- if (record.thread())
+ if (record.thread() !== WebInspector.TimelineModel.MainThreadName)
this.element.classList.add("background");
- this._typeElement.textContent = record.title();
+ this._typeElement.textContent = uiUtils.titleForRecord(record);
if (this._dataElement.firstChild)
this._dataElement.removeChildren();
if (presentationRecord.coalesced()) {
this._dataElement.createTextChild(WebInspector.UIString("× %d", presentationRecord.presentationChildren().length));
} else {
- var detailsNode = WebInspector.TimelineUIUtils.buildDetailsNode(record, this._linkifier, loadedFromFile);
+ var detailsNode = uiUtils.buildDetailsNode(record, this._linkifier);
if (detailsNode) {
- this._dataElement.appendChild(document.createTextNode("("));
+ this._dataElement.createTextChild("(");
this._dataElement.appendChild(detailsNode);
- this._dataElement.appendChild(document.createTextNode(")"));
+ this._dataElement.createTextChild(")");
}
}
},
/**
- * @param {?Event} event
+ * @param {!Event} event
*/
_onClick: function(event)
{
},
/**
- * @param {?Event} event
+ * @param {!Event} event
*/
_onMouseOver: function(event)
{
},
/**
- * @param {?Event} event
+ * @param {!Event} event
*/
_onMouseOut: function(event)
{
/**
* @constructor
+ * @param {!Element} graphContainer
* @param {function(!WebInspector.TimelinePresentationModel.Record)} selectRecord
* @param {function()} scheduleRefresh
*/
this.element.addEventListener("mouseout", this._onMouseOut.bind(this), false);
this.element.addEventListener("click", this._onClick.bind(this), false);
- this._barAreaElement = document.createElement("div");
- this._barAreaElement.className = "timeline-graph-bar-area";
- this.element.appendChild(this._barAreaElement);
+ this._barAreaElement = this.element.createChild("div", "timeline-graph-bar-area");
- this._barCpuElement = document.createElement("div");
- this._barCpuElement.className = "timeline-graph-bar cpu"
+ this._barCpuElement = this._barAreaElement.createChild("div", "timeline-graph-bar cpu");
this._barCpuElement.row = this;
- this._barAreaElement.appendChild(this._barCpuElement);
- this._barElement = document.createElement("div");
- this._barElement.className = "timeline-graph-bar";
+ this._barElement = this._barAreaElement.createChild("div", "timeline-graph-bar");
this._barElement.row = this;
- this._barAreaElement.appendChild(this._barElement);
this._expandElement = new WebInspector.TimelineExpandableElement(graphContainer);
* @param {!WebInspector.TimelineCalculator} calculator
* @param {number} expandOffset
* @param {number} index
+ * @param {!WebInspector.TimelineUIUtils} uiUtils
*/
- update: function(presentationRecord, calculator, expandOffset, index)
+ update: function(presentationRecord, calculator, expandOffset, index, uiUtils)
{
this._record = presentationRecord;
var record = presentationRecord.record();
- this.element.className = "timeline-graph-side timeline-category-" + record.category().name;
- if (record.thread())
+ this.element.className = "timeline-graph-side timeline-category-" + uiUtils.categoryForRecord(record).name;
+ if (record.thread() !== WebInspector.TimelineModel.MainThreadName)
this.element.classList.add("background");
- var barPosition = calculator.computeBarGraphWindowPosition(record);
+ var barPosition = calculator.computeBarGraphWindowPosition(presentationRecord);
this._barElement.style.left = barPosition.left + "px";
this._barElement.style.width = barPosition.width + "px";
this._barCpuElement.style.left = barPosition.left + "px";
},
/**
- * @param {?Event} event
+ * @param {!Event} event
*/
_onClick: function(event)
{
},
/**
- * @param {?Event} event
+ * @param {!Event} event
*/
_onMouseOver: function(event)
{
},
/**
- * @param {?Event} event
+ * @param {!Event} event
*/
_onMouseOut: function(event)
{
WebInspector.TimelineExpandableElement.prototype = {
/**
* @param {!WebInspector.TimelinePresentationModel.Record} record
+ * @param {number} index
+ * @param {number} left
+ * @param {number} width
*/
_update: function(record, index, left, width)
{
this._element.classList.remove("timeline-expandable-expanded");
}
this._element.classList.remove("hidden");
- } else
+ } else {
this._element.classList.add("hidden");
+ }
},
_dispose: function()