this._currentMode = mode;
this._calculator = new WebInspector.TimelineCalculator(this._model);
this._model.addEventListener(WebInspector.TimelineModel.Events.RecordAdded, this._onTimelineEventRecorded, this);
- this._model.addEventListener(WebInspector.TimelineModel.Events.RecordsCleared, this._onRecordsCleared, this);
// Create presentation model.
this._presentationModel = new WebInspector.TimelinePresentationModel();
this._boundariesAreValid = true;
this._scrollTop = 0;
- // Create layout componets.
-
- // |-------------------------------|
- // | | | |
- // | | Records | |
- // | | | Details |
- // |----------------| |
- // | | Memory | |
- // -------------------------------
-
- // Create top level properties splitter.
- this._detailsSplitView = new WebInspector.SplitView(false, "timeline-details");
- this._detailsSplitView.element.classList.add("timeline-details-split");
- this._detailsSplitView.sidebarElement().classList.add("timeline-details");
- this._detailsSplitView.setMainElementConstraints(undefined, 40);
- this._detailsView = new WebInspector.TimelineDetailsView();
- this._detailsSplitView.setSidebarView(this._detailsView);
- this._detailsSplitView.installResizer(this._detailsView.titleElement());
-
- WebInspector.dockController.addEventListener(WebInspector.DockController.Events.DockSideChanged, this._dockSideChanged.bind(this));
- WebInspector.settings.splitVerticallyWhenDockedToRight.addChangeListener(this._dockSideChanged.bind(this));
- this._dockSideChanged();
-
this._searchableView = new WebInspector.SearchableView(this);
this._searchableView.element.classList.add("searchable-view");
- this._detailsSplitView.setMainView(this._searchableView);
- this._views = [];
this._recordsView = this._createRecordsView();
- this._views.push(this._recordsView);
-
- this._stackView = new WebInspector.StackView(false);
- this._stackView.show(this._searchableView.element);
- this._stackView.element.classList.add("timeline-view-stack");
- this._recordsViewMainElement = this._stackView.appendView(this._recordsView, "timeline-records").mainElement();
- this._recordsViewMainElement.classList.add("timeline-records-view");
- this._recordsViewMainElement.appendChild(this._timelineGrid.gridHeaderElement);
-
- if (this._currentMode === WebInspector.TimelinePanel.Mode.Memory) {
- // Create memory statistics as a bottom memory splitter child.
- this._memoryStatistics = new WebInspector.CountersGraph(this, this._model);
- this._views.push(this._memoryStatistics);
- this._memoryStatistics.addEventListener(WebInspector.SidebarView.EventTypes.Resized, this._sidebarResized, this);
- this._stackView.appendView(this._memoryStatistics, "timeline-memory");
- }
+ this._recordsView.addEventListener(WebInspector.SplitView.Events.SidebarSizeChanged, this._sidebarResized, this);
+ this._recordsView.show(this._searchableView.element);
+ this._searchableView.element.appendChild(this._timelineGrid.gridHeaderElement);
this._popoverHelper = new WebInspector.PopoverHelper(this.element, this._getPopoverAnchor.bind(this), this._showPopover.bind(this));
this._expandOffset = 15;
- this._windowStartTime = 0;
- this._windowEndTime = Infinity;
-
this._allRecordsCount = 0;
this._presentationModel.setGlueRecords(glueRecordsSetting.get());
this._glueRecordsSetting = glueRecordsSetting;
this._glueRecordsSetting.addChangeListener(this._onGlueRecordsSettingChanged, this);
- switch (mode) {
- case WebInspector.TimelinePanel.Mode.Events:
- this._overviewControl = new WebInspector.TimelineEventOverview(this._model);
- break;
- case WebInspector.TimelinePanel.Mode.Frames:
- this._overviewControl = new WebInspector.TimelineFrameOverview(this._model);
+ if (mode === WebInspector.TimelinePanel.Mode.Frames) {
+ this.frameModel = new WebInspector.TimelineFrameModel(this._model);
this._presentationModel.setGlueRecords(false);
- this._frameController = new WebInspector.TimelineFrameController(this._model, this._overviewControl, this._presentationModel);
- break;
- case WebInspector.TimelinePanel.Mode.Memory:
- this._overviewControl = new WebInspector.TimelineMemoryOverview(this._model);
- break;
}
- this._detailsSplitView.show(this.element);
+ this._searchableView.show(this.element);
}
WebInspector.TimelineView.commonUIFilters = function()
WebInspector.TimelineView.prototype = {
/**
- * @return {!WebInspector.SidebarView}
+ * @return {!WebInspector.SplitView}
*/
_createRecordsView: function()
{
- // Create records sidebar as a top memory splitter child.
- var recordsView = new WebInspector.SidebarView(WebInspector.SidebarView.SidebarPosition.Start, "timeline-split");
- recordsView.addEventListener(WebInspector.SidebarView.EventTypes.Resized, this._sidebarResized, this);
- recordsView.setSecondIsSidebar(false);
+ var recordsView = new WebInspector.SplitView(true, false, "timeline-split");
this._containerElement = recordsView.element;
this._containerElement.tabIndex = 0;
this._containerElement.id = "timeline-container";
// Create grid in the records main area.
this._gridContainer = new WebInspector.ViewWithResizeCallback(this._onViewportResize.bind(this));
this._gridContainer.element.id = "resources-container-content";
- recordsView.setMainView(this._gridContainer);
+ this._gridContainer.show(recordsView.mainElement());
this._timelineGrid = new WebInspector.TimelineGrid();
this._itemsGraphsElement = this._timelineGrid.itemsGraphsElement;
this._itemsGraphsElement.id = "timeline-graphs";
this._repopulateRecords();
},
- /**
- * @return {number}
- */
- windowStartTime: function()
- {
- return this._windowStartTime || this._model.minimumRecordTime();
- },
-
- /**
- * @return {number}
- */
- windowEndTime: function()
- {
- return this._windowEndTime < Infinity ? this._windowEndTime : this._model.maximumRecordTime();
- },
-
- /**
- * @return {!WebInspector.TimelineOverviewBase}
- */
- overviewControl: function()
- {
- return this._overviewControl;
- },
-
get calculator()
{
return this._calculator;
this._invalidateAndScheduleRefresh(true, true);
},
- _dockSideChanged: function()
- {
- var dockSide = WebInspector.dockController.dockSide();
- var vertically = false;
- if (dockSide === WebInspector.DockController.State.DockedToBottom)
- vertically = true;
- else
- vertically = !WebInspector.settings.splitVerticallyWhenDockedToRight.get();
- this._detailsSplitView.setVertical(vertically);
- this._detailsView.setVertical(vertically);
- },
-
_rootRecord: function()
{
return this._presentationModel.rootRecord();
this._timelineGrid.gridHeaderElement.appendChild(this._frameContainer);
},
- _onFrameDoubleClicked: function(event)
- {
- var frameBar = event.target.enclosingNodeOrSelfWithClass("timeline-frame-strip");
- if (!frameBar)
- return;
- this._setWindowTimes(frameBar._frame.startTime, frameBar._frame.endTime);
- },
-
- _updateWindowBoundaries: function()
- {
- var windowBoundaries = this.overviewControl().windowBoundaries(this._windowStartTime, this._windowEndTime);
- this._panel.setWindow(windowBoundaries.left, windowBoundaries.right);
- },
-
/**
- * @return {!{windowStartTime: number, windowEndTime: number}}
+ * @param {number} startTime
+ * @param {number} endTime
+ * @return {!Array.<!WebInspector.TimelineFrame>}
*/
- windowTimes: function()
+ _filteredFrames: function(startTime, endTime)
{
- return {windowStartTime: this._windowStartTime, windowEndTime: this._windowEndTime};
+ if (!this.frameModel)
+ return [];
+ function compareStartTime(value, object)
+ {
+ return value - object.startTime;
+ }
+ function compareEndTime(value, object)
+ {
+ return value - object.endTime;
+ }
+ var frames = this.frameModel.frames();
+ var firstFrame = insertionIndexForObjectInListSortedByFunction(startTime, frames, compareStartTime);
+ var lastFrame = insertionIndexForObjectInListSortedByFunction(endTime, frames, compareEndTime);
+ while (lastFrame < frames.length && frames[lastFrame].endTime <= endTime)
+ ++lastFrame;
+ return frames.slice(firstFrame, lastFrame);
},
- /**
- * @param {?Object} windowTimes
- */
- setWindowTimes: function(windowTimes)
- {
- if (!windowTimes)
- return;
- this._setWindowTimes(windowTimes.windowStartTime, windowTimes.windowEndTime);
- },
- /**
- * @param {number} startTime
- * @param {number} endTime
- */
- _setWindowTimes: function(startTime, endTime)
+ _onFrameDoubleClicked: function(event)
{
- this._windowStartTime = startTime;
- this._windowEndTime = endTime;
- this._windowFilter.setWindowTimes(startTime, endTime);
- var windowBoundaries = this.overviewControl().windowBoundaries(startTime, endTime);
- this._panel.setWindow(windowBoundaries.left, windowBoundaries.right);
+ var frameBar = event.target.enclosingNodeOrSelfWithClass("timeline-frame-strip");
+ if (!frameBar)
+ return;
+ this._panel.setWindowTimes(frameBar._frame.startTime, frameBar._frame.endTime);
},
_repopulateRecords: function()
if (record.type === WebInspector.TimelineModel.RecordType.GPUTask) {
this._gpuTasks.push(record);
- return WebInspector.TimelineModel.startTimeInSeconds(record) < this._windowEndTime;
+ return WebInspector.TimelineModel.startTimeInSeconds(record) < this._panel.windowEndTime();
}
var records = this._presentationModel.addRecord(record);
},
/**
- * @param {!WebInspector.Event} event
+ * @param {number} width
*/
- _sidebarResized: function(event)
+ setSidebarSize: function(width)
{
- var width = /** @type {number} */(event.data);
- this.setSidebarWidth(width);
- this._panel.setSidebarWidth(width);
+ this._recordsView.setSidebarSize(width);
},
/**
- * @param {number} width
+ * @param {!WebInspector.Event} event
*/
- setSidebarWidth: function(width)
+ _sidebarResized: function(event)
{
- this._timelineGrid.gridHeaderElement.style.left = width + "px";
- for (var i = 0; i < this._views.length; ++i)
- this._views[i].setSidebarWidth(width);
+ this.dispatchEventToListeners(WebInspector.SplitView.Events.SidebarSizeChanged, event.data);
},
_onViewportResize: function()
{
- this._resize(this._recordsView.sidebarWidth());
+ this._resize(this._recordsView.sidebarSize());
},
/**
this._closeRecordDetails();
this._graphRowsElementWidth = this._graphRowsElement.offsetWidth;
this._containerElementHeight = this._containerElement.clientHeight;
+ this._timelineGrid.gridHeaderElement.style.left = sidebarWidth + "px";
this._timelineGrid.gridHeaderElement.style.width = this._itemsGraphsElement.offsetWidth + "px";
this._scheduleRefresh(false, true);
},
this._gpuTasks = [];
},
- _onRecordsCleared: function()
+ reset: function()
{
- this._windowStartTime = 0;
- this._windowEndTime = Infinity;
-
this._resetView();
- this.overviewControl().reset();
this._windowFilter.reset();
this._invalidateAndScheduleRefresh(true, true);
+ this._updateSelectionDetails();
},
/**
this._repopulateRecords();
this._updateSelectionDetails();
- this._updateWindowBoundaries();
if (!WebInspector.TimelinePanel._categoryStylesInitialized) {
WebInspector.TimelinePanel._categoryStylesInitialized = true;
*/
function showCallback(element)
{
- this._detailsView.setContent(record.title, element);
+ this._panel.setDetailsContent(record.title, element);
}
},
_updateSelectionDetails: function()
{
- var startTime = this.windowStartTime() * 1000;
- var endTime = this.windowEndTime() * 1000;
+ var startTime = this._panel.windowStartTime() * 1000;
+ var endTime = this._panel.windowEndTime() * 1000;
// Return early in case 0 selection window.
if (startTime < 0)
return;
aggregatedStats["idle"] = Math.max(0, (endTime - startTime) / 1000 - aggregatedTotal);
var fragment = document.createDocumentFragment();
- var pie = WebInspector.TimelinePresentationModel.generatePieChart(aggregatedStats);
- fragment.appendChild(pie.element);
+ fragment.appendChild(WebInspector.TimelinePresentationModel.generatePieChart(aggregatedStats));
if (this._frameMode && this._lastFrameStatistics) {
var title = WebInspector.UIString("%s \u2013 %s (%d frames)", Number.secondsToString(this._lastFrameStatistics.startOffset, true), Number.secondsToString(this._lastFrameStatistics.endOffset, true), this._lastFrameStatistics.frameCount);
} else {
var title = WebInspector.UIString("%s \u2013 %s", this._calculator.formatTime(0, true), this._calculator.formatTime(this._calculator.boundarySpan(), true));
}
- this._detailsView.setContent(title, fragment);
+ this._panel.setDetailsContent(title, fragment);
},
/**
- * @param {number} left
- * @param {number} right
+ * @param {number} startTime
+ * @param {number} endTime
*/
- windowChanged: function(left, right)
+ setWindowTimes: function(startTime, endTime)
{
- var windowTimes = this.overviewControl().windowTimes(left, right);
- this._windowStartTime = windowTimes.startTime;
- this._windowEndTime = windowTimes.endTime;
- this._windowFilter.setWindowTimes(windowTimes.startTime, windowTimes.endTime);
+ this._windowFilter.setWindowTimes(startTime, endTime);
this._invalidateAndScheduleRefresh(false, true);
this._selectRecord(null);
},
clearTimeout(this._refreshTimeout);
delete this._refreshTimeout;
}
-
+ var windowStartTime = this._panel.windowStartTime();
+ var windowEndTime = this._panel.windowEndTime();
this._timelinePaddingLeft = this._expandOffset;
- this._calculator.setWindow(this.windowStartTime(), this.windowEndTime());
+ this._calculator.setWindow(windowStartTime, windowEndTime);
this._calculator.setDisplayWindow(this._timelinePaddingLeft, this._graphRowsElementWidth);
var recordsInWindowCount = this._refreshRecords();
this._updateRecordsCounter(recordsInWindowCount);
if (!this._boundariesAreValid) {
this._updateEventDividers();
- var frames = this._frameController && this._presentationModel.filteredFrames(this.windowStartTime(), this.windowEndTime());
+ var frames = this._filteredFrames(windowStartTime, windowEndTime);
if (frames) {
this._updateFrameStatistics(frames);
const maxFramesForFrameBars = 30;
this._timelineGrid.updateDividers(this._calculator);
this._refreshAllUtilizationBars();
}
- if (this._currentMode === WebInspector.TimelinePanel.Mode.Memory)
- this._memoryStatistics.refresh();
- this._updateWindowBoundaries();
this._boundariesAreValid = true;
},
this._selectRecord(null);
// 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].startTime : this._model.minimumRecordTime();
- this._setWindowTimes(windowStartTime, recordsInWindow[Math.max(0, lastVisibleLine - 1)].endTime);
+ var windowEndTime = recordsInWindow[Math.max(0, lastVisibleLine - 1)].endTime;
+ this._panel.setWindowTimes(windowStartTime, windowEndTime);
+ this._windowFilter.setWindowTimes(windowStartTime, windowEndTime);
recordsInWindow = this._presentationModel.filteredRecords();
endIndex = Math.min(recordsInWindow.length, lastVisibleLine);
- } else {
- this._updateWindowBoundaries();
}
// Resize gaps first.
var rowsHeight = headerHeight + recordsInWindow.length * rowHeight;
var totalHeight = Math.max(this._containerElementHeight, rowsHeight);
- this._recordsView.firstElement().style.height = totalHeight + "px";
- this._recordsView.secondElement().style.height = totalHeight + "px";
+ this._recordsView.mainElement().style.height = totalHeight + "px";
+ this._recordsView.sidebarElement().style.height = totalHeight + "px";
this._recordsView.resizerElement().style.height = totalHeight + "px";
// Update visible rows.
var widthAdjustment = minWidth / 2;
var width = this._graphRowsElementWidth;
- var boundarySpan = this.windowEndTime() - this.windowStartTime();
+ var boundarySpan = this._panel.windowEndTime() - this._panel.windowStartTime();
var scale = boundarySpan / (width - minWidth - this._timelinePaddingLeft);
- var startTime = (this.windowStartTime() - this._timelinePaddingLeft * scale) * 1000;
+ var startTime = (this._panel.windowStartTime() - this._timelinePaddingLeft * scale) * 1000;
var endTime = startTime + width * scale * 1000;
/**
for (var currentRecord = record.parent ? record.parent.parent : null; currentRecord; currentRecord = currentRecord.parent)
paddingLeft += 12 / (Math.max(1, step++));
this.element.style.paddingLeft = paddingLeft + "px";
- if (record.isBackground)
+ if (record.isBackground())
this.element.classList.add("background");
this._typeElement.textContent = record.title;
{
this._record = record;
this.element.className = "timeline-graph-side timeline-category-" + record.category.name;
- if (record.isBackground)
+ if (record.isBackground())
this.element.classList.add("background");
var barPosition = calculator.computeBarGraphWindowPosition(record);
*/
accept: function(record)
{
- return !record.category.hidden && record.type !== WebInspector.TimelineModel.RecordType.BeginFrame;
+ return !record.category.hidden;
}
}
return record.lastChildEndTime >= this._windowStartTime && record.startTime <= this._windowEndTime;
}
}
-
-/**
- * @constructor
- * @extends {WebInspector.View}
- */
-WebInspector.TimelineDetailsView = function()
-{
- WebInspector.View.call(this);
- this.element.classList.add("timeline-details-view");
- this._titleElement = this.element.createChild("div", "timeline-details-view-title");
- this._titleElement.textContent = WebInspector.UIString("DETAILS");
- this._contentElement = this.element.createChild("div", "timeline-details-view-body");
-}
-
-WebInspector.TimelineDetailsView.prototype = {
- /**
- * @return {!Element}
- */
- titleElement: function()
- {
- return this._titleElement;
- },
-
- /**
- * @param {string} title
- * @param {!Node} node
- */
- setContent: function(title, node)
- {
- this._titleElement.textContent = WebInspector.UIString("DETAILS: %s", title);
- this._contentElement.removeChildren();
- this._contentElement.appendChild(node);
- },
-
- /**
- * @param {boolean} vertical
- */
- setVertical: function(vertical)
- {
- this._contentElement.enableStyleClass("hbox", !vertical);
- this._contentElement.enableStyleClass("vbox", vertical);
- },
-
- __proto__: WebInspector.View.prototype
-}