Diff
Modified: trunk/LayoutTests/ChangeLog (109106 => 109107)
--- trunk/LayoutTests/ChangeLog 2012-02-28 16:11:56 UTC (rev 109106)
+++ trunk/LayoutTests/ChangeLog 2012-02-28 16:18:58 UTC (rev 109107)
@@ -1,3 +1,12 @@
+2012-02-28 Pavel Feldman <[email protected]>
+
+ Web Inspector: move filtering of the timeline records into the presentation model.
+ https://bugs.webkit.org/show_bug.cgi?id=79789
+
+ Reviewed by Yury Semikhatsky.
+
+ * inspector/timeline/timeline-enum-stability-expected.txt:
+
2012-02-28 Florin Malita <[email protected]>
Percent width/height SVG not always scaled on window resize
Modified: trunk/LayoutTests/inspector/timeline/timeline-enum-stability-expected.txt (109106 => 109107)
--- trunk/LayoutTests/inspector/timeline/timeline-enum-stability-expected.txt 2012-02-28 16:11:56 UTC (rev 109106)
+++ trunk/LayoutTests/inspector/timeline/timeline-enum-stability-expected.txt 2012-02-28 16:18:58 UTC (rev 109107)
@@ -3,6 +3,7 @@
Applications outside of WebKit depend on the stability of the mapping of these types to these specific values.
{
+ Root : "Root"
EventDispatch : "EventDispatch"
Layout : "Layout"
RecalculateStyles : "RecalculateStyles"
Modified: trunk/Source/WebCore/ChangeLog (109106 => 109107)
--- trunk/Source/WebCore/ChangeLog 2012-02-28 16:11:56 UTC (rev 109106)
+++ trunk/Source/WebCore/ChangeLog 2012-02-28 16:18:58 UTC (rev 109107)
@@ -1,3 +1,54 @@
+2012-02-28 Pavel Feldman <[email protected]>
+
+ Web Inspector: move filtering of the timeline records into the presentation model.
+ https://bugs.webkit.org/show_bug.cgi?id=79789
+
+ Reviewed by Yury Semikhatsky.
+
+ * inspector/front-end/TimelineModel.js:
+ * inspector/front-end/TimelineOverviewPane.js:
+ (WebInspector.TimelineOverviewPane):
+ (WebInspector.TimelineOverviewPane.prototype.setStartAtZero):
+ (WebInspector.TimelineOverviewPane.prototype.scrollWindow):
+ (WebInspector.TimelineOverviewPane.prototype.accept):
+ (WebInspector.TimelineOverviewPane.prototype._setWindowIndices):
+ (WebInspector.TimelineStartAtZeroOverview):
+ (WebInspector.TimelineStartAtZeroOverview.prototype._onWindowChanged):
+ * inspector/front-end/TimelinePanel.js:
+ (WebInspector.TimelinePanel):
+ (WebInspector.TimelinePanel.prototype._createStatusbarButtons):
+ (WebInspector.TimelinePanel.prototype._updateRecordsCounter):
+ (WebInspector.TimelinePanel.prototype._glueParentButtonClicked):
+ (WebInspector.TimelinePanel.prototype._toggleStartAtZeroButtonClicked):
+ (WebInspector.TimelinePanel.prototype._innerAddRecordToTimeline):
+ (WebInspector.TimelinePanel.prototype._resetPanel):
+ (WebInspector.TimelinePanel.prototype._refresh):
+ (WebInspector.TimelinePanel.prototype.revealRecordAt):
+ (WebInspector.TimelinePanel.prototype._refreshRecords):
+ (WebInspector.TimelineExpandableElement.prototype._update):
+ (WebInspector.TimelineCategoryFilter):
+ (WebInspector.TimelineCategoryFilter.prototype.accept):
+ (WebInspector.TimelineIsLongFilter):
+ (WebInspector.TimelineIsLongFilter.prototype.accept):
+ * inspector/front-end/TimelinePresentationModel.js:
+ (WebInspector.TimelinePresentationModel):
+ (WebInspector.TimelinePresentationModel.prototype.addFilter):
+ (WebInspector.TimelinePresentationModel.prototype.reset):
+ (WebInspector.TimelinePresentationModel.prototype.minimumRecordTime):
+ (WebInspector.TimelinePresentationModel.prototype.maximumRecordTime):
+ (WebInspector.TimelinePresentationModel.prototype.addRecord):
+ (WebInspector.TimelinePresentationModel.prototype._updateBoundaries):
+ (WebInspector.TimelinePresentationModel.prototype._findParentRecord):
+ (WebInspector.TimelinePresentationModel.prototype.setGlueRecords):
+ (WebInspector.TimelinePresentationModel.prototype.fireWindowChanged):
+ (WebInspector.TimelinePresentationModel.prototype.get _recordStyles):
+ (WebInspector.TimelinePresentationModel.prototype.filteredRecords):
+ (WebInspector.TimelinePresentationModel.prototype._filterRecords):
+ (WebInspector.TimelinePresentationModel.Record.prototype.get visibleChildrenCount):
+ (WebInspector.TimelinePresentationModel.Record.prototype.get invisibleChildrenCount):
+ (WebInspector.TimelinePresentationModel.Filter):
+ (WebInspector.TimelinePresentationModel.Filter.prototype.accept):
+
2012-02-28 Florin Malita <[email protected]>
Percent width/height SVG not always scaled on window resize
Modified: trunk/Source/WebCore/inspector/front-end/TimelineModel.js (109106 => 109107)
--- trunk/Source/WebCore/inspector/front-end/TimelineModel.js 2012-02-28 16:11:56 UTC (rev 109106)
+++ trunk/Source/WebCore/inspector/front-end/TimelineModel.js 2012-02-28 16:18:58 UTC (rev 109107)
@@ -41,6 +41,7 @@
}
WebInspector.TimelineModel.RecordType = {
+ Root: "Root",
EventDispatch: "EventDispatch",
Layout: "Layout",
RecalculateStyles: "RecalculateStyles",
Modified: trunk/Source/WebCore/inspector/front-end/TimelineOverviewPane.js (109106 => 109107)
--- trunk/Source/WebCore/inspector/front-end/TimelineOverviewPane.js 2012-02-28 16:11:56 UTC (rev 109106)
+++ trunk/Source/WebCore/inspector/front-end/TimelineOverviewPane.js 2012-02-28 16:18:58 UTC (rev 109107)
@@ -31,6 +31,7 @@
/**
* @constructor
* @extends {WebInspector.Object}
+ * @implements {WebInspector.TimelinePresentationModel.Filter}
*/
WebInspector.TimelineOverviewPane = function(presentationModel)
{
@@ -38,6 +39,9 @@
this.element.className = "fill";
this._startAtZero = false;
+ this._topLevelRecordIndex = 0;
+ this._windowIndexLeft = 0;
+ this._windowIndexRight = null;
this._presentationModel = presentationModel;
@@ -139,7 +143,7 @@
if (this._heapGraph.visible)
this._showTimelines();
this.element.addStyleClass("timeline-start-at-zero");
- this._startAtZeroOverview = new WebInspector.TimelineStartAtZeroOverview(this._presentationModel);
+ this._startAtZeroOverview = new WebInspector.TimelineStartAtZeroOverview(this);
this._startAtZeroOverview.show(this.element);
this._startAtZeroOverview.update(this._records);
} else {
@@ -163,6 +167,7 @@
update: function(records, showShortEvents)
{
+ this._topLevelRecordIndex = 0;
this._records = records;
this._showShortEvents = showShortEvents;
// Clear summary bars.
@@ -261,6 +266,32 @@
scrollWindow: function(event)
{
this._overviewWindow.scrollWindow(event);
+ },
+
+ /**
+ * @param {WebInspector.TimelinePresentationModel.Record} record
+ */
+ accept: function(record)
+ {
+ if (this._startAtZeroOverview) {
+ if (record.parent === this._presentationModel.rootRecord())
+ ++this._topLevelRecordIndex;
+ return this._topLevelRecordIndex > this._windowIndexLeft &&
+ (typeof this._windowIndexRight !== "number" || this._topLevelRecordIndex <= this._windowIndexRight);
+ } else {
+ var absoluteMin = this._presentationModel.minimumRecordTime();
+ var absoluteMax = this._presentationModel.maximumRecordTime();
+ var windowLeft = absoluteMin + (absoluteMax - absoluteMin) * this._overviewWindow.windowLeft;
+ var windowRight = absoluteMin + (absoluteMax - absoluteMin) * this._overviewWindow.windowRight;
+ return record.endTime >= windowLeft && record.startTime <= windowRight;
+ }
+ },
+
+ _setWindowIndices: function(indexLeft, indexRight)
+ {
+ this._windowIndexLeft = indexLeft;
+ this._windowIndexRight = indexRight;
+ this._presentationModel.fireWindowChanged();
}
}
@@ -721,12 +752,12 @@
/**
* @constructor
- * @param {WebInspector.TimelinePresentationModel} model
+ * @param {WebInspector.TimelineOverviewPane} pane
* @extends {WebInspector.View}
*/
-WebInspector.TimelineStartAtZeroOverview = function(model) {
+WebInspector.TimelineStartAtZeroOverview = function(pane) {
WebInspector.View.call(this);
- this._presentationModel = model;
+ this._pane = pane;
this.element.className = "timeline-overview-start-at-zero fill";
this._overviewElement = this.element.createChild("div", "timeline-overview-start-at-zero-bars fill");
this._overviewWindow = new WebInspector.TimelineOverviewWindow(this.element);
@@ -810,7 +841,7 @@
var leftIndex = Math.floor((leftOffset - offset0) / barWidth * this._recordsPerBar);
var rightIndex = rightOffset + barWidth >= this.element.clientWidth ? null : Math.ceil((rightOffset - offset0 - 2) / barWidth * this._recordsPerBar);
- this._presentationModel.setWindowIndices(leftIndex, rightIndex);
+ this._pane._setWindowIndices(leftIndex, rightIndex);
}
}
Modified: trunk/Source/WebCore/inspector/front-end/TimelinePanel.js (109106 => 109107)
--- trunk/Source/WebCore/inspector/front-end/TimelinePanel.js 2012-02-28 16:11:56 UTC (rev 109106)
+++ trunk/Source/WebCore/inspector/front-end/TimelinePanel.js 2012-02-28 16:18:58 UTC (rev 109107)
@@ -123,8 +123,11 @@
this._registerShortcuts();
- this._visibleRecordsCount = 0;
this._allRecordsCount = 0;
+
+ this._presentationModel.addFilter(this._overviewPane);
+ this._presentationModel.addFilter(new WebInspector.TimelineCategoryFilter());
+ this._presentationModel.addFilter(new WebInspector.TimelineIsLongFilter(this));
}
// Define row height, should be in sync with styles for timeline graphs.
@@ -221,6 +224,7 @@
this._glueParentButton = new WebInspector.StatusBarButton(WebInspector.UIString("Glue asynchronous events to causes"), "glue-async-status-bar-item");
this._glueParentButton.toggled = true;
+ this._presentationModel.setGlueRecords(true);
this._glueParentButton.addEventListener("click", this._glueParentButtonClicked, this);
this.statusBarFilters = document.createElement("div");
@@ -322,9 +326,9 @@
return this._presentationModel.rootRecord();
},
- _updateRecordsCounter: function()
+ _updateRecordsCounter: function(recordsInWindowCount)
{
- this.recordsCounter.textContent = WebInspector.UIString("%d of %d captured records are visible", this._visibleRecordsCount, this._allRecordsCount);
+ this.recordsCounter.textContent = WebInspector.UIString("%d of %d captured records are visible", recordsInWindowCount, this._allRecordsCount);
},
_updateEventDividers: function()
@@ -416,6 +420,7 @@
_glueParentButtonClicked: function()
{
this._glueParentButton.toggled = !this._glueParentButton.toggled;
+ this._presentationModel.setGlueRecords(this._glueParentButton.toggled && !this.toggleStartAtZeroButton.toggled);
this._repopulateRecords();
},
@@ -425,6 +430,7 @@
this._glueParentButton.disabled = toggled;
this.toggleStartAtZeroButton.toggled = toggled;
this._calculator = toggled ? new WebInspector.TimelineStartAtZeroCalculator() : new WebInspector.TimelineCalculator();
+ this._presentationModel.setGlueRecords(this._glueParentButton.toggled && !this.toggleStartAtZeroButton.toggled);
this._repopulateRecords();
this._overviewPane.setStartAtZero(toggled);
},
@@ -454,77 +460,11 @@
_innerAddRecordToTimeline: function(record, parentRecord)
{
- var connectedToOldRecord = false;
+ var formattedRecord = this._presentationModel.addRecord(record, parentRecord);
+ ++this._allRecordsCount;
var recordTypes = WebInspector.TimelineModel.RecordType;
-
- if (record.type === recordTypes.MarkDOMContent || record.type === recordTypes.MarkLoad)
- parentRecord = null; // No bar entry for load events.
- else if (!this._startAtZero &&
- this._glueParentButton.toggled &&
- (parentRecord === this._rootRecord() ||
- record.type === recordTypes.ResourceReceiveResponse ||
- record.type === recordTypes.ResourceFinish ||
- record.type === recordTypes.ResourceReceivedData)) {
- var newParentRecord = this._presentationModel.findParentRecord(record);
- if (newParentRecord) {
- parentRecord = newParentRecord;
- connectedToOldRecord = true;
- }
- }
-
- var children = record.children;
- var scriptDetails;
- if (record.data && record.data["scriptName"]) {
- scriptDetails = {
- scriptName: record.data["scriptName"],
- scriptLine: record.data["scriptLine"]
- }
- };
-
- if ((record.type === recordTypes.TimerFire || record.type === recordTypes.FireAnimationFrame) && children && children.length) {
- var childRecord = children[0];
- if (childRecord.type === recordTypes.FunctionCall) {
- scriptDetails = {
- scriptName: childRecord.data["scriptName"],
- scriptLine: childRecord.data["scriptLine"]
- };
- children = childRecord.children.concat(children.slice(1));
- }
- }
-
- var formattedRecord = this._presentationModel.createFormattedRecord(record, parentRecord, scriptDetails);
-
- if (record.type === recordTypes.MarkDOMContent || record.type === recordTypes.MarkLoad) {
+ if (record.type === recordTypes.MarkDOMContent || record.type === recordTypes.MarkLoad || record.type === recordTypes.TimeStamp)
this._timeStampRecords.push(formattedRecord);
- return;
- }
-
- ++this._allRecordsCount;
- formattedRecord.collapsed = (parentRecord === this._rootRecord());
-
- var childrenCount = children ? children.length : 0;
- for (var i = 0; i < childrenCount; ++i)
- this._innerAddRecordToTimeline(children[i], formattedRecord);
-
- formattedRecord.calculateAggregatedStats(this._presentationModel.categories);
-
- if (connectedToOldRecord) {
- record = formattedRecord;
- do {
- var parent = record.parent;
- if (parent.lastChildEndTime < record.lastChildEndTime)
- parent.lastChildEndTime = record.lastChildEndTime;
- for (var category in formattedRecord.aggregatedStats)
- parent.aggregatedStats[category] += formattedRecord.aggregatedStats[category];
- record = parent;
- } while (record.parent);
- } else {
- if (parentRecord !== this._rootRecord())
- parentRecord.selfTime -= formattedRecord.endTime - formattedRecord.startTime;
- }
- // Keep bar entry for mark timeline since nesting might be interesting to the user.
- if (record.type === recordTypes.TimeStamp)
- this._timeStampRecords.push(formattedRecord);
},
sidebarResized: function(event)
@@ -565,7 +505,6 @@
this._overviewPane.reset();
this._adjustScrollPosition(0);
this._closeRecordDetails();
- this._visibleRecordsCount = 0;
this._allRecordsCount = 0;
},
@@ -624,8 +563,8 @@
if (!this._boundariesAreValid)
this._updateBoundaries();
- this._refreshRecords(!this._boundariesAreValid);
- this._updateRecordsCounter();
+ var recordsInWindowCount = this._refreshRecords(!this._boundariesAreValid);
+ this._updateRecordsCounter(recordsInWindowCount);
if(!this._boundariesAreValid)
this._updateEventDividers();
if (this._memoryStatistics && this._memoryStatistics.visible())
@@ -645,60 +584,18 @@
this._calculator.calculateWindow();
},
- _filterRecords: function()
- {
- var recordsInWindow = [];
- var filter = this._startAtZero ? new WebInspector.TimelineStartAtZeroRecordFilter(this._presentationModel, this._rootRecord(), this._showShortEvents)
- : new WebInspector.TimelineRecordFilter(this._calculator, this._showShortEvents);
- this._visibleRecordsCount = 0;
-
- var stack = [{children: this._rootRecord().children, index: 0, parentIsCollapsed: false}];
- while (stack.length) {
- var entry = stack[stack.length - 1];
- var records = entry.children;
- if (records && entry.index < records.length) {
- var record = records[entry.index];
- ++entry.index;
-
- if (filter.accept(record)) {
- ++this._visibleRecordsCount;
- ++record.parent._invisibleChildrenCount;
- if (!entry.parentIsCollapsed)
- recordsInWindow.push(record);
- }
-
- record._invisibleChildrenCount = 0;
-
- stack.push({children: record.children,
- index: 0,
- parentIsCollapsed: (entry.parentIsCollapsed || record.collapsed),
- parentRecord: record,
- windowLengthBeforeChildrenTraversal: recordsInWindow.length});
- } else {
- stack.pop();
- if (entry.parentRecord)
- entry.parentRecord._visibleChildrenCount = recordsInWindow.length - entry.windowLengthBeforeChildrenTraversal;
- }
- }
-
- return recordsInWindow;
- },
-
revealRecordAt: function(time)
{
if (this._startAtZero)
return;
- var filter = new WebInspector.TimelineRecordFilter(this._calculator, this._showShortEvents);
+ var recordsInWindow = this._presentationModel.filteredRecords();
var recordToReveal;
- function recordFinder(record)
- {
- if (filter.accept(record) && record.containsTime(time)) {
- recordToReveal = record;
- return true;
+ for (var i = 0; i < recordsInWindow.length; ++i) {
+ if (recordsInWindow[i].containsTime(time)) {
+ recordToReveal = recordsInWindow[i];
+ break;
}
- return false;
}
- WebInspector.TimelinePanel.forAllRecords(this._rootRecord().children, recordFinder);
// The record ends before the window left bound so scroll to the top.
if (!recordToReveal) {
@@ -709,14 +606,13 @@
// Expand all ancestors.
for (var parent = recordToReveal.parent; parent !== this._rootRecord(); parent = parent.parent)
parent.collapsed = false;
- var recordsInWindow = this._filterRecords();
var index = recordsInWindow.indexOf(recordToReveal);
this._containerElement.scrollTop = index * WebInspector.TimelinePanel.rowHeight;
},
_refreshRecords: function(updateBoundaries)
{
- var recordsInWindow = this._filterRecords();
+ var recordsInWindow = this._presentationModel.filteredRecords();
// Calculate the visible area.
this._scrollTop = this._containerElement.scrollTop;
@@ -750,7 +646,7 @@
var isEven = !(i % 2);
if (i < startIndex) {
- var lastChildIndex = i + record._visibleChildrenCount;
+ var lastChildIndex = i + record.visibleChildrenCount;
if (lastChildIndex >= startIndex && lastChildIndex < endIndex) {
var expandElement = new WebInspector.TimelineExpandableElement(this._expandElements);
expandElement._update(record, i, this._calculator.computeBarGraphWindowPosition(record, width - this._expandOffset));
@@ -792,6 +688,8 @@
if (updateBoundaries)
this._timelineGrid.updateDividers(true, this._calculator, this.timelinePaddingLeft);
this._adjustScrollPosition((recordsInWindow.length + 1) * rowHeight);
+
+ return recordsInWindow.length;
},
get timelinePaddingLeft()
@@ -1159,12 +1057,12 @@
_update: function(record, index, barPosition)
{
const rowHeight = WebInspector.TimelinePanel.rowHeight;
- if (record._visibleChildrenCount || record._invisibleChildrenCount) {
+ if (record.visibleChildrenCount || record.invisibleChildrenCount) {
this._element.style.top = index * rowHeight + "px";
this._element.style.left = barPosition.left + "px";
this._element.style.width = Math.max(12, barPosition.width + 25) + "px";
if (!record.collapsed) {
- this._element.style.height = (record._visibleChildrenCount + 1) * rowHeight + "px";
+ this._element.style.height = (record.visibleChildrenCount + 1) * rowHeight + "px";
this._element.addStyleClass("timeline-expandable-expanded");
this._element.removeStyleClass("timeline-expandable-collapsed");
} else {
@@ -1185,58 +1083,38 @@
/**
* @constructor
- * @param {WebInspector.TimelineCalculator} calculator
- * @param {boolean} showShortEvents
+ * @implements {WebInspector.TimelinePresentationModel.Filter}
*/
-WebInspector.TimelineRecordFilter = function(calculator, showShortEvents)
+WebInspector.TimelineCategoryFilter = function()
{
- this._calculator = calculator;
- this._showShortEvents = showShortEvents;
}
-WebInspector.TimelineRecordFilter.prototype = {
+WebInspector.TimelineCategoryFilter.prototype = {
/**
* @param {WebInspector.TimelinePresentationModel.Record} record
*/
accept: function(record)
{
- if (record.category.hidden)
- return false;
- if (!this._showShortEvents && !record.isLong())
- return false;
- var percentages = this._calculator.computeBarGraphPercentages(record);
- return percentages.start <= 100 && percentages.endWithChildren >= 0;
+ return !record.category.hidden;
}
}
/**
+ * @param {WebInspector.TimelinePanel} panel
* @constructor
- * @param {WebInspector.TimelinePresentationModel} model
- * @param {Object} rootRecord
- * @param {boolean} showShortEvents
+ * @implements {WebInspector.TimelinePresentationModel.Filter}
*/
-WebInspector.TimelineStartAtZeroRecordFilter = function(model, rootRecord, showShortEvents)
+WebInspector.TimelineIsLongFilter = function(panel)
{
- this._windowIndexLeft = model.windowIndexLeft;
- this._windowIndexRight = model.windowIndexRight;
- this._rootRecord = rootRecord;
- this._topLevelRecordIndex = 0;
- this._showShortEvents = showShortEvents;
+ this._panel = panel;
}
-WebInspector.TimelineStartAtZeroRecordFilter.prototype = {
+WebInspector.TimelineIsLongFilter.prototype = {
/**
* @param {WebInspector.TimelinePresentationModel.Record} record
*/
accept: function(record)
{
- if (record.category.hidden)
- return false;
- if (record.parent === this._rootRecord)
- ++this._topLevelRecordIndex;
- if (!this._showShortEvents && !record.isLong())
- return false;
- return this._topLevelRecordIndex > this._windowIndexLeft &&
- (typeof this._windowIndexRight !== "number" || this._topLevelRecordIndex <= this._windowIndexRight);
+ return this._panel._showShortEvents || record.isLong();
}
}
Modified: trunk/Source/WebCore/inspector/front-end/TimelinePresentationModel.js (109106 => 109107)
--- trunk/Source/WebCore/inspector/front-end/TimelinePresentationModel.js 2012-02-28 16:11:56 UTC (rev 109106)
+++ trunk/Source/WebCore/inspector/front-end/TimelinePresentationModel.js 2012-02-28 16:18:58 UTC (rev 109107)
@@ -39,6 +39,8 @@
this._addCategory(new WebInspector.TimelineCategory("scripting", WebInspector.UIString("Scripting"), "rgb(157,231,119)"));
this._addCategory(new WebInspector.TimelineCategory("rendering", WebInspector.UIString("Rendering"), "rgb(164,60,255)"));
this._linkifier = WebInspector.debuggerPresentationModel.createLinkifier();
+ this._glueRecords = false;
+ this._filters = [];
this.reset();
}
@@ -50,19 +52,14 @@
WebInspector.TimelinePresentationModel.shortRecordThreshold = 0.015;
WebInspector.TimelinePresentationModel.prototype = {
- createFormattedRecord: function(record, parentRecord, scriptDetails)
+ /**
+ * @param {WebInspector.TimelinePresentationModel.Filter} filter
+ */
+ addFilter: function(filter)
{
- return new WebInspector.TimelinePresentationModel.Record(this, record, parentRecord, scriptDetails);
+ this._filters.push(filter);
},
- _createRootRecord: function()
- {
- var rootRecord = {};
- rootRecord.children = [];
- rootRecord.aggregatedStats = {};
- return rootRecord;
- },
-
rootRecord: function()
{
return this._rootRecord;
@@ -71,18 +68,105 @@
reset: function()
{
this._linkifier.reset();
- this._rootRecord = this._createRootRecord();
+ this._rootRecord = new WebInspector.TimelinePresentationModel.Record(this, { type: WebInspector.TimelineModel.RecordType.Root }, null, null);
this._sendRequestRecords = {};
this._scheduledResourceRequests = {};
this._timerRecords = {};
this._requestAnimationFrameRecords = {};
-
+ this._minimumRecordTime = -1;
+ this._maximumRecordTime = -1;
this._resetWindow();
},
- findParentRecord: function(record)
+ minimumRecordTime: function()
{
+ return this._minimumRecordTime;
+ },
+
+ maximumRecordTime: function()
+ {
+ return this._maximumRecordTime;
+ },
+
+ addRecord: function(record, parentRecord)
+ {
+ var connectedToOldRecord = false;
var recordTypes = WebInspector.TimelineModel.RecordType;
+
+ if (record.type === recordTypes.MarkDOMContent || record.type === recordTypes.MarkLoad)
+ parentRecord = null; // No bar entry for load events.
+ else {
+ var newParentRecord = this._findParentRecord(record);
+ if (newParentRecord) {
+ parentRecord = newParentRecord;
+ connectedToOldRecord = true;
+ }
+ }
+
+ var children = record.children;
+ var scriptDetails;
+ if (record.data && record.data["scriptName"]) {
+ scriptDetails = {
+ scriptName: record.data["scriptName"],
+ scriptLine: record.data["scriptLine"]
+ }
+ };
+
+ if ((record.type === recordTypes.TimerFire || record.type === recordTypes.FireAnimationFrame) && children && children.length) {
+ var childRecord = children[0];
+ if (childRecord.type === recordTypes.FunctionCall) {
+ scriptDetails = {
+ scriptName: childRecord.data["scriptName"],
+ scriptLine: childRecord.data["scriptLine"]
+ };
+ children = childRecord.children.concat(children.slice(1));
+ }
+ }
+
+ var formattedRecord = new WebInspector.TimelinePresentationModel.Record(this, record, parentRecord, scriptDetails);
+ this._updateBoundaries(formattedRecord);
+
+ if (record.type === recordTypes.MarkDOMContent || record.type === recordTypes.MarkLoad)
+ return formattedRecord;
+
+ formattedRecord.collapsed = (parentRecord === this._rootRecord);
+
+ var childrenCount = children ? children.length : 0;
+ for (var i = 0; i < childrenCount; ++i)
+ this.addRecord(children[i], formattedRecord);
+
+ formattedRecord.calculateAggregatedStats(this._categories);
+
+ if (connectedToOldRecord) {
+ record = formattedRecord;
+ do {
+ var parent = record.parent;
+ if (parent.lastChildEndTime < record.lastChildEndTime)
+ parent.lastChildEndTime = record.lastChildEndTime;
+ for (var category in formattedRecord.aggregatedStats)
+ parent.aggregatedStats[category] += formattedRecord.aggregatedStats[category];
+ record = parent;
+ } while (record.parent);
+ } else {
+ if (parentRecord !== this._rootRecord)
+ parentRecord.selfTime -= formattedRecord.endTime - formattedRecord.startTime;
+ }
+ return formattedRecord;
+ },
+
+ _updateBoundaries: function(formattedRecord)
+ {
+ if (this._minimumRecordTime === -1 || formattedRecord.startTime < this._minimumRecordTime)
+ this._minimumRecordTime = formattedRecord.startTime;
+ if (this._maximumRecordTime === -1 || formattedRecord.endTime > this._maximumRecordTime)
+ this._maximumRecordTime = formattedRecord.endTime;
+ },
+
+ _findParentRecord: function(record)
+ {
+ if (!this._glueRecords)
+ return null;
+ var recordTypes = WebInspector.TimelineModel.RecordType;
var parentRecord;
if (record.type === recordTypes.ResourceReceiveResponse ||
record.type === recordTypes.ResourceFinish ||
@@ -105,6 +189,11 @@
this.windowIndexRight = null;
},
+ setGlueRecords: function(glue)
+ {
+ this._glueRecords = glue;
+ },
+
get categories()
{
return this._categories;
@@ -129,14 +218,8 @@
this.dispatchEventToListeners(WebInspector.TimelinePresentationModel.Events.WindowChanged);
},
- /**
- * @param {number} left
- * @param {?number} right
- */
- setWindowIndices: function(left, right)
+ fireWindowChanged: function()
{
- this.windowIndexLeft = left;
- this.windowIndexRight = right;
this.dispatchEventToListeners(WebInspector.TimelinePresentationModel.Events.WindowChanged);
},
@@ -157,6 +240,7 @@
var categories = this._categories;
var recordStyles = {};
+ recordStyles[recordTypes.Root] = { title: "#root", category: categories["loading"] };
recordStyles[recordTypes.EventDispatch] = { title: WebInspector.UIString("Event"), category: categories["scripting"] };
recordStyles[recordTypes.Layout] = { title: WebInspector.UIString("Layout"), category: categories["rendering"] };
recordStyles[recordTypes.RecalculateStyles] = { title: WebInspector.UIString("Recalculate Style"), category: categories["rendering"] };
@@ -184,6 +268,54 @@
this._recordStylesArray = recordStyles;
}
return this._recordStylesArray;
+ },
+
+ filteredRecords: function()
+ {
+ function filter(record)
+ {
+ for (var i = 0; i < this._filters.length; ++i) {
+ if (!this._filters[i].accept(record))
+ return false;
+ }
+ return true;
+ }
+ return this._filterRecords(filter.bind(this));
+ },
+
+ _filterRecords: function(filter)
+ {
+ var recordsInWindow = [];
+
+ var stack = [{children: this._rootRecord.children, index: 0, parentIsCollapsed: false}];
+ while (stack.length) {
+ var entry = stack[stack.length - 1];
+ var records = entry.children;
+ if (records && entry.index < records.length) {
+ var record = records[entry.index];
+ ++entry.index;
+
+ if (filter(record)) {
+ ++record.parent._invisibleChildrenCount;
+ if (!entry.parentIsCollapsed)
+ recordsInWindow.push(record);
+ }
+
+ record._invisibleChildrenCount = 0;
+
+ stack.push({children: record.children,
+ index: 0,
+ parentIsCollapsed: (entry.parentIsCollapsed || record.collapsed),
+ parentRecord: record,
+ windowLengthBeforeChildrenTraversal: recordsInWindow.length});
+ } else {
+ stack.pop();
+ if (entry.parentRecord)
+ entry.parentRecord._visibleChildrenCount = recordsInWindow.length - entry.windowLengthBeforeChildrenTraversal;
+ }
+ }
+
+ return recordsInWindow;
}
}
@@ -300,6 +432,16 @@
return this._children;
},
+ get visibleChildrenCount()
+ {
+ return this._visibleChildrenCount || 0;
+ },
+
+ get invisibleChildrenCount()
+ {
+ return this._invisibleChildrenCount || 0;
+ },
+
containsTime: function(time)
{
return this.startTime <= time && time <= this.endTime;
@@ -574,3 +716,17 @@
this._appendElementRow(title, framesTable, "timeline-stacktrace-title");
}
}
+
+/**
+ * @interface
+ */
+WebInspector.TimelinePresentationModel.Filter = function()
+{
+}
+
+WebInspector.TimelinePresentationModel.Filter.prototype = {
+ /**
+ * @param {WebInspector.TimelinePresentationModel.Record} record
+ */
+ accept: function(record) { return false; }
+}