Diff
Modified: trunk/Source/WebInspectorUI/ChangeLog (187633 => 187634)
--- trunk/Source/WebInspectorUI/ChangeLog 2015-07-31 01:49:35 UTC (rev 187633)
+++ trunk/Source/WebInspectorUI/ChangeLog 2015-07-31 01:55:56 UTC (rev 187634)
@@ -1,3 +1,66 @@
+2015-07-30 Matt Baker <mattba...@apple.com>
+
+ Web Inspector: Better share objects generated from timeline events (Records)
+ https://bugs.webkit.org/show_bug.cgi?id=147029
+
+ Reviewed by Brian Burg.
+
+ This patch changes the way TimelineManager processes events, preserving the event hierarchy after
+ converting payloads to TimelineRecord objects by retaining parent-child relationships between records.
+ This eliminates the need for RenderingFrameTimelineRecord objects to create a separate copy of their child
+ records, and provides richer data for the Timelines UI.
+
+ * UserInterface/Controllers/TimelineManager.js:
+ (WebInspector.TimelineManager.prototype.eventRecorded):
+ Track the parent TimelineRecord as child record payloads are unpacked, and create
+ a hierarchy of TimelineRecords that mirrors the original event payload hierarchy.
+ (WebInspector.TimelineManager.prototype._processRecord):
+ RenderingFrameTimelineRecord is now processed like any other event.
+ (WebInspector.TimelineManager.prototype._processNestedRecords): Deleted.
+ Reverted back to a single pass over the incoming timeline event payload.
+
+ * UserInterface/Models/LayoutTimelineRecord.js:
+ (WebInspector.LayoutTimelineRecord):
+ (WebInspector.LayoutTimelineRecord.prototype.get duringComposite): Deleted.
+ Removed duringComposite property and constructor parameter. No longer needed.
+
+ * UserInterface/Models/RenderingFrameTimelineRecord.js:
+ (WebInspector.RenderingFrameTimelineRecord.prototype.get children): Deleted.
+ Removed children property. It now exists on the base class TimelineRecord.
+ Also removed code that was needed to prevent paint time from being added twice.
+
+ * UserInterface/Models/ScriptTimelineRecord.js:
+ (WebInspector.ScriptTimelineRecord.prototype._initializeProfileFromPayload):
+ (WebInspector.ScriptTimelineRecord):
+ Removed workaround added in:
+ <https://webkit.org/b/147025> Web Inspector: REGRESSION (r186218) ScriptTimelineRecord attempts to access null property
+
+ * UserInterface/Models/TimelineRecord.js:
+ (WebInspector.TimelineRecord):
+ (WebInspector.TimelineRecord.prototype.get children):
+ Added children property.
+
+ * UserInterface/Views/RenderingFrameTimelineView.js:
+ (WebInspector.RenderingFrameTimelineView.prototype._processPendingRecords):
+ Now that we preserve the frame's child record hierarchy, we process the entire tree,
+ yielding richer data grid output:
+
+ Frame X
+ Styles Recalculated
+ Layout Invalidated
+ Composite
+ Paint
+ Paint
+
+ Compared to the previous output:
+
+ Frame X
+ Styles Recalculated
+ Layout Invalidated
+ Composite
+ Paint
+ Paint
+
2015-07-30 Devin Rousso <drou...@apple.com>
Web Inspector: Support smart-pasting in the Rules sidebar panel
Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js (187633 => 187634)
--- trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js 2015-07-31 01:49:35 UTC (rev 187633)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js 2015-07-31 01:55:56 UTC (rev 187634)
@@ -183,35 +183,11 @@
if (!this._isCapturing)
return;
- var records = this._processNestedRecords(recordPayload);
- records.forEach(function(currentValue) {
- this._addRecord(currentValue);
- }.bind(this));
- }
-
- // Protected
-
- pageDidLoad(timestamp)
- {
- // Called from WebInspector.PageObserver.
-
- if (isNaN(WebInspector.frameResourceManager.mainFrame.loadEventTimestamp))
- WebInspector.frameResourceManager.mainFrame.markLoadEvent(this.activeRecording.computeElapsedTime(timestamp));
- }
-
- // Private
-
- _processNestedRecords(childRecordPayloads, parentRecordPayload)
- {
- // Convert to a single item array if needed.
- if (!(childRecordPayloads instanceof Array))
- childRecordPayloads = [childRecordPayloads];
-
var records = [];
// Iterate over the records tree using a stack. Doing this recursively has
// been known to cause a call stack overflow. https://webkit.org/b/79106
- var stack = [{array: childRecordPayloads, parent: parentRecordPayload || null, index: 0}];
+ var stack = [{array: [recordPayload], parent: null, parentRecord: null, index: 0}];
while (stack.length) {
var entry = stack.lastValue;
var recordPayloads = entry.array;
@@ -219,19 +195,38 @@
if (entry.index < recordPayloads.length) {
var recordPayload = recordPayloads[entry.index];
var record = this._processEvent(recordPayload, entry.parent);
- if (record)
+ if (record) {
records.push(record);
+ if (entry.parentRecord)
+ entry.parentRecord.children.push(record);
+ }
if (recordPayload.children)
- stack.push({array: recordPayload.children, parent: recordPayload, index: 0});
+ stack.push({array: recordPayload.children, parent: recordPayload, parentRecord: record, index: 0});
++entry.index;
} else
stack.pop();
}
- return records;
+ for (var record of records) {
+ if (record.type === WebInspector.RenderingFrameTimelineRecord && !record.children.length)
+ continue;
+ this._addRecord(record);
+ }
}
+ // Protected
+
+ pageDidLoad(timestamp)
+ {
+ // Called from WebInspector.PageObserver.
+
+ if (isNaN(WebInspector.frameResourceManager.mainFrame.loadEventTimestamp))
+ WebInspector.frameResourceManager.mainFrame.markLoadEvent(this.activeRecording.computeElapsedTime(timestamp));
+ }
+
+ // Private
+
_processRecord(recordPayload, parentRecordPayload)
{
var startTime = this.activeRecording.computeElapsedTime(recordPayload.startTime);
@@ -279,27 +274,19 @@
case TimelineAgent.EventType.Paint:
// COMPATIBILITY (iOS 6): Paint records data contained x, y, width, height properties. This became a quad "clip".
var quad = recordPayload.data.clip ? new WebInspector.Quad(recordPayload.data.clip) : null;
- var duringComposite = recordPayload.__duringComposite || false;
if (quad)
- return new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.Paint, startTime, endTime, callFrames, sourceCodeLocation, null, null, quad.width, quad.height, quad, duringComposite);
+ return new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.Paint, startTime, endTime, callFrames, sourceCodeLocation, null, null, quad.width, quad.height, quad);
else
- return new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.Paint, startTime, endTime, callFrames, sourceCodeLocation, recordPayload.data.x, recordPayload.data.y, recordPayload.data.width, recordPayload.data.height, null, duringComposite);
+ return new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.Paint, startTime, endTime, callFrames, sourceCodeLocation, recordPayload.data.x, recordPayload.data.y, recordPayload.data.width, recordPayload.data.height);
case TimelineAgent.EventType.Composite:
- recordPayload.children.forEach(function(childRecordPayload) {
- console.assert(childRecordPayload.type === TimelineAgent.EventType.Paint, childRecordPayload.type);
- childRecordPayload.__duringComposite = true;
- });
return new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.Composite, startTime, endTime, callFrames, sourceCodeLocation);
case TimelineAgent.EventType.RenderingFrame:
- if (!recordPayload.children)
+ if (!recordPayload.children || !recordPayload.children.length)
return null;
- var children = this._processNestedRecords(recordPayload.children, recordPayload);
- if (!children.length)
- return null;
- return new WebInspector.RenderingFrameTimelineRecord(startTime, endTime, children);
+ return new WebInspector.RenderingFrameTimelineRecord(startTime, endTime);
case TimelineAgent.EventType.EvaluateScript:
if (!sourceCodeLocation) {
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/LayoutTimelineRecord.js (187633 => 187634)
--- trunk/Source/WebInspectorUI/UserInterface/Models/LayoutTimelineRecord.js 2015-07-31 01:49:35 UTC (rev 187633)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/LayoutTimelineRecord.js 2015-07-31 01:55:56 UTC (rev 187634)
@@ -25,7 +25,7 @@
WebInspector.LayoutTimelineRecord = class LayoutTimelineRecord extends WebInspector.TimelineRecord
{
- constructor(eventType, startTime, endTime, callFrames, sourceCodeLocation, x, y, width, height, quad, duringComposite)
+ constructor(eventType, startTime, endTime, callFrames, sourceCodeLocation, x, y, width, height, quad)
{
super(WebInspector.TimelineRecord.Type.Layout, startTime, endTime, callFrames, sourceCodeLocation);
@@ -40,7 +40,6 @@
this._width = typeof width === "number" ? width : NaN;
this._height = typeof height === "number" ? height : NaN;
this._quad = quad instanceof WebInspector.Quad ? quad : null;
- this._duringComposite = duringComposite || false;
}
// Static
@@ -109,11 +108,6 @@
return this._quad;
}
- get duringComposite()
- {
- return this._duringComposite;
- }
-
saveIdentityToCookie(cookie)
{
super.saveIdentityToCookie(cookie);
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/RenderingFrameTimelineRecord.js (187633 => 187634)
--- trunk/Source/WebInspectorUI/UserInterface/Models/RenderingFrameTimelineRecord.js 2015-07-31 01:49:35 UTC (rev 187633)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/RenderingFrameTimelineRecord.js 2015-07-31 01:55:56 UTC (rev 187634)
@@ -25,11 +25,10 @@
WebInspector.RenderingFrameTimelineRecord = class RenderingFrameTimelineRecord extends WebInspector.TimelineRecord
{
- constructor(startTime, endTime, children)
+ constructor(startTime, endTime)
{
super(WebInspector.TimelineRecord.Type.RenderingFrame, startTime, endTime);
- this._children = children || [];
this._durationByTaskType = new Map;
this._frameIndex = WebInspector.RenderingFrameTimelineRecord._nextFrameIndex++;
}
@@ -67,11 +66,6 @@
return this._frameIndex + 1;
}
- get children()
- {
- return this._children.slice();
- }
-
durationForTask(taskType)
{
if (this._durationByTaskType.has(taskType))
@@ -96,7 +90,7 @@
if (taskType === WebInspector.RenderingFrameTimelineRecord.TaskType.Other)
duration = this._calculateDurationRemainder();
else {
- duration = this._children.reduce(function(previousValue, currentValue) {
+ duration = this.children.reduce(function(previousValue, currentValue) {
if (!validRecordForTaskType(currentValue))
return previousValue;
@@ -109,18 +103,11 @@
if (taskType === WebInspector.RenderingFrameTimelineRecord.TaskType.Script) {
// Layout events synchronously triggered from _javascript_ must be subtracted from the total
// script time, to prevent the time from being counted twice.
- duration -= this._children.reduce(function(previousValue, currentValue) {
+ duration -= this.children.reduce(function(previousValue, currentValue) {
if (currentValue.type === WebInspector.TimelineRecord.Type.Layout && (currentValue.sourceCodeLocation || currentValue.callFrames))
return previousValue + currentValue.duration;
return previousValue;
}, 0);
- } else if (taskType === WebInspector.RenderingFrameTimelineRecord.TaskType.Paint) {
- // Paint events triggered during a Composite event must be subtracted from the total painting time,
- // since the compositing time already includes time spent in these Paint events.
- var paintRecords = this._children.filter(function(record) { return record.eventType === WebInspector.LayoutTimelineRecord.EventType.Paint; });
- duration -= paintRecords.reduce(function(previousValue, currentValue) {
- return currentValue.duringComposite ? previousValue + currentValue.duration : previousValue;
- }, 0);
}
}
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/ScriptTimelineRecord.js (187633 => 187634)
--- trunk/Source/WebInspectorUI/UserInterface/Models/ScriptTimelineRecord.js 2015-07-31 01:49:35 UTC (rev 187633)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/ScriptTimelineRecord.js 2015-07-31 01:55:56 UTC (rev 187634)
@@ -73,13 +73,6 @@
if (this._profile || !this._profilePayload)
return;
- // FIXME: <https://webkit.org/b/147029> Web Inspector: Better share objects generated from timeline events (Records)
- if (this._profilePayload.__profile) {
- this._profile = this._profilePayload.__profile;
- this._profilePayload = undefined;
- return;
- }
-
var payload = this._profilePayload;
this._profilePayload = undefined;
@@ -151,7 +144,7 @@
}
}
- this._profile = payload.__profile = new WebInspector.Profile(rootNodes);
+ this._profile = new WebInspector.Profile(rootNodes);
}
};
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecord.js (187633 => 187634)
--- trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecord.js 2015-07-31 01:49:35 UTC (rev 187633)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecord.js 2015-07-31 01:55:56 UTC (rev 187634)
@@ -39,6 +39,7 @@
this._endTime = endTime || NaN;
this._callFrames = callFrames || null;
this._sourceCodeLocation = sourceCodeLocation || null;
+ this._children = [];
}
// Public
@@ -121,6 +122,11 @@
return this._sourceCodeLocation;
}
+ get children()
+ {
+ return this._children;
+ }
+
saveIdentityToCookie(cookie)
{
cookie[WebInspector.TimelineRecord.SourceCodeURLCookieKey] = this._sourceCodeLocation ? this._sourceCodeLocation.sourceCode.url ? this._sourceCodeLocation.sourceCode.url.hash : null : null;
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/RenderingFrameTimelineView.js (187633 => 187634)
--- trunk/Source/WebInspectorUI/UserInterface/Views/RenderingFrameTimelineView.js 2015-07-31 01:49:35 UTC (rev 187633)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/RenderingFrameTimelineView.js 2015-07-31 01:55:56 UTC (rev 187634)
@@ -263,15 +263,23 @@
var treeElement = new WebInspector.TimelineRecordTreeElement(renderingFrameTimelineRecord);
var dataGridNode = new WebInspector.RenderingFrameTimelineDataGridNode(renderingFrameTimelineRecord, this.zeroTime);
-
this._dataGrid.addRowInSortOrder(treeElement, dataGridNode);
- for (var childRecord of renderingFrameTimelineRecord.children) {
+ var stack = [{children: renderingFrameTimelineRecord.children, parentTreeElement: treeElement, index: 0}];
+ while (stack.length) {
+ var entry = stack.lastValue;
+ if (entry.index >= entry.children.length) {
+ stack.pop();
+ continue;
+ }
+
+ var childRecord = entry.children[entry.index];
+ var childTreeElement = null;
if (childRecord.type === WebInspector.TimelineRecord.Type.Layout) {
- var layoutTreeElement = new WebInspector.TimelineRecordTreeElement(childRecord, WebInspector.SourceCodeLocation.NameStyle.Short);
+ childTreeElement = new WebInspector.TimelineRecordTreeElement(childRecord, WebInspector.SourceCodeLocation.NameStyle.Short);
var layoutDataGridNode = new WebInspector.LayoutTimelineDataGridNode(childRecord, this.zeroTime);
- this._dataGrid.addRowInSortOrder(layoutTreeElement, layoutDataGridNode, treeElement);
+ this._dataGrid.addRowInSortOrder(childTreeElement, layoutDataGridNode, entry.parentTreeElement);
} else if (childRecord.type === WebInspector.TimelineRecord.Type.Script) {
var rootNodes = [];
if (childRecord.profile) {
@@ -279,21 +287,21 @@
rootNodes = childRecord.profile.topDownRootNodes;
}
- var zeroTime = this.zeroTime;
- var scriptTreeElement = new WebInspector.TimelineRecordTreeElement(childRecord, WebInspector.SourceCodeLocation.NameStyle.Short, rootNodes.length);
- var scriptDataGridNode = new WebInspector.ScriptTimelineDataGridNode(childRecord, zeroTime);
+ childTreeElement = new WebInspector.TimelineRecordTreeElement(childRecord, WebInspector.SourceCodeLocation.NameStyle.Short, rootNodes.length);
+ var scriptDataGridNode = new WebInspector.ScriptTimelineDataGridNode(childRecord, this.zeroTime);
- this._dataGrid.addRowInSortOrder(scriptTreeElement, scriptDataGridNode, treeElement);
+ this._dataGrid.addRowInSortOrder(childTreeElement, scriptDataGridNode, entry.parentTreeElement);
- var startTime = this.startTime;
- var endTime = this.endTime;
-
for (var profileNode of rootNodes) {
var profileNodeTreeElement = new WebInspector.ProfileNodeTreeElement(profileNode, this);
- var profileNodeDataGridNode = new WebInspector.ProfileNodeDataGridNode(profileNode, zeroTime, startTime, endTime);
- this._dataGrid.addRowInSortOrder(profileNodeTreeElement, profileNodeDataGridNode, scriptTreeElement);
+ var profileNodeDataGridNode = new WebInspector.ProfileNodeDataGridNode(profileNode, this.zeroTime, this.startTime, this.endTime);
+ this._dataGrid.addRowInSortOrder(profileNodeTreeElement, profileNodeDataGridNode, childTreeElement);
}
}
+
+ if (childTreeElement && childRecord.children.length)
+ stack.push({children: childRecord.children, parentTreeElement: childTreeElement, index: 0});
+ ++entry.index;
}
}