<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[181626] trunk/Source/WebInspectorUI</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/181626">181626</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2015-03-17 01:43:30 -0700 (Tue, 17 Mar 2015)</dd>
</dl>
<h3>Log Message</h3>
<pre>Web Inspector: Show rendering frames (and FPS) in Layout and Rendering timeline
https://bugs.webkit.org/show_bug.cgi?id=142029
Patch by Matt Baker <mattbaker@apple.com> on 2015-03-17
Reviewed by Timothy Hatcher.
Add UI for showing runloop records and their child records as a frame histogram,
with the recording time on the x-axis and the frame duration on the y-axis. Each frame
is comprised of colored regions representing the time spent in various activities (script,
layout, etc).
Eventually the Frames timeline will replace the Layout & Rendering timeline. Until the views
for the new timeline are finalized the Layout & Rendering timeline will remain in place.
* Localizations/en.lproj/localizedStrings.js:
* UserInterface/Main.html:
New string and files.
* UserInterface/Controllers/TimelineManager.js:
(WebInspector.TimelineManager.prototype.eventRecorded):
(WebInspector.TimelineManager.prototype.pageDidLoad):
(WebInspector.TimelineManager.prototype._processNestedRecords):
(WebInspector.TimelineManager.prototype._processRecord):
(WebInspector.TimelineManager.prototype._processEvent):
(WebInspector.TimelineManager.prototype._loadNewRecording):
(WebInspector.TimelineManager.prototype.eventRecorded.processRecord): Deleted.
Added support for new runloop record type and nested record handling.
* UserInterface/Images/Frames.png: Added.
* UserInterface/Images/Frames@2x.png: Added.
* UserInterface/Images/FramesLarge.png: Added.
* UserInterface/Images/FramesLarge@2x.png: Added.
New images for runloop timeline overview graph and runloop tree records.
* UserInterface/Models/RunLoopTimelineRecord.js: Added.
(WebInspector.RunLoopTimelineRecord):
(WebInspector.RunLoopTimelineRecord.prototype.get children):
(WebInspector.RunLoopTimelineRecord.prototype.get durationRemainder):
(WebInspector.RunLoopTimelineRecord.prototype.durationForRecords.get var):
Extends TimelineRecord to add child records and subframe duration details.
* UserInterface/Models/Timeline.js:
(WebInspector.Timeline.prototype.get displayName):
(WebInspector.Timeline.prototype.get iconClassName):
New UI strings and icons.
* UserInterface/Models/TimelineRecord.js:
* UserInterface/Views/ContentView.js:
(WebInspector.ContentView):
* UserInterface/Views/LayoutTimelineView.js:
(WebInspector.LayoutTimelineView.prototype._layoutTimelineRecordAdded):
* UserInterface/Views/TimelineRecordTreeElement.js:
(WebInspector.TimelineRecordTreeElement):
Added support for new runloop record type.
* UserInterface/Views/RunLoopTimelineOverviewGraph.css: Added.
(.timeline-overview-graph.runloop > .divider):
(.timeline-overview-graph.runloop > .divider > span):
New styles for runloop timeline graph.
* UserInterface/Views/RunLoopTimelineOverviewGraph.js: Added.
(WebInspector.RunLoopTimelineOverviewGraph):
(WebInspector.RunLoopTimelineOverviewGraph.prototype.updateLayout.createFrame):
(WebInspector.RunLoopTimelineOverviewGraph.prototype.get graphHeightSeconds.this):
(WebInspector.RunLoopTimelineOverviewGraph.prototype.get graphHeightSeconds):
(WebInspector.RunLoopTimelineOverviewGraph.prototype._updateDividers.createDividerAtPosition.get if):
New overview graph for displaying TimelineRecordFrames and horizontal frame budget dividers.
* UserInterface/Views/TimelineIcons.css:
(.runloop-icon .icon):
(.runloop-icon.large .icon):
(.runloop-record .icon):
* UserInterface/Views/TimelineSidebarPanel.js:
New runloop icon styles.
* UserInterface/Views/TimelineOverviewGraph.js:
(WebInspector.TimelineOverviewGraph):
Updated factory to support creation of the new overview graph.
* UserInterface/Views/TimelineRecordFrame.css: Added.
(.timeline-record-frame):
(.timeline-record-frame > .frame):
(.timeline-record-frame > .dropped):
(.timeline-record-frame > .frame > .duration):
(.timeline-record-frame > .frame > .duration:first-child):
(.timeline-record-frame > .frame > .duration:last-child):
(.timeline-record-frame > .frame > .duration.timeline-record-type-network):
(.timeline-record-frame > .frame > .duration.timeline-record-type-layout):
(.timeline-record-frame > .frame > .duration.timeline-record-type-script):
New styles for frame bars in the runloop timeline graph.
* UserInterface/Views/TimelineRecordFrame.js: Added.
(WebInspector.TimelineRecordFrame):
(WebInspector.TimelineRecordFrame.createCombinedFrames):
(WebInspector.TimelineRecordFrame.prototype.get element):
(WebInspector.TimelineRecordFrame.prototype.get duration):
(WebInspector.TimelineRecordFrame.prototype.get records):
(WebInspector.TimelineRecordFrame.prototype.set records):
(WebInspector.TimelineRecordFrame.prototype._updateChildElements.createDurationElement):
New view representing a single frame within the runloop overview graph.
* WebInspectorUI.vcxproj/WebInspectorUI.vcxproj:
* WebInspectorUI.vcxproj/WebInspectorUI.vcxproj.filters:
New files.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</a></li>
<li><a href="#trunkSourceWebInspectorUILocalizationsenlprojlocalizedStringsjs">trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceControllersTimelineManagerjs">trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceMainhtml">trunk/Source/WebInspectorUI/UserInterface/Main.html</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsTimelinejs">trunk/Source/WebInspectorUI/UserInterface/Models/Timeline.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsTimelineRecordjs">trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecord.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsContentViewjs">trunk/Source/WebInspectorUI/UserInterface/Views/ContentView.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsLayoutTimelineViewjs">trunk/Source/WebInspectorUI/UserInterface/Views/LayoutTimelineView.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsTimelineIconscss">trunk/Source/WebInspectorUI/UserInterface/Views/TimelineIcons.css</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsTimelineOverviewGraphjs">trunk/Source/WebInspectorUI/UserInterface/Views/TimelineOverviewGraph.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsTimelineRecordTreeElementjs">trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordTreeElement.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsTimelineSidebarPaneljs">trunk/Source/WebInspectorUI/UserInterface/Views/TimelineSidebarPanel.js</a></li>
<li><a href="#trunkSourceWebInspectorUIWebInspectorUIvcxprojWebInspectorUIvcxproj">trunk/Source/WebInspectorUI/WebInspectorUI.vcxproj/WebInspectorUI.vcxproj</a></li>
<li><a href="#trunkSourceWebInspectorUIWebInspectorUIvcxprojWebInspectorUIvcxprojfilters">trunk/Source/WebInspectorUI/WebInspectorUI.vcxproj/WebInspectorUI.vcxproj.filters</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceImagesFramespng">trunk/Source/WebInspectorUI/UserInterface/Images/Frames.png</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceImagesFrames2xpng">trunk/Source/WebInspectorUI/UserInterface/Images/Frames@2x.png</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceImagesFramesLargepng">trunk/Source/WebInspectorUI/UserInterface/Images/FramesLarge.png</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceImagesFramesLarge2xpng">trunk/Source/WebInspectorUI/UserInterface/Images/FramesLarge@2x.png</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsRunLoopTimelineRecordjs">trunk/Source/WebInspectorUI/UserInterface/Models/RunLoopTimelineRecord.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsRunLoopTimelineOverviewGraphcss">trunk/Source/WebInspectorUI/UserInterface/Views/RunLoopTimelineOverviewGraph.css</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsRunLoopTimelineOverviewGraphjs">trunk/Source/WebInspectorUI/UserInterface/Views/RunLoopTimelineOverviewGraph.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsTimelineRecordFramecss">trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordFrame.css</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsTimelineRecordFramejs">trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordFrame.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (181625 => 181626)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2015-03-17 08:41:19 UTC (rev 181625)
+++ trunk/Source/WebInspectorUI/ChangeLog        2015-03-17 08:43:30 UTC (rev 181626)
</span><span class="lines">@@ -1,3 +1,109 @@
</span><ins>+2015-03-17 Matt Baker <mattbaker@apple.com>
+
+ Web Inspector: Show rendering frames (and FPS) in Layout and Rendering timeline
+ https://bugs.webkit.org/show_bug.cgi?id=142029
+
+ Reviewed by Timothy Hatcher.
+
+ Add UI for showing runloop records and their child records as a frame histogram,
+ with the recording time on the x-axis and the frame duration on the y-axis. Each frame
+ is comprised of colored regions representing the time spent in various activities (script,
+ layout, etc).
+
+ Eventually the Frames timeline will replace the Layout & Rendering timeline. Until the views
+ for the new timeline are finalized the Layout & Rendering timeline will remain in place.
+
+ * Localizations/en.lproj/localizedStrings.js:
+ * UserInterface/Main.html:
+ New string and files.
+
+ * UserInterface/Controllers/TimelineManager.js:
+ (WebInspector.TimelineManager.prototype.eventRecorded):
+ (WebInspector.TimelineManager.prototype.pageDidLoad):
+ (WebInspector.TimelineManager.prototype._processNestedRecords):
+ (WebInspector.TimelineManager.prototype._processRecord):
+ (WebInspector.TimelineManager.prototype._processEvent):
+ (WebInspector.TimelineManager.prototype._loadNewRecording):
+ (WebInspector.TimelineManager.prototype.eventRecorded.processRecord): Deleted.
+ Added support for new runloop record type and nested record handling.
+
+ * UserInterface/Images/Frames.png: Added.
+ * UserInterface/Images/Frames@2x.png: Added.
+ * UserInterface/Images/FramesLarge.png: Added.
+ * UserInterface/Images/FramesLarge@2x.png: Added.
+ New images for runloop timeline overview graph and runloop tree records.
+
+ * UserInterface/Models/RunLoopTimelineRecord.js: Added.
+ (WebInspector.RunLoopTimelineRecord):
+ (WebInspector.RunLoopTimelineRecord.prototype.get children):
+ (WebInspector.RunLoopTimelineRecord.prototype.get durationRemainder):
+ (WebInspector.RunLoopTimelineRecord.prototype.durationForRecords.get var):
+ Extends TimelineRecord to add child records and subframe duration details.
+
+ * UserInterface/Models/Timeline.js:
+ (WebInspector.Timeline.prototype.get displayName):
+ (WebInspector.Timeline.prototype.get iconClassName):
+ New UI strings and icons.
+
+ * UserInterface/Models/TimelineRecord.js:
+ * UserInterface/Views/ContentView.js:
+ (WebInspector.ContentView):
+ * UserInterface/Views/LayoutTimelineView.js:
+ (WebInspector.LayoutTimelineView.prototype._layoutTimelineRecordAdded):
+ * UserInterface/Views/TimelineRecordTreeElement.js:
+ (WebInspector.TimelineRecordTreeElement):
+ Added support for new runloop record type.
+
+ * UserInterface/Views/RunLoopTimelineOverviewGraph.css: Added.
+ (.timeline-overview-graph.runloop > .divider):
+ (.timeline-overview-graph.runloop > .divider > span):
+ New styles for runloop timeline graph.
+
+ * UserInterface/Views/RunLoopTimelineOverviewGraph.js: Added.
+ (WebInspector.RunLoopTimelineOverviewGraph):
+ (WebInspector.RunLoopTimelineOverviewGraph.prototype.updateLayout.createFrame):
+ (WebInspector.RunLoopTimelineOverviewGraph.prototype.get graphHeightSeconds.this):
+ (WebInspector.RunLoopTimelineOverviewGraph.prototype.get graphHeightSeconds):
+ (WebInspector.RunLoopTimelineOverviewGraph.prototype._updateDividers.createDividerAtPosition.get if):
+ New overview graph for displaying TimelineRecordFrames and horizontal frame budget dividers.
+
+ * UserInterface/Views/TimelineIcons.css:
+ (.runloop-icon .icon):
+ (.runloop-icon.large .icon):
+ (.runloop-record .icon):
+ * UserInterface/Views/TimelineSidebarPanel.js:
+ New runloop icon styles.
+
+ * UserInterface/Views/TimelineOverviewGraph.js:
+ (WebInspector.TimelineOverviewGraph):
+ Updated factory to support creation of the new overview graph.
+
+ * UserInterface/Views/TimelineRecordFrame.css: Added.
+ (.timeline-record-frame):
+ (.timeline-record-frame > .frame):
+ (.timeline-record-frame > .dropped):
+ (.timeline-record-frame > .frame > .duration):
+ (.timeline-record-frame > .frame > .duration:first-child):
+ (.timeline-record-frame > .frame > .duration:last-child):
+ (.timeline-record-frame > .frame > .duration.timeline-record-type-network):
+ (.timeline-record-frame > .frame > .duration.timeline-record-type-layout):
+ (.timeline-record-frame > .frame > .duration.timeline-record-type-script):
+ New styles for frame bars in the runloop timeline graph.
+
+ * UserInterface/Views/TimelineRecordFrame.js: Added.
+ (WebInspector.TimelineRecordFrame):
+ (WebInspector.TimelineRecordFrame.createCombinedFrames):
+ (WebInspector.TimelineRecordFrame.prototype.get element):
+ (WebInspector.TimelineRecordFrame.prototype.get duration):
+ (WebInspector.TimelineRecordFrame.prototype.get records):
+ (WebInspector.TimelineRecordFrame.prototype.set records):
+ (WebInspector.TimelineRecordFrame.prototype._updateChildElements.createDurationElement):
+ New view representing a single frame within the runloop overview graph.
+
+ * WebInspectorUI.vcxproj/WebInspectorUI.vcxproj:
+ * WebInspectorUI.vcxproj/WebInspectorUI.vcxproj.filters:
+ New files.
+
</ins><span class="cx"> 2015-03-16 Joseph Pecoraro <pecoraro@apple.com>
</span><span class="cx">
</span><span class="cx"> Web Inspector: Add more DOM Native Function parameter strings
</span></span></pre></div>
<a id="trunkSourceWebInspectorUILocalizationsenlprojlocalizedStringsjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (181625 => 181626)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js        2015-03-17 08:41:19 UTC (rev 181625)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js        2015-03-17 08:43:30 UTC (rev 181626)
</span><span class="lines">@@ -397,6 +397,7 @@
</span><span class="cx"> localizedStrings["Reveal in Original Resource"] = "Reveal in Original Resource";
</span><span class="cx"> localizedStrings["Role"] = "Role";
</span><span class="cx"> localizedStrings["Rules"] = "Rules";
</span><ins>+localizedStrings["Runloop Executed"] = "Runloop Executed";
</ins><span class="cx"> localizedStrings["Scheme"] = "Scheme";
</span><span class="cx"> localizedStrings["Scope Chain"] = "Scope Chain";
</span><span class="cx"> localizedStrings["Script"] = "Script";
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceControllersTimelineManagerjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js (181625 => 181626)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js        2015-03-17 08:41:19 UTC (rev 181625)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js        2015-03-17 08:43:30 UTC (rev 181626)
</span><span class="lines">@@ -162,248 +162,268 @@
</span><span class="cx"> this.dispatchEventToListeners(WebInspector.TimelineManager.Event.CapturingStopped);
</span><span class="cx"> },
</span><span class="cx">
</span><del>- eventRecorded: function(originalRecordPayload)
</del><ins>+ eventRecorded: function(recordPayload)
</ins><span class="cx"> {
</span><span class="cx"> // Called from WebInspector.TimelineObserver.
</span><span class="cx">
</span><span class="cx"> if (!this._isCapturing)
</span><span class="cx"> return;
</span><span class="cx">
</span><del>- function processRecord(recordPayload, parentRecordPayload)
- {
- var startTime = this.activeRecording.computeElapsedTime(recordPayload.startTime);
- var endTime = this.activeRecording.computeElapsedTime(recordPayload.endTime);
- var callFrames = this._callFramesFromPayload(recordPayload.stackTrace);
</del><ins>+ var records = this._processNestedRecords(recordPayload);
+ records.forEach(function(currentValue) {
+ this._addRecord(currentValue);
+ }.bind(this));
+ },
</ins><span class="cx">
</span><del>- var significantCallFrame = null;
- if (callFrames) {
- for (var i = 0; i < callFrames.length; ++i) {
- if (callFrames[i].nativeCode)
- continue;
- significantCallFrame = callFrames[i];
- break;
- }
- }
</del><ins>+ pageDidLoad: function(timestamp)
+ {
+ if (isNaN(WebInspector.frameResourceManager.mainFrame.loadEventTimestamp))
+ WebInspector.frameResourceManager.mainFrame.markLoadEvent(this.activeRecording.computeElapsedTime(timestamp));
+ },
</ins><span class="cx">
</span><del>- var sourceCodeLocation = significantCallFrame && significantCallFrame.sourceCodeLocation;
</del><ins>+ // Private
</ins><span class="cx">
</span><del>- switch (recordPayload.type) {
- case TimelineAgent.EventType.MarkLoad:
- console.assert(isNaN(endTime));
</del><ins>+ _processNestedRecords: function(childRecordPayloads, parentRecordPayload)
+ {
+ // Convert to a single item array if needed.
+ if (!(childRecordPayloads instanceof Array))
+ childRecordPayloads = [childRecordPayloads];
</ins><span class="cx">
</span><del>- var frame = WebInspector.frameResourceManager.frameForIdentifier(recordPayload.frameId);
- console.assert(frame);
- if (!frame)
- break;
</del><ins>+ var records = [];
</ins><span class="cx">
</span><del>- frame.markLoadEvent(startTime);
</del><ins>+ // 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}];
+ while (stack.length) {
+ var entry = stack.lastValue;
+ var recordPayloads = entry.array;
</ins><span class="cx">
</span><del>- if (!frame.isMainFrame())
- break;
</del><ins>+ if (entry.index < recordPayloads.length) {
+ var recordPayload = recordPayloads[entry.index];
+ var record = this._processEvent(recordPayload, entry.parent);
+ if (record)
+ records.push(record);
</ins><span class="cx">
</span><del>- var eventMarker = new WebInspector.TimelineMarker(startTime, WebInspector.TimelineMarker.Type.LoadEvent);
- this._activeRecording.addEventMarker(eventMarker);
</del><ins>+ if (recordPayload.children)
+ stack.push({array: recordPayload.children, parent: recordPayload, index: 0});
+ ++entry.index;
+ } else
+ stack.pop();
+ }
</ins><span class="cx">
</span><del>- this._stopAutoRecordingSoon();
</del><ins>+ return records;
+ },
+
+ _processRecord: function(recordPayload, parentRecordPayload)
+ {
+ var startTime = this.activeRecording.computeElapsedTime(recordPayload.startTime);
+ var endTime = this.activeRecording.computeElapsedTime(recordPayload.endTime);
+ var callFrames = this._callFramesFromPayload(recordPayload.stackTrace);
+
+ var significantCallFrame = null;
+ if (callFrames) {
+ for (var i = 0; i < callFrames.length; ++i) {
+ if (callFrames[i].nativeCode)
+ continue;
+ significantCallFrame = callFrames[i];
</ins><span class="cx"> break;
</span><ins>+ }
+ }
</ins><span class="cx">
</span><del>- case TimelineAgent.EventType.MarkDOMContent:
- console.assert(isNaN(endTime));
</del><ins>+ var sourceCodeLocation = significantCallFrame && significantCallFrame.sourceCodeLocation;
</ins><span class="cx">
</span><del>- var frame = WebInspector.frameResourceManager.frameForIdentifier(recordPayload.frameId);
- console.assert(frame);
- if (!frame)
- break;
</del><ins>+ switch (recordPayload.type) {
+ case TimelineAgent.EventType.ScheduleStyleRecalculation:
+ console.assert(isNaN(endTime));
</ins><span class="cx">
</span><del>- frame.markDOMContentReadyEvent(startTime);
</del><ins>+ // Pass the startTime as the endTime since this record type has no duration.
+ return new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.InvalidateStyles, startTime, startTime, callFrames, sourceCodeLocation);
</ins><span class="cx">
</span><del>- if (!frame.isMainFrame())
- break;
</del><ins>+ case TimelineAgent.EventType.RecalculateStyles:
+ return new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.RecalculateStyles, startTime, endTime, callFrames, sourceCodeLocation);
</ins><span class="cx">
</span><del>- var eventMarker = new WebInspector.TimelineMarker(startTime, WebInspector.TimelineMarker.Type.DOMContentEvent);
- this._activeRecording.addEventMarker(eventMarker);
- break;
</del><ins>+ case TimelineAgent.EventType.InvalidateLayout:
+ console.assert(isNaN(endTime));
</ins><span class="cx">
</span><del>- case TimelineAgent.EventType.ScheduleStyleRecalculation:
- console.assert(isNaN(endTime));
</del><ins>+ // Pass the startTime as the endTime since this record type has no duration.
+ return new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.InvalidateLayout, startTime, startTime, callFrames, sourceCodeLocation);
</ins><span class="cx">
</span><del>- // Pass the startTime as the endTime since this record type has no duration.
- this._addRecord(new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.InvalidateStyles, startTime, startTime, callFrames, sourceCodeLocation));
- break;
</del><ins>+ case TimelineAgent.EventType.Layout:
+ var layoutRecordType = sourceCodeLocation ? WebInspector.LayoutTimelineRecord.EventType.ForcedLayout : WebInspector.LayoutTimelineRecord.EventType.Layout;
</ins><span class="cx">
</span><del>- case TimelineAgent.EventType.RecalculateStyles:
- this._addRecord(new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.RecalculateStyles, startTime, endTime, callFrames, sourceCodeLocation));
- break;
</del><ins>+ // COMPATIBILITY (iOS 6): Layout records did not contain area properties. This is not exposed via a quad "root".
+ var quad = recordPayload.data.root ? new WebInspector.Quad(recordPayload.data.root) : null;
+ if (quad)
+ return new WebInspector.LayoutTimelineRecord(layoutRecordType, startTime, endTime, callFrames, sourceCodeLocation, quad.points[0].x, quad.points[0].y, quad.width, quad.height, quad);
+ else
+ return new WebInspector.LayoutTimelineRecord(layoutRecordType, startTime, endTime, callFrames, sourceCodeLocation);
</ins><span class="cx">
</span><del>- case TimelineAgent.EventType.InvalidateLayout:
- console.assert(isNaN(endTime));
</del><ins>+ 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;
+ if (quad)
+ 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);
</ins><span class="cx">
</span><del>- // Pass the startTime as the endTime since this record type has no duration.
- this._addRecord(new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.InvalidateLayout, startTime, startTime, callFrames, sourceCodeLocation));
- break;
</del><ins>+ case TimelineAgent.EventType.RunLoop:
+ if (!recordPayload.children)
+ return null;
</ins><span class="cx">
</span><del>- case TimelineAgent.EventType.Layout:
- var layoutRecordType = sourceCodeLocation ? WebInspector.LayoutTimelineRecord.EventType.ForcedLayout : WebInspector.LayoutTimelineRecord.EventType.Layout;
</del><ins>+ var children = this._processNestedRecords(recordPayload.children, recordPayload);
+ return new WebInspector.RunLoopTimelineRecord(startTime, endTime, children);
</ins><span class="cx">
</span><del>- // COMPATIBILITY (iOS 6): Layout records did not contain area properties. This is not exposed via a quad "root".
- var quad = recordPayload.data.root ? new WebInspector.Quad(recordPayload.data.root) : null;
- if (quad)
- this._addRecord(new WebInspector.LayoutTimelineRecord(layoutRecordType, startTime, endTime, callFrames, sourceCodeLocation, quad.points[0].x, quad.points[0].y, quad.width, quad.height, quad));
- else
- this._addRecord(new WebInspector.LayoutTimelineRecord(layoutRecordType, startTime, endTime, callFrames, sourceCodeLocation));
- break;
</del><ins>+ case TimelineAgent.EventType.EvaluateScript:
+ if (!sourceCodeLocation) {
+ var mainFrame = WebInspector.frameResourceManager.mainFrame;
+ var scriptResource = mainFrame.url === recordPayload.data.url ? mainFrame.mainResource : mainFrame.resourceForURL(recordPayload.data.url, true);
+ if (scriptResource) {
+ // The lineNumber is 1-based, but we expect 0-based.
+ var lineNumber = recordPayload.data.lineNumber - 1;
</ins><span class="cx">
</span><del>- 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;
- if (quad)
- this._addRecord(new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.Paint, startTime, endTime, callFrames, sourceCodeLocation, null, null, quad.width, quad.height, quad));
- else
- this._addRecord(new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.Paint, startTime, endTime, callFrames, sourceCodeLocation, recordPayload.data.x, recordPayload.data.y, recordPayload.data.width, recordPayload.data.height));
</del><ins>+ // FIXME: No column number is provided.
+ sourceCodeLocation = scriptResource.createSourceCodeLocation(lineNumber, 0);
+ }
+ }
+
+ var profileData = recordPayload.data.profile;
+
+ switch (parentRecordPayload && parentRecordPayload.type) {
+ case TimelineAgent.EventType.TimerFire:
+ return new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.TimerFired, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.timerId, profileData);
+ default:
+ return new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.ScriptEvaluated, startTime, endTime, callFrames, sourceCodeLocation, null, profileData);
+ }
+
+ break;
+
+ case TimelineAgent.EventType.ConsoleProfile:
+ var profileData = recordPayload.data.profile;
+ console.assert(profileData);
+ return new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.ConsoleProfileRecorded, startTime, endTime, callFrames, sourceCodeLocation, recordPayload.data.title, profileData);
+
+ case TimelineAgent.EventType.FunctionCall:
+ // FunctionCall always happens as a child of another record, and since the FunctionCall record
+ // has useful info we just make the timeline record here (combining the data from both records).
+ if (!parentRecordPayload)
</ins><span class="cx"> break;
</span><span class="cx">
</span><del>- case TimelineAgent.EventType.EvaluateScript:
- if (!sourceCodeLocation) {
- var mainFrame = WebInspector.frameResourceManager.mainFrame;
- var scriptResource = mainFrame.url === recordPayload.data.url ? mainFrame.mainResource : mainFrame.resourceForURL(recordPayload.data.url, true);
- if (scriptResource) {
- // The lineNumber is 1-based, but we expect 0-based.
- var lineNumber = recordPayload.data.lineNumber - 1;
</del><ins>+ if (!sourceCodeLocation) {
+ var mainFrame = WebInspector.frameResourceManager.mainFrame;
+ var scriptResource = mainFrame.url === recordPayload.data.scriptName ? mainFrame.mainResource : mainFrame.resourceForURL(recordPayload.data.scriptName, true);
+ if (scriptResource) {
+ // The lineNumber is 1-based, but we expect 0-based.
+ var lineNumber = recordPayload.data.scriptLine - 1;
</ins><span class="cx">
</span><del>- // FIXME: No column number is provided.
- sourceCodeLocation = scriptResource.createSourceCodeLocation(lineNumber, 0);
- }
</del><ins>+ // FIXME: No column number is provided.
+ sourceCodeLocation = scriptResource.createSourceCodeLocation(lineNumber, 0);
</ins><span class="cx"> }
</span><ins>+ }
</ins><span class="cx">
</span><del>- var profileData = recordPayload.data.profile;
</del><ins>+ var profileData = recordPayload.data.profile;
</ins><span class="cx">
</span><del>- switch (parentRecordPayload && parentRecordPayload.type) {
- case TimelineAgent.EventType.TimerFire:
- this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.TimerFired, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.timerId, profileData));
- break;
- default:
- this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.ScriptEvaluated, startTime, endTime, callFrames, sourceCodeLocation, null, profileData));
- break;
- }
</del><ins>+ switch (parentRecordPayload.type) {
+ case TimelineAgent.EventType.TimerFire:
+ return new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.TimerFired, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.timerId, profileData);
+ case TimelineAgent.EventType.EventDispatch:
+ return new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.EventDispatched, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.type, profileData);
+ case TimelineAgent.EventType.XHRLoad:
+ return new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.EventDispatched, startTime, endTime, callFrames, sourceCodeLocation, "load", profileData);
+ case TimelineAgent.EventType.XHRReadyStateChange:
+ return new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.EventDispatched, startTime, endTime, callFrames, sourceCodeLocation, "readystatechange", profileData);
+ case TimelineAgent.EventType.FireAnimationFrame:
+ return new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.AnimationFrameFired, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.id, profileData);
+ }
</ins><span class="cx">
</span><del>- break;
</del><ins>+ break;
</ins><span class="cx">
</span><del>- case TimelineAgent.EventType.TimeStamp:
- var eventMarker = new WebInspector.TimelineMarker(startTime, WebInspector.TimelineMarker.Type.TimeStamp);
- this._activeRecording.addEventMarker(eventMarker);
- break;
</del><ins>+ case TimelineAgent.EventType.ProbeSample:
+ // Pass the startTime as the endTime since this record type has no duration.
+ sourceCodeLocation = WebInspector.probeManager.probeForIdentifier(recordPayload.data.probeId).breakpoint.sourceCodeLocation;
+ return new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.ProbeSampleRecorded, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.probeId);
</ins><span class="cx">
</span><del>- case TimelineAgent.EventType.ConsoleProfile:
- var profileData = recordPayload.data.profile;
- console.assert(profileData);
- this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.ConsoleProfileRecorded, startTime, endTime, callFrames, sourceCodeLocation, recordPayload.data.title, profileData));
- break;
</del><ins>+ case TimelineAgent.EventType.TimerInstall:
+ console.assert(isNaN(endTime));
</ins><span class="cx">
</span><del>- case TimelineAgent.EventType.FunctionCall:
- // FunctionCall always happens as a child of another record, and since the FunctionCall record
- // has useful info we just make the timeline record here (combining the data from both records).
- if (!parentRecordPayload)
- break;
</del><ins>+ // Pass the startTime as the endTime since this record type has no duration.
+ return new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.TimerInstalled, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.timerId);
</ins><span class="cx">
</span><del>- if (!sourceCodeLocation) {
- var mainFrame = WebInspector.frameResourceManager.mainFrame;
- var scriptResource = mainFrame.url === recordPayload.data.scriptName ? mainFrame.mainResource : mainFrame.resourceForURL(recordPayload.data.scriptName, true);
- if (scriptResource) {
- // The lineNumber is 1-based, but we expect 0-based.
- var lineNumber = recordPayload.data.scriptLine - 1;
</del><ins>+ case TimelineAgent.EventType.TimerRemove:
+ console.assert(isNaN(endTime));
</ins><span class="cx">
</span><del>- // FIXME: No column number is provided.
- sourceCodeLocation = scriptResource.createSourceCodeLocation(lineNumber, 0);
- }
- }
</del><ins>+ // Pass the startTime as the endTime since this record type has no duration.
+ return new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.TimerRemoved, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.timerId);
</ins><span class="cx">
</span><del>- var profileData = recordPayload.data.profile;
</del><ins>+ case TimelineAgent.EventType.RequestAnimationFrame:
+ console.assert(isNaN(endTime));
</ins><span class="cx">
</span><del>- switch (parentRecordPayload.type) {
- case TimelineAgent.EventType.TimerFire:
- this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.TimerFired, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.timerId, profileData));
- break;
- case TimelineAgent.EventType.EventDispatch:
- this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.EventDispatched, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.type, profileData));
- break;
- case TimelineAgent.EventType.XHRLoad:
- this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.EventDispatched, startTime, endTime, callFrames, sourceCodeLocation, "load", profileData));
- break;
- case TimelineAgent.EventType.XHRReadyStateChange:
- this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.EventDispatched, startTime, endTime, callFrames, sourceCodeLocation, "readystatechange", profileData));
- break;
- case TimelineAgent.EventType.FireAnimationFrame:
- this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.AnimationFrameFired, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.id, profileData));
- break;
- }
</del><ins>+ // Pass the startTime as the endTime since this record type has no duration.
+ return new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.AnimationFrameRequested, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.timerId);
</ins><span class="cx">
</span><del>- break;
</del><ins>+ case TimelineAgent.EventType.CancelAnimationFrame:
+ console.assert(isNaN(endTime));
</ins><span class="cx">
</span><del>- case TimelineAgent.EventType.ProbeSample:
- // Pass the startTime as the endTime since this record type has no duration.
- sourceCodeLocation = WebInspector.probeManager.probeForIdentifier(recordPayload.data.probeId).breakpoint.sourceCodeLocation;
- this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.ProbeSampleRecorded, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.probeId));
- break;
</del><ins>+ // Pass the startTime as the endTime since this record type has no duration.
+ return new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.AnimationFrameCanceled, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.timerId);
+ }
</ins><span class="cx">
</span><del>- case TimelineAgent.EventType.TimerInstall:
- console.assert(isNaN(endTime));
</del><ins>+ return null;
+ },
</ins><span class="cx">
</span><del>- // Pass the startTime as the endTime since this record type has no duration.
- this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.TimerInstalled, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.timerId));
</del><ins>+ _processEvent: function(recordPayload, parentRecordPayload)
+ {
+ var startTime = this.activeRecording.computeElapsedTime(recordPayload.startTime);
+ var endTime = this.activeRecording.computeElapsedTime(recordPayload.endTime);
+
+ switch (recordPayload.type) {
+ case TimelineAgent.EventType.MarkLoad:
+ console.assert(isNaN(endTime));
+
+ var frame = WebInspector.frameResourceManager.frameForIdentifier(recordPayload.frameId);
+ console.assert(frame);
+ if (!frame)
</ins><span class="cx"> break;
</span><span class="cx">
</span><del>- case TimelineAgent.EventType.TimerRemove:
- console.assert(isNaN(endTime));
</del><ins>+ frame.markLoadEvent(startTime);
</ins><span class="cx">
</span><del>- // Pass the startTime as the endTime since this record type has no duration.
- this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.TimerRemoved, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.timerId));
</del><ins>+ if (!frame.isMainFrame())
</ins><span class="cx"> break;
</span><span class="cx">
</span><del>- case TimelineAgent.EventType.RequestAnimationFrame:
- console.assert(isNaN(endTime));
</del><ins>+ var eventMarker = new WebInspector.TimelineMarker(startTime, WebInspector.TimelineMarker.Type.LoadEvent);
+ this._activeRecording.addEventMarker(eventMarker);
</ins><span class="cx">
</span><del>- // Pass the startTime as the endTime since this record type has no duration.
- this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.AnimationFrameRequested, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.timerId));
</del><ins>+ this._stopAutoRecordingSoon();
+ break;
+
+ case TimelineAgent.EventType.MarkDOMContent:
+ console.assert(isNaN(endTime));
+
+ var frame = WebInspector.frameResourceManager.frameForIdentifier(recordPayload.frameId);
+ console.assert(frame);
+ if (!frame)
</ins><span class="cx"> break;
</span><span class="cx">
</span><del>- case TimelineAgent.EventType.CancelAnimationFrame:
- console.assert(isNaN(endTime));
</del><ins>+ frame.markDOMContentReadyEvent(startTime);
</ins><span class="cx">
</span><del>- // Pass the startTime as the endTime since this record type has no duration.
- this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.AnimationFrameCanceled, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.timerId));
</del><ins>+ if (!frame.isMainFrame())
</ins><span class="cx"> break;
</span><del>- }
- }
</del><span class="cx">
</span><del>- // 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: [originalRecordPayload], parent: null, index: 0}];
- while (stack.length) {
- var entry = stack.lastValue;
- var recordPayloads = entry.array;
- var parentRecordPayload = entry.parent;
</del><ins>+ var eventMarker = new WebInspector.TimelineMarker(startTime, WebInspector.TimelineMarker.Type.DOMContentEvent);
+ this._activeRecording.addEventMarker(eventMarker);
+ break;
</ins><span class="cx">
</span><del>- if (entry.index < recordPayloads.length) {
- var recordPayload = recordPayloads[entry.index];
</del><ins>+ case TimelineAgent.EventType.TimeStamp:
+ var eventMarker = new WebInspector.TimelineMarker(startTime, WebInspector.TimelineMarker.Type.TimeStamp);
+ this._activeRecording.addEventMarker(eventMarker);
+ break;
</ins><span class="cx">
</span><del>- processRecord.call(this, recordPayload, parentRecordPayload);
-
- if (recordPayload.children)
- stack.push({array: recordPayload.children, parent: recordPayload, index: 0});
- ++entry.index;
- } else
- stack.pop();
</del><ins>+ default:
+ return this._processRecord(recordPayload, parentRecordPayload);
</ins><span class="cx"> }
</span><del>- },
</del><span class="cx">
</span><del>- pageDidLoad: function(timestamp)
- {
- if (isNaN(WebInspector.frameResourceManager.mainFrame.loadEventTimestamp))
- WebInspector.frameResourceManager.mainFrame.markLoadEvent(this.activeRecording.computeElapsedTime(timestamp));
</del><ins>+ return null;
</ins><span class="cx"> },
</span><span class="cx">
</span><del>- // Private
-
</del><span class="cx"> _loadNewRecording: function()
</span><span class="cx"> {
</span><span class="cx"> if (this._activeRecording && this._activeRecording.isEmpty())
</span><span class="lines">@@ -411,9 +431,10 @@
</span><span class="cx">
</span><span class="cx"> var identifier = this._nextRecordingIdentifier++;
</span><span class="cx"> var newRecording = new WebInspector.TimelineRecording(identifier, WebInspector.UIString("Timeline Recording %d").format(identifier));
</span><del>- newRecording.addTimeline(new WebInspector.Timeline(WebInspector.TimelineRecord.Type.Network));
- newRecording.addTimeline(new WebInspector.Timeline(WebInspector.TimelineRecord.Type.Layout));
- newRecording.addTimeline(new WebInspector.Timeline(WebInspector.TimelineRecord.Type.Script));
</del><ins>+ newRecording.addTimeline(new WebInspector.Timeline(WebInspector.TimelineRecord.Type.Network, newRecording));
+ newRecording.addTimeline(new WebInspector.Timeline(WebInspector.TimelineRecord.Type.RunLoop, newRecording));
+ newRecording.addTimeline(new WebInspector.Timeline(WebInspector.TimelineRecord.Type.Layout, newRecording));
+ newRecording.addTimeline(new WebInspector.Timeline(WebInspector.TimelineRecord.Type.Script, newRecording));
</ins><span class="cx">
</span><span class="cx"> this._recordings.push(newRecording);
</span><span class="cx"> this.dispatchEventToListeners(WebInspector.TimelineManager.Event.RecordingCreated, {recording: newRecording});
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceImagesFramespng"></a>
<div class="binary"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Images/Frames.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Property changes on: trunk/Source/WebInspectorUI/UserInterface/Images/Frames.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<a id="trunkSourceWebInspectorUIUserInterfaceImagesFrames2xpng"></a>
<div class="binary"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Images/Frames@2x.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Property changes on: trunk/Source/WebInspectorUI/UserInterface/Images/Frames@2x.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<a id="trunkSourceWebInspectorUIUserInterfaceImagesFramesLargepng"></a>
<div class="binary"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Images/FramesLarge.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Property changes on: trunk/Source/WebInspectorUI/UserInterface/Images/FramesLarge.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<a id="trunkSourceWebInspectorUIUserInterfaceImagesFramesLarge2xpng"></a>
<div class="binary"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Images/FramesLarge@2x.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Property changes on: trunk/Source/WebInspectorUI/UserInterface/Images/FramesLarge@2x.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<a id="trunkSourceWebInspectorUIUserInterfaceMainhtml"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (181625 => 181626)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Main.html        2015-03-17 08:41:19 UTC (rev 181625)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html        2015-03-17 08:43:30 UTC (rev 181626)
</span><span class="lines">@@ -114,6 +114,7 @@
</span><span class="cx"> <link rel="stylesheet" href="Views/ResourceSidebarPanel.css">
</span><span class="cx"> <link rel="stylesheet" href="Views/ResourceTreeElement.css">
</span><span class="cx"> <link rel="stylesheet" href="Views/RulesStyleDetailsPanel.css">
</span><ins>+ <link rel="stylesheet" href="Views/RunLoopTimelineOverviewGraph.css">
</ins><span class="cx"> <link rel="stylesheet" href="Views/ScopeBar.css">
</span><span class="cx"> <link rel="stylesheet" href="Views/ScriptContentView.css">
</span><span class="cx"> <link rel="stylesheet" href="Views/ScriptTimelineOverviewGraph.css">
</span><span class="lines">@@ -134,6 +135,7 @@
</span><span class="cx"> <link rel="stylesheet" href="Views/TimelineIcons.css">
</span><span class="cx"> <link rel="stylesheet" href="Views/TimelineOverview.css">
</span><span class="cx"> <link rel="stylesheet" href="Views/TimelineRecordBar.css">
</span><ins>+ <link rel="stylesheet" href="Views/TimelineRecordFrame.css">
</ins><span class="cx"> <link rel="stylesheet" href="Views/TimelineRecordingContentView.css">
</span><span class="cx"> <link rel="stylesheet" href="Views/TimelineRuler.css">
</span><span class="cx"> <link rel="stylesheet" href="Views/TimelineSidebarPanel.css">
</span><span class="lines">@@ -272,6 +274,7 @@
</span><span class="cx"> <script src="Models/ResourceCollection.js"></script>
</span><span class="cx"> <script src="Models/ResourceTimelineRecord.js"></script>
</span><span class="cx"> <script src="Models/Revision.js"></script>
</span><ins>+ <script src="Models/RunLoopTimelineRecord.js"></script>
</ins><span class="cx"> <script src="Models/ScopeChainNode.js"></script>
</span><span class="cx"> <script src="Models/Script.js"></script>
</span><span class="cx"> <script src="Models/ScriptSyntaxTree.js"></script>
</span><span class="lines">@@ -448,6 +451,7 @@
</span><span class="cx"> <script src="Views/ResourceTimelineDataGridNode.js"></script>
</span><span class="cx"> <script src="Views/ResourceTimelineDataGridNodePathComponent.js"></script>
</span><span class="cx"> <script src="Views/RulesStyleDetailsPanel.js"></script>
</span><ins>+ <script src="Views/RunLoopTimelineOverviewGraph.js"></script>
</ins><span class="cx"> <script src="Views/ScopeBar.js"></script>
</span><span class="cx"> <script src="Views/ScopeBarItem.js"></script>
</span><span class="cx"> <script src="Views/ScopeChainDetailsSidebarPanel.js"></script>
</span><span class="lines">@@ -471,6 +475,7 @@
</span><span class="cx"> <script src="Views/TextResourceContentView.js"></script>
</span><span class="cx"> <script src="Views/TimelineOverview.js"></script>
</span><span class="cx"> <script src="Views/TimelineRecordBar.js"></script>
</span><ins>+ <script src="Views/TimelineRecordFrame.js"></script>
</ins><span class="cx"> <script src="Views/TimelineRecordingContentView.js"></script>
</span><span class="cx"> <script src="Views/TimelineRuler.js"></script>
</span><span class="cx"> <script src="Views/TimelineSidebarPanel.js"></script>
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsRunLoopTimelineRecordjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Models/RunLoopTimelineRecord.js (0 => 181626)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/RunLoopTimelineRecord.js         (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/RunLoopTimelineRecord.js        2015-03-17 08:43:30 UTC (rev 181626)
</span><span class="lines">@@ -0,0 +1,78 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.RunLoopTimelineRecord = function(startTime, endTime, children)
+{
+ WebInspector.TimelineRecord.call(this, WebInspector.TimelineRecord.Type.RunLoop, startTime, endTime);
+
+ this._children = children || [];
+ this._durationByRecordType = new Map;
+ this._durationRemainder = NaN;
+};
+
+WebInspector.RunLoopTimelineRecord.TypeIdentifier = "runloop-timeline-record";
+
+WebInspector.RunLoopTimelineRecord.prototype = {
+ constructor: WebInspector.RunLoopTimelineRecord,
+ __proto__: WebInspector.TimelineRecord.prototype,
+
+ // Public
+
+ get children()
+ {
+ return this._children.slice();
+ },
+
+ get durationRemainder()
+ {
+ if (!isNaN(this._durationRemainder))
+ return this._durationRemainder;
+
+ this._durationRemainder = this.duration;
+ for (recordType in WebInspector.TimelineRecord.Type)
+ this._durationRemainder -= this.durationForRecords(WebInspector.TimelineRecord.Type[recordType]);
+
+ return this._durationRemainder;
+ },
+
+ durationForRecords(recordType)
+ {
+ if (this._durationByRecordType.has(recordType))
+ return this._durationByRecordType.get(recordType);
+
+ var duration = this._children.reduce(function(previousValue, currentValue) {
+ if (currentValue.type === recordType) {
+ var currentDuration = currentValue.duration;
+ if (currentValue.usesActiveStartTime)
+ currentDuration -= currentValue.inactiveDuration;
+ return previousValue + currentDuration;
+ }
+ return previousValue;
+ }, 0);
+
+ this._durationByRecordType.set(recordType, duration);
+ return duration;
+ }
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsTimelinejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Models/Timeline.js (181625 => 181626)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/Timeline.js        2015-03-17 08:41:19 UTC (rev 181625)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Timeline.js        2015-03-17 08:43:30 UTC (rev 181626)
</span><span class="lines">@@ -80,6 +80,8 @@
</span><span class="cx"> return WebInspector.UIString("Layout & Rendering");
</span><span class="cx"> if (this._type === WebInspector.TimelineRecord.Type.Script)
</span><span class="cx"> return WebInspector.UIString("JavaScript & Events");
</span><ins>+ if (this._type === WebInspector.TimelineRecord.Type.RunLoop)
+ return WebInspector.UIString("Frames");
</ins><span class="cx">
</span><span class="cx"> console.error("Timeline has unknown type:", this._type, this);
</span><span class="cx"> },
</span><span class="lines">@@ -90,6 +92,8 @@
</span><span class="cx"> return WebInspector.TimelineSidebarPanel.NetworkIconStyleClass;
</span><span class="cx"> if (this._type === WebInspector.TimelineRecord.Type.Layout)
</span><span class="cx"> return WebInspector.TimelineSidebarPanel.ColorsIconStyleClass;
</span><ins>+ if (this._type === WebInspector.TimelineRecord.Type.RunLoop)
+ return WebInspector.TimelineSidebarPanel.RunLoopIconStyleClass;
</ins><span class="cx"> if (this._type === WebInspector.TimelineRecord.Type.Script)
</span><span class="cx"> return WebInspector.TimelineSidebarPanel.ScriptIconStyleClass;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsTimelineRecordjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecord.js (181625 => 181626)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecord.js        2015-03-17 08:41:19 UTC (rev 181625)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecord.js        2015-03-17 08:43:30 UTC (rev 181626)
</span><span class="lines">@@ -46,7 +46,8 @@
</span><span class="cx"> WebInspector.TimelineRecord.Type = {
</span><span class="cx"> Network: "timeline-record-type-network",
</span><span class="cx"> Layout: "timeline-record-type-layout",
</span><del>- Script: "timeline-record-type-script"
</del><ins>+ Script: "timeline-record-type-script",
+ RunLoop: "timeline-record-type-runloop"
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> WebInspector.TimelineRecord.TypeIdentifier = "timeline-record";
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsContentViewjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ContentView.js (181625 => 181626)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/ContentView.js        2015-03-17 08:41:19 UTC (rev 181625)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ContentView.js        2015-03-17 08:43:30 UTC (rev 181626)
</span><span class="lines">@@ -47,7 +47,7 @@
</span><span class="cx"> if (timelineType === WebInspector.TimelineRecord.Type.Network)
</span><span class="cx"> return new WebInspector.NetworkTimelineView(representedObject);
</span><span class="cx">
</span><del>- if (timelineType === WebInspector.TimelineRecord.Type.Layout)
</del><ins>+ if (timelineType === WebInspector.TimelineRecord.Type.Layout || timelineType === WebInspector.TimelineRecord.Type.RunLoop)
</ins><span class="cx"> return new WebInspector.LayoutTimelineView(representedObject);
</span><span class="cx">
</span><span class="cx"> if (timelineType === WebInspector.TimelineRecord.Type.Script)
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsLayoutTimelineViewjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/LayoutTimelineView.js (181625 => 181626)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/LayoutTimelineView.js        2015-03-17 08:41:19 UTC (rev 181625)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/LayoutTimelineView.js        2015-03-17 08:43:30 UTC (rev 181626)
</span><span class="lines">@@ -27,7 +27,7 @@
</span><span class="cx"> {
</span><span class="cx"> WebInspector.TimelineView.call(this, timeline);
</span><span class="cx">
</span><del>- console.assert(timeline.type === WebInspector.TimelineRecord.Type.Layout);
</del><ins>+ console.assert(timeline.type === WebInspector.TimelineRecord.Type.Layout || WebInspector.TimelineRecord.Type.RunLoop);
</ins><span class="cx">
</span><span class="cx"> this.navigationSidebarTreeOutline.onselect = this._treeElementSelected.bind(this);
</span><span class="cx"> this.navigationSidebarTreeOutline.ondeselect = this._treeElementDeselected.bind(this);
</span><span class="lines">@@ -185,7 +185,7 @@
</span><span class="cx"> _layoutTimelineRecordAdded: function(event)
</span><span class="cx"> {
</span><span class="cx"> var layoutTimelineRecord = event.data.record;
</span><del>- console.assert(layoutTimelineRecord instanceof WebInspector.LayoutTimelineRecord);
</del><ins>+ console.assert(layoutTimelineRecord instanceof WebInspector.LayoutTimelineRecord || layoutTimelineRecord instanceof WebInspector.RunLoopTimelineRecord);
</ins><span class="cx">
</span><span class="cx"> this._pendingRecords.push(layoutTimelineRecord);
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsRunLoopTimelineOverviewGraphcss"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Views/RunLoopTimelineOverviewGraph.css (0 => 181626)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/RunLoopTimelineOverviewGraph.css         (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/RunLoopTimelineOverviewGraph.css        2015-03-17 08:43:30 UTC (rev 181626)
</span><span class="lines">@@ -0,0 +1,44 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+.timeline-overview-graph.runloop > .divider {
+ position: absolute;
+ z-index: 10;
+
+ width: 100%;
+ height: 1px;
+
+ background-color: rgba(0, 0, 0, 0.05);
+ text-align: right;
+}
+
+.timeline-overview-graph.runloop > .divider > span {
+ padding-right: 1px;
+
+ font-family: Helvetica, sans-serif;
+ font-size: 8px;
+
+ color: rgba(0, 0, 0, 0.2);
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsRunLoopTimelineOverviewGraphjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Views/RunLoopTimelineOverviewGraph.js (0 => 181626)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/RunLoopTimelineOverviewGraph.js         (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/RunLoopTimelineOverviewGraph.js        2015-03-17 08:43:30 UTC (rev 181626)
</span><span class="lines">@@ -0,0 +1,160 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.RunLoopTimelineOverviewGraph = function(timeline)
+{
+ WebInspector.TimelineOverviewGraph.call(this, timeline);
+
+ this.element.classList.add(WebInspector.RunLoopTimelineOverviewGraph.StyleClassName);
+
+ this._runLoopTimeline = timeline;
+ this._timelineRecordFrames = [];
+ this._graphHeightSeconds = NaN;
+ this._framesPerSecondDividers = new Map;
+
+ this._runLoopTimeline.addEventListener(WebInspector.Timeline.Event.RecordAdded, this._timelineRecordAdded, this);
+
+ this.reset();
+};
+
+WebInspector.RunLoopTimelineOverviewGraph.StyleClassName = "runloop";
+WebInspector.RunLoopTimelineOverviewGraph.MaximumGraphHeightSeconds = 0.05;
+
+WebInspector.RunLoopTimelineOverviewGraph.prototype = {
+ constructor: WebInspector.RunLoopTimelineOverviewGraph,
+ __proto__: WebInspector.TimelineOverviewGraph.prototype,
+
+ // Public
+
+ get graphHeightSeconds()
+ {
+ if (!isNaN(this._graphHeightSeconds))
+ return this._graphHeightSeconds;
+
+ var maximumFrameDuration = this._runLoopTimeline.records.reduce(function(previousValue, currentValue) {
+ return Math.max(previousValue, currentValue.duration);
+ }, 0);
+
+ this._graphHeightSeconds = maximumFrameDuration * 1.1; // Add 10% margin above frames.
+ this._graphHeightSeconds = Math.min(this._graphHeightSeconds, WebInspector.RunLoopTimelineOverviewGraph.MaximumGraphHeightSeconds);
+ return this._graphHeightSeconds;
+ },
+
+ reset()
+ {
+ WebInspector.TimelineOverviewGraph.prototype.reset.call(this);
+
+ this.element.removeChildren();
+
+ this._framesPerSecondDividers.clear();
+ },
+
+ updateLayout()
+ {
+ WebInspector.TimelineOverviewGraph.prototype.updateLayout.call(this);
+
+ var secondsPerPixel = this.timelineOverview.secondsPerPixel;
+
+ var recordFrameIndex = 0;
+
+ function createFrame(records)
+ {
+ var timelineRecordFrame = this._timelineRecordFrames[recordFrameIndex];
+ if (!timelineRecordFrame)
+ timelineRecordFrame = this._timelineRecordFrames[recordFrameIndex] = new WebInspector.TimelineRecordFrame(this, records);
+ else
+ timelineRecordFrame.records = records;
+
+ timelineRecordFrame.refresh(this);
+ if (!timelineRecordFrame.element.parentNode)
+ this.element.appendChild(timelineRecordFrame.element);
+ ++recordFrameIndex;
+ }
+
+ WebInspector.TimelineRecordFrame.createCombinedFrames(this._runLoopTimeline.records, secondsPerPixel, this, createFrame.bind(this));
+
+ // Remove the remaining unused TimelineRecordFrames.
+ for (; recordFrameIndex < this._timelineRecordFrames.length; ++recordFrameIndex) {
+ this._timelineRecordFrames[recordFrameIndex].records = null;
+ this._timelineRecordFrames[recordFrameIndex].element.remove();
+ }
+
+ this._updateDividers();
+ },
+
+ // Private
+
+ _timelineRecordAdded(event)
+ {
+ this._graphHeightSeconds = NaN;
+
+ this.needsLayout();
+ },
+
+ _updateDividers()
+ {
+ if (this.graphHeightSeconds === 0)
+ return;
+
+ var overviewGraphHeight = this.element.offsetHeight;
+
+ function createDividerAtPosition(framesPerSecond)
+ {
+ var secondsPerFrame = 1 / framesPerSecond;
+ var dividerTop = 1 - secondsPerFrame / this.graphHeightSeconds;
+ if (dividerTop < 0.01 || dividerTop >= 1)
+ return;
+
+ var divider = this._framesPerSecondDividers.get(framesPerSecond);
+ if (!divider) {
+ divider = document.createElement("div");
+ divider.classList.add("divider");
+
+ var label = document.createElement("span");
+ label.innerText = framesPerSecond + " fps";
+ divider.appendChild(label);
+
+ this.element.appendChild(divider);
+
+ this._framesPerSecondDividers.set(framesPerSecond, divider);
+ }
+
+ divider.style.marginTop = (dividerTop * overviewGraphHeight).toFixed(2) + "px";
+ }
+
+ createDividerAtPosition.call(this, 60);
+ createDividerAtPosition.call(this, 30);
+ },
+
+ _updateElementPosition(element, newPosition, property)
+ {
+ newPosition *= 100;
+ newPosition = newPosition.toFixed(2);
+
+ var currentPosition = parseFloat(element.style[property]).toFixed(2);
+ if (currentPosition !== newPosition)
+ element.style[property] = newPosition + "%";
+ }
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsTimelineIconscss"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TimelineIcons.css (181625 => 181626)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/TimelineIcons.css        2015-03-17 08:41:19 UTC (rev 181625)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TimelineIcons.css        2015-03-17 08:43:30 UTC (rev 181626)
</span><span class="lines">@@ -63,6 +63,14 @@
</span><span class="cx"> content: -webkit-image-set(url(../Images/ScriptLarge.png) 1x, url(../Images/ScriptLarge@2x.png) 2x);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+.runloop-icon .icon {
+ content: -webkit-image-set(url(../Images/Frames.png) 1x, url(../Images/Frames@2x.png) 2x);
+}
+
+.runloop-icon.large .icon {
+ content: -webkit-image-set(url(../Images/FramesLarge.png) 1x, url(../Images/FramesLarge@2x.png) 2x);
+}
+
</ins><span class="cx"> .stopwatch-icon .icon {
</span><span class="cx"> content: -webkit-image-set(url(../Images/Stopwatch.png) 1x, url(../Images/Stopwatch@2x.png) 2x);
</span><span class="cx"> }
</span><span class="lines">@@ -83,6 +91,10 @@
</span><span class="cx"> content: url(../Images/TimelineRecordPaint.svg);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+.runloop-record .icon {
+ content: -webkit-image-set(url(../Images/Frames.png) 1x, url(../Images/Frames@2x.png) 2x);
+}
+
</ins><span class="cx"> .evaluated-record .icon {
</span><span class="cx"> content: url(../Images/TimelineRecordScriptEvaluated.svg);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsTimelineOverviewGraphjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TimelineOverviewGraph.js (181625 => 181626)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/TimelineOverviewGraph.js        2015-03-17 08:41:19 UTC (rev 181625)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TimelineOverviewGraph.js        2015-03-17 08:43:30 UTC (rev 181626)
</span><span class="lines">@@ -40,6 +40,9 @@
</span><span class="cx"> if (timelineType === WebInspector.TimelineRecord.Type.Script)
</span><span class="cx"> return new WebInspector.ScriptTimelineOverviewGraph(timeline);
</span><span class="cx">
</span><ins>+ if (timelineType === WebInspector.TimelineRecord.Type.RunLoop)
+ return new WebInspector.RunLoopTimelineOverviewGraph(timeline);
+
</ins><span class="cx"> throw Error("Can't make a graph for an unknown timeline.");
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsTimelineRecordFramecss"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordFrame.css (0 => 181626)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordFrame.css         (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordFrame.css        2015-03-17 08:43:30 UTC (rev 181626)
</span><span class="lines">@@ -0,0 +1,92 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+.timeline-record-frame {
+ position: absolute;
+ height: 36px;
+ min-width: 6px;
+
+ overflow: hidden;
+
+ -webkit-mask-image: -webkit-linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 1) 10%);
+}
+
+.timeline-record-frame > .frame {
+ position: absolute;
+ z-index: 1;
+ bottom: 1px;
+ min-width: 6px;
+
+ box-sizing: border-box;
+}
+
+.timeline-record-frame > .dropped {
+ position: absolute;
+ bottom: 1px;
+ right: 0;
+
+ min-width: 6px;
+ box-sizing: border-box;
+
+ background: repeating-linear-gradient(-45deg, white, white 2px, rgb(234, 234, 234) 2px, rgb(234, 234, 234) 4px);
+
+ border-top-style: solid;
+ border-right-style: solid;
+ border-width: 1px;
+ border-color: rgb(221, 221, 221);
+}
+
+.timeline-record-frame > .frame > .duration {
+ box-sizing: border-box;
+
+ background-color: rgb(221, 221, 221);
+
+ border-color: rgb(176, 176, 176);
+ border-style: none solid solid solid;
+ border-width: 1px;
+}
+
+.timeline-record-frame > .frame > .duration:first-child {
+ border-top-style: solid;
+}
+
+.timeline-record-frame > .frame > .duration:last-child {
+ border-bottom-style: none;
+}
+
+.timeline-record-frame > .frame > .duration.timeline-record-type-network {
+ background-color: rgb(120, 176, 225);
+ border-color: rgb(61, 147, 200);
+}
+
+.timeline-record-frame > .frame > .duration.timeline-record-type-layout {
+ background-color: rgb(234, 153, 153);
+ border-color: rgb(212, 108, 108);
+}
+
+.timeline-record-frame > .frame > .duration.timeline-record-type-script {
+ background-color: rgb(190, 148, 233);
+ border-color: rgb(153, 113, 185);
+}
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsTimelineRecordFramejs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordFrame.js (0 => 181626)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordFrame.js         (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordFrame.js        2015-03-17 08:43:30 UTC (rev 181626)
</span><span class="lines">@@ -0,0 +1,261 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.TimelineRecordFrame = function(graphDataSource, records)
+{
+ WebInspector.Object.call(this);
+
+ this._element = document.createElement("div");
+ this._element.classList.add(WebInspector.TimelineRecordFrame.StyleClassName);
+
+ this._graphDataSource = graphDataSource;
+ this.records = records || [];
+};
+
+WebInspector.Object.addConstructorFunctions(WebInspector.TimelineRecordFrame);
+
+WebInspector.TimelineRecordFrame.StyleClassName = "timeline-record-frame";
+WebInspector.TimelineRecordFrame.SixtyFpsFrameBudget = 0.0166;
+WebInspector.TimelineRecordFrame.MinimumWidthPixels = 6;
+WebInspector.TimelineRecordFrame.MinimumMarginPixels = 1;
+
+WebInspector.TimelineRecordFrame.createCombinedFrames = function(records, secondsPerPixel, graphDataSource, createFrameCallback)
+{
+ if (!records.length)
+ return;
+
+ var startTime = graphDataSource.startTime;
+ var currentTime = graphDataSource.currentTime;
+ var endTime = graphDataSource.endTime;
+
+ var visibleRecords = [];
+
+ for (var record of records) {
+ if (isNaN(record.startTime))
+ continue;
+
+ // If this frame is completely before the bounds of the graph, skip this record.
+ if (record.endTime < startTime)
+ continue;
+
+ // If this record is completely after the current time or end time, break out now.
+ // Records are sorted, so all records after this will be beyond the current or end time too.
+ if (record.startTime > currentTime || record.startTime > endTime)
+ break;
+
+ visibleRecords.push(record);
+ }
+
+ if (!visibleRecords.length)
+ return;
+
+ var minimumFrameDuration = secondsPerPixel * WebInspector.TimelineRecordFrame.MinimumWidthPixels;
+ var minimumMargin = secondsPerPixel * WebInspector.TimelineRecordFrame.MinimumMarginPixels;
+
+ var activeStartTime = NaN;
+ var activeEndTime = NaN;
+ var activeRecords = [];
+
+ for (var record of visibleRecords) {
+ // Check if the previous record is far enough away to create the frame.
+ if (!isNaN(activeStartTime) && (activeStartTime + Math.max(activeEndTime - activeStartTime, minimumFrameDuration) + minimumMargin <= record.startTime)) {
+ createFrameCallback(activeRecords);
+ activeRecords = [];
+ activeStartTime = NaN;
+ activeEndTime = NaN;
+ }
+
+ // If this is a new frame, peg the start time.
+ if (isNaN(activeStartTime))
+ activeStartTime = record.startTime;
+
+ // Update the end time to be the maximum we encounter. endTime might be NaN, so "|| 0" to prevent Math.max from returning NaN.
+ if (!isNaN(record.endTime))
+ activeEndTime = Math.max(activeEndTime || 0, record.endTime);
+
+ activeRecords.push(record);
+ }
+
+ // Create the active frame for the last record if needed.
+ if (!isNaN(activeStartTime))
+ createFrameCallback(activeRecords);
+};
+
+WebInspector.TimelineRecordFrame.prototype = {
+ constructor: WebInspector.TimelineRecordFrame,
+ __proto__: WebInspector.Object.prototype,
+
+ // Public
+
+ get element()
+ {
+ return this._element;
+ },
+
+ get duration()
+ {
+ if (this.records.length === 0)
+ return 0;
+
+ return this.records.lastValue.endTime - this.records[0].startTime;
+ },
+
+ get records()
+ {
+ return this._records;
+ },
+
+ set records(records)
+ {
+ records = records || [];
+
+ if (!(records instanceof Array))
+ records = [records];
+
+ this._records = records;
+ },
+
+ refresh(graphDataSource)
+ {
+ if (!this.records || !this.records.length)
+ return false;
+
+ var firstRecord = this.records[0];
+ var frameStartTime = firstRecord.startTime;
+
+ // If this frame has no time info, return early.
+ if (isNaN(frameStartTime))
+ return false;
+
+ var graphStartTime = graphDataSource.startTime;
+ var graphEndTime = graphDataSource.endTime;
+ var graphCurrentTime = graphDataSource.currentTime;
+
+ // If this frame is completely after the current time, return early.
+ if (frameStartTime > graphCurrentTime)
+ return false;
+
+ var frameEndTime = this.records.lastValue.endTime;
+
+ // If this frame is completely before or after the bounds of the graph, return early.
+ if (frameEndTime < graphStartTime || frameStartTime > graphEndTime)
+ return false;
+
+ var graphDuration = graphEndTime - graphStartTime;
+ var recordLeftPosition = (frameStartTime - graphStartTime) / graphDuration;
+ this._updateElementPosition(this._element, recordLeftPosition, "left");
+
+ var recordWidth = ((frameEndTime - graphStartTime) / graphDuration) - recordLeftPosition;
+ this._updateElementPosition(this._element, recordWidth, "width");
+
+ this._updateChildElements(graphDataSource);
+
+ return true;
+ },
+
+ // Private
+
+ _updateChildElements(graphDataSource)
+ {
+ this._element.removeChildren();
+
+ console.assert(this.records.length);
+ if (!this.records.length)
+ return;
+
+ if (graphDataSource.graphHeightSeconds === 0)
+ return;
+
+ // When combining multiple records into a frame, display the record with the longest duration rather than averaging.
+ var displayRecord = this.records.reduce(function(previousValue, currentValue) {
+ return currentValue.duration >= previousValue.duration ? currentValue : previousValue;
+ });
+
+ var frameElement = document.createElement("div");
+ frameElement.classList.add("frame");
+ this._element.appendChild(frameElement);
+
+ var frameHeight = displayRecord.duration / graphDataSource.graphHeightSeconds;
+ this._updateElementPosition(frameElement, frameHeight, "height");
+
+ function createDurationElement(duration, recordType)
+ {
+ var element = document.createElement("div");
+ this._updateElementPosition(element, duration / displayRecord.duration, "height");
+ element.classList.add("duration");
+ if (recordType)
+ element.classList.add(recordType);
+ return element;
+ }
+
+ for (type in WebInspector.TimelineRecord.Type) {
+ var recordType = WebInspector.TimelineRecord.Type[type];
+ var duration = displayRecord.durationForRecords(recordType);
+ if (duration === 0)
+ continue;
+ frameElement.appendChild(createDurationElement.call(this, duration, recordType));
+ }
+
+ if (displayRecord.durationRemainder > 0)
+ frameElement.appendChild(createDurationElement.call(this, displayRecord.durationRemainder));
+
+ // Add "includes-dropped" style class if multiple records are being combined in the frame,
+ // and one of those records exceeds the 60 fps frame budget.
+ if (this.records.length > 1 && displayRecord.duration > WebInspector.TimelineRecordFrame.SixtyFpsFrameBudget)
+ frameElement.classList.add("includes-dropped");
+
+ // If the display record is the last combined record and also exceeds the 60 fps budget,
+ // add a "dropped" element to the right of the frame.
+ var frameWidth = 1;
+ var secondsPerPixel = this._graphDataSource.timelineOverview.secondsPerPixel;
+ var minimumRecordDuration = secondsPerPixel * WebInspector.TimelineRecordFrame.MinimumWidthPixels * 2; // Combine minimum widths of the frame element and dropped element.
+
+ if (displayRecord === this.records.lastValue && displayRecord.duration > WebInspector.TimelineRecordFrame.SixtyFpsFrameBudget && displayRecord.duration >= minimumRecordDuration) {
+ var overflowDuration = displayRecord.duration - WebInspector.TimelineRecordFrame.SixtyFpsFrameBudget;
+ var droppedElementWidth = overflowDuration / displayRecord.duration;
+ frameWidth -= droppedElementWidth;
+
+ var droppedElement = document.createElement("div");
+ droppedElement.className = "dropped";
+
+ this._element.appendChild(droppedElement);
+
+ this._updateElementPosition(droppedElement, frameHeight, "height");
+ this._updateElementPosition(droppedElement, droppedElementWidth, "width");
+ }
+
+ this._updateElementPosition(frameElement, frameWidth, "width");
+ },
+
+ _updateElementPosition(element, newPosition, property)
+ {
+ newPosition *= 100;
+ newPosition = newPosition.toFixed(2);
+
+ var currentPosition = parseFloat(element.style[property]).toFixed(2);
+ if (currentPosition !== newPosition)
+ element.style[property] = newPosition + "%";
+ }
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsTimelineRecordTreeElementjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordTreeElement.js (181625 => 181626)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordTreeElement.js        2015-03-17 08:41:19 UTC (rev 181625)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordTreeElement.js        2015-03-17 08:43:30 UTC (rev 181626)
</span><span class="lines">@@ -99,6 +99,11 @@
</span><span class="cx">
</span><span class="cx"> break;
</span><span class="cx">
</span><ins>+ case WebInspector.TimelineRecord.Type.RunLoop:
+ title = WebInspector.UIString("Runloop Executed");
+ iconStyleClass = WebInspector.TimelineRecordTreeElement.RunLoopRecordIconStyleClass;
+ break;
+
</ins><span class="cx"> default:
</span><span class="cx"> console.error("Unknown TimelineRecord type: " + timelineRecord.type, timelineRecord);
</span><span class="cx"> }
</span><span class="lines">@@ -114,6 +119,7 @@
</span><span class="cx"> WebInspector.TimelineRecordTreeElement.StyleRecordIconStyleClass = "style-record";
</span><span class="cx"> WebInspector.TimelineRecordTreeElement.LayoutRecordIconStyleClass = "layout-record";
</span><span class="cx"> WebInspector.TimelineRecordTreeElement.PaintRecordIconStyleClass = "paint-record";
</span><ins>+WebInspector.TimelineRecordTreeElement.RunLoopRecordIconStyleClass = "runloop-record";
</ins><span class="cx"> WebInspector.TimelineRecordTreeElement.EvaluatedRecordIconStyleClass = "evaluated-record";
</span><span class="cx"> WebInspector.TimelineRecordTreeElement.EventRecordIconStyleClass = "event-record";
</span><span class="cx"> WebInspector.TimelineRecordTreeElement.TimerRecordIconStyleClass = "timer-record";
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsTimelineSidebarPaneljs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TimelineSidebarPanel.js (181625 => 181626)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/TimelineSidebarPanel.js        2015-03-17 08:41:19 UTC (rev 181625)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TimelineSidebarPanel.js        2015-03-17 08:43:30 UTC (rev 181626)
</span><span class="lines">@@ -139,6 +139,7 @@
</span><span class="cx"> WebInspector.TimelineSidebarPanel.NetworkIconStyleClass = "network-icon";
</span><span class="cx"> WebInspector.TimelineSidebarPanel.ColorsIconStyleClass = "colors-icon";
</span><span class="cx"> WebInspector.TimelineSidebarPanel.ScriptIconStyleClass = "script-icon";
</span><ins>+WebInspector.TimelineSidebarPanel.RunLoopIconStyleClass = "runloop-icon";
</ins><span class="cx"> WebInspector.TimelineSidebarPanel.TimelineRecordingContentViewShowingStyleClass = "timeline-recording-content-view-showing";
</span><span class="cx">
</span><span class="cx"> WebInspector.TimelineSidebarPanel.ShowingTimelineRecordingContentViewCookieKey = "timeline-sidebar-panel-showing-timeline-recording-content-view";
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIWebInspectorUIvcxprojWebInspectorUIvcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/WebInspectorUI.vcxproj/WebInspectorUI.vcxproj (181625 => 181626)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/WebInspectorUI.vcxproj/WebInspectorUI.vcxproj        2015-03-17 08:41:19 UTC (rev 181625)
+++ trunk/Source/WebInspectorUI/WebInspectorUI.vcxproj/WebInspectorUI.vcxproj        2015-03-17 08:43:30 UTC (rev 181626)
</span><span class="lines">@@ -525,6 +525,10 @@
</span><span class="cx"> <None Include="..\UserInterface\Images\FolderGeneric.png" />
</span><span class="cx"> <None Include="..\UserInterface\Images\ForwardArrow.svg" />
</span><span class="cx"> <None Include="..\UserInterface\Images\ForwardArrowLegacy.svg" />
</span><ins>+ <None Include="..\UserInterface\Images\Frames.png" />
+ <None Include="..\UserInterface\Images\Frames%402x.png" />
+ <None Include="..\UserInterface\Images\FramesLarge.png" />
+ <None Include="..\UserInterface\Images\FramesLarge%402x.png" />
</ins><span class="cx"> <None Include="..\UserInterface\Images\Function.svg" />
</span><span class="cx"> <None Include="..\UserInterface\Images\GoToArrow.svg" />
</span><span class="cx"> <None Include="..\UserInterface\Images\HierarchicalNavigationItemChevron.svg" />
</span><span class="lines">@@ -747,6 +751,9 @@
</span><span class="cx"> <None Include="..\UserInterface\Revision.js" />
</span><span class="cx"> <None Include="..\UserInterface\RulesStyleDetailsPanel.css" />
</span><span class="cx"> <None Include="..\UserInterface\RulesStyleDetailsPanel.js" />
</span><ins>+ <None Include="..\UserInterface\RunLoopTimelineOverviewGraph.css" />
+ <None Include="..\UserInterface\RunLoopTimelineOverviewGraph.js" />
+ <None Include="..\UserInterface\RunLoopTimelineRecord.js" />
</ins><span class="cx"> <None Include="..\UserInterface\RuntimeObserver.js" />
</span><span class="cx"> <None Include="..\UserInterface\ScopeBar.css" />
</span><span class="cx"> <None Include="..\UserInterface\ScopeBar.js" />
</span><span class="lines">@@ -808,6 +815,8 @@
</span><span class="cx"> <None Include="..\UserInterface\TimelineOverview.css" />
</span><span class="cx"> <None Include="..\UserInterface\TimelineOverview.js" />
</span><span class="cx"> <None Include="..\UserInterface\TimelineRecord.js" />
</span><ins>+ <None Include="..\UserInterface\TimelineRecordFrame.css" />
+ <None Include="..\UserInterface\TimelineRecordFrame.js" />
</ins><span class="cx"> <None Include="..\UserInterface\TimelinesContentView.css" />
</span><span class="cx"> <None Include="..\UserInterface\TimelinesContentView.js" />
</span><span class="cx"> <None Include="..\UserInterface\TimelinesObject.js" />
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIWebInspectorUIvcxprojWebInspectorUIvcxprojfilters"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/WebInspectorUI.vcxproj/WebInspectorUI.vcxproj.filters (181625 => 181626)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/WebInspectorUI.vcxproj/WebInspectorUI.vcxproj.filters        2015-03-17 08:41:19 UTC (rev 181625)
+++ trunk/Source/WebInspectorUI/WebInspectorUI.vcxproj/WebInspectorUI.vcxproj.filters        2015-03-17 08:43:30 UTC (rev 181626)
</span><span class="lines">@@ -825,6 +825,15 @@
</span><span class="cx"> <None Include="..\UserInterface\RulesStyleDetailsPanel.js">
</span><span class="cx"> <Filter>UserInterface</Filter>
</span><span class="cx"> </None>
</span><ins>+ <None Include="..\UserInterface\RunLoopTimelineOverviewGraph.css">
+ <Filter>UserInterface</Filter>
+ </None>
+ <None Include="..\UserInterface\RunLoopTimelineOverviewGraph.js">
+ <Filter>UserInterface</Filter>
+ </None>
+ <None Include="..\UserInterface\RunLoopTimelineRecord.js">
+ <Filter>UserInterface</Filter>
+ </None>
</ins><span class="cx"> <None Include="..\UserInterface\RuntimeObserver.js">
</span><span class="cx"> <Filter>UserInterface</Filter>
</span><span class="cx"> </None>
</span><span class="lines">@@ -1008,6 +1017,12 @@
</span><span class="cx"> <None Include="..\UserInterface\TimelineRecord.js">
</span><span class="cx"> <Filter>UserInterface</Filter>
</span><span class="cx"> </None>
</span><ins>+ <None Include="..\UserInterface\TimelineRecordFrame.css">
+ <Filter>UserInterface</Filter>
+ </None>
+ <None Include="..\UserInterface\TimelineRecordFrame.js">
+ <Filter>UserInterface</Filter>
+ </None>
</ins><span class="cx"> <None Include="..\UserInterface\TimelinesContentView.css">
</span><span class="cx"> <Filter>UserInterface</Filter>
</span><span class="cx"> </None>
</span></span></pre>
</div>
</div>
</body>
</html>