<!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>[162419] 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/162419">162419</a></dd>
<dt>Author</dt> <dd>timothy@apple.com</dd>
<dt>Date</dt> <dd>2014-01-20 18:56:29 -0800 (Mon, 20 Jan 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Implement basic versions of the TimelineOverview graphs.

https://bugs.webkit.org/show_bug.cgi?id=127184

Reviewed by Joseph Pecoraro.

* UserInterface/LayoutTimelineOverviewGraph.css: Added.
(.timeline-overview-graph.layout &gt; .timeline-record-bar):
(.timeline-overview-graph.layout &gt; .timeline-record-bar &gt; .segment):

* UserInterface/LayoutTimelineOverviewGraph.js: Added.
(WebInspector.LayoutTimelineOverviewGraph.prototype.reset):
(WebInspector.LayoutTimelineOverviewGraph.prototype.updateLayout):
(WebInspector.LayoutTimelineOverviewGraph.prototype._layoutTimelineRecordAdded):

* UserInterface/Main.html: Added new files.

* UserInterface/NetworkTimelineOverviewGraph.css: Added.
(.timeline-overview-graph.network):
(.timeline-overview-graph.network &gt; .graph-row):
(.timeline-overview-graph.network &gt; .graph-row &gt; .bar):
(.timeline-overview-graph.network &gt; .graph-row &gt; .bar.inactive):
(.timeline-overview-graph.network &gt; .graph-row &gt; .bar.unfinished):
(.timeline-overview-graph.network &gt; .graph-row &gt; .bar:not(.inactive)):
(.timeline-overview-graph.network:nth-child(even) &gt; .graph-row &gt; .bar:not(.inactive)):

* UserInterface/NetworkTimelineOverviewGraph.js: Added.
(WebInspector.NetworkTimelineOverviewGraph.prototype.reset):
(WebInspector.NetworkTimelineOverviewGraph.prototype.updateLayout.updateElementPosition):
(WebInspector.NetworkTimelineOverviewGraph.prototype.updateLayout.createBar):
(WebInspector.NetworkTimelineOverviewGraph.prototype.updateLayout):
(WebInspector.NetworkTimelineOverviewGraph.prototype._networkTimelineRecordAdded.compareByStartTime):
(WebInspector.NetworkTimelineOverviewGraph.prototype._networkTimelineRecordAdded.insertObjectIntoSortedArray):
(WebInspector.NetworkTimelineOverviewGraph.prototype._networkTimelineRecordAdded):

* UserInterface/ScriptTimelineOverviewGraph.css: Added.
(.timeline-overview-graph.script &gt; .timeline-record-bar):
(.timeline-overview-graph.script &gt; .timeline-record-bar &gt; .segment):

* UserInterface/ScriptTimelineOverviewGraph.js: Added.
(WebInspector.ScriptTimelineOverviewGraph.prototype.reset):
(WebInspector.ScriptTimelineOverviewGraph.prototype.updateLayout):
(WebInspector.ScriptTimelineOverviewGraph.prototype._scriptTimelineRecordAdded):

* UserInterface/TimelineContentView.js:
(WebInspector.TimelineContentView.prototype._showTimelineView):
(WebInspector.TimelineContentView.prototype._update):
(WebInspector.TimelineContentView.prototype._recordingReset):
Create and keep the graphs informed.

* UserInterface/TimelineDataGridNode.js:
(WebInspector.TimelineDataGridNode):
(WebInspector.TimelineDataGridNode.prototype.refreshGraph):
Combine records that might overlap.

* UserInterface/TimelineOverview.css:
(.timeline-overview &gt; .graphs-container):
(.timeline-overview &gt; .graphs-container &gt; .timeline-overview-graph):
(.timeline-overview &gt; .graphs-container &gt; .timeline-overview-graph:nth-child(even)):
(.timeline-overview &gt; .graphs-container &gt; .timeline-overview-graph:not(:first-child)):
Add the graph rows with alternating stripe.

* UserInterface/TimelineOverview.js:
(WebInspector.TimelineOverview):
(WebInspector.TimelineOverview.prototype.set startTime):
(WebInspector.TimelineOverview.prototype.get currentTime):
(WebInspector.TimelineOverview.prototype.set currentTime):
(WebInspector.TimelineOverview.prototype.updateLayout):
(WebInspector.TimelineOverview.prototype.updateLayoutIfNeeded):
Track currentTime in a member variable and let TimelineOverview manage the current time marker.

* UserInterface/TimelineOverviewGraph.js: Added.
(WebInspector.TimelineOverviewGraph):
(WebInspector.TimelineOverviewGraph.prototype.get zeroTime):
(WebInspector.TimelineOverviewGraph.prototype.set zeroTime):
(WebInspector.TimelineOverviewGraph.prototype.get startTime):
(WebInspector.TimelineOverviewGraph.prototype.set startTime):
(WebInspector.TimelineOverviewGraph.prototype.get endTime):
(WebInspector.TimelineOverviewGraph.prototype.set endTime):
(WebInspector.TimelineOverviewGraph.prototype.get currentTime):
(WebInspector.TimelineOverviewGraph.prototype.set currentTime):
(WebInspector.TimelineOverviewGraph.prototype.reset):
(WebInspector.TimelineOverviewGraph.prototype.updateLayout):
(WebInspector.TimelineOverviewGraph.prototype.updateLayoutIfNeeded):
(WebInspector.TimelineOverviewGraph.prototype.needsLayout):

* UserInterface/TimelineRecordBar.css:
(.timeline-record-bar &gt; .segment):
(.timeline-record-bar.unfinished &gt; .segment):
(.timeline-record-bar &gt; .segment.inactive + .segment):
(.timeline-record-bar.timeline-record-type-network &gt; .segment.inactive):

* UserInterface/TimelineRecordBar.js:
(WebInspector.TimelineRecordBar):
(WebInspector.TimelineRecordBar.recordsCannotBeCombined):
(WebInspector.TimelineRecordBar.prototype.get records):
(WebInspector.TimelineRecordBar.prototype.set records):
(WebInspector.TimelineRecordBar.prototype.refresh):
Make TimelineRecordBar support multiple records.

* UserInterface/TimelineRuler.css:
(.timeline-ruler &gt; .markers):
(.timeline-ruler &gt; .selection-handle):
(.timeline-ruler &gt; .shaded-area):
Add some z-index values to stay above graph elements.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceBinarySearchjs">trunk/Source/WebInspectorUI/UserInterface/BinarySearch.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceMainhtml">trunk/Source/WebInspectorUI/UserInterface/Main.html</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTimelineContentViewjs">trunk/Source/WebInspectorUI/UserInterface/TimelineContentView.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTimelineDataGridNodejs">trunk/Source/WebInspectorUI/UserInterface/TimelineDataGridNode.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTimelineOverviewcss">trunk/Source/WebInspectorUI/UserInterface/TimelineOverview.css</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTimelineOverviewjs">trunk/Source/WebInspectorUI/UserInterface/TimelineOverview.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTimelineRecordBarcss">trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.css</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTimelineRecordBarjs">trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTimelineRulercss">trunk/Source/WebInspectorUI/UserInterface/TimelineRuler.css</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceLayoutTimelineOverviewGraphcss">trunk/Source/WebInspectorUI/UserInterface/LayoutTimelineOverviewGraph.css</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceLayoutTimelineOverviewGraphjs">trunk/Source/WebInspectorUI/UserInterface/LayoutTimelineOverviewGraph.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceNetworkTimelineOverviewGraphcss">trunk/Source/WebInspectorUI/UserInterface/NetworkTimelineOverviewGraph.css</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceNetworkTimelineOverviewGraphjs">trunk/Source/WebInspectorUI/UserInterface/NetworkTimelineOverviewGraph.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceScriptTimelineOverviewGraphcss">trunk/Source/WebInspectorUI/UserInterface/ScriptTimelineOverviewGraph.css</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceScriptTimelineOverviewGraphjs">trunk/Source/WebInspectorUI/UserInterface/ScriptTimelineOverviewGraph.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTimelineOverviewGraphjs">trunk/Source/WebInspectorUI/UserInterface/TimelineOverviewGraph.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (162418 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2014-01-21 02:56:17 UTC (rev 162418)
+++ trunk/Source/WebInspectorUI/ChangeLog        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -1,3 +1,111 @@
</span><ins>+2014-01-19  Timothy Hatcher  &lt;timothy@apple.com&gt;
+
+        Implement basic versions of the TimelineOverview graphs.
+
+        https://bugs.webkit.org/show_bug.cgi?id=127184
+
+        Reviewed by Joseph Pecoraro.
+
+        * UserInterface/LayoutTimelineOverviewGraph.css: Added.
+        (.timeline-overview-graph.layout &gt; .timeline-record-bar):
+        (.timeline-overview-graph.layout &gt; .timeline-record-bar &gt; .segment):
+
+        * UserInterface/LayoutTimelineOverviewGraph.js: Added.
+        (WebInspector.LayoutTimelineOverviewGraph.prototype.reset):
+        (WebInspector.LayoutTimelineOverviewGraph.prototype.updateLayout):
+        (WebInspector.LayoutTimelineOverviewGraph.prototype._layoutTimelineRecordAdded):
+
+        * UserInterface/Main.html: Added new files.
+
+        * UserInterface/NetworkTimelineOverviewGraph.css: Added.
+        (.timeline-overview-graph.network):
+        (.timeline-overview-graph.network &gt; .graph-row):
+        (.timeline-overview-graph.network &gt; .graph-row &gt; .bar):
+        (.timeline-overview-graph.network &gt; .graph-row &gt; .bar.inactive):
+        (.timeline-overview-graph.network &gt; .graph-row &gt; .bar.unfinished):
+        (.timeline-overview-graph.network &gt; .graph-row &gt; .bar:not(.inactive)):
+        (.timeline-overview-graph.network:nth-child(even) &gt; .graph-row &gt; .bar:not(.inactive)):
+
+        * UserInterface/NetworkTimelineOverviewGraph.js: Added.
+        (WebInspector.NetworkTimelineOverviewGraph.prototype.reset):
+        (WebInspector.NetworkTimelineOverviewGraph.prototype.updateLayout.updateElementPosition):
+        (WebInspector.NetworkTimelineOverviewGraph.prototype.updateLayout.createBar):
+        (WebInspector.NetworkTimelineOverviewGraph.prototype.updateLayout):
+        (WebInspector.NetworkTimelineOverviewGraph.prototype._networkTimelineRecordAdded.compareByStartTime):
+        (WebInspector.NetworkTimelineOverviewGraph.prototype._networkTimelineRecordAdded.insertObjectIntoSortedArray):
+        (WebInspector.NetworkTimelineOverviewGraph.prototype._networkTimelineRecordAdded):
+
+        * UserInterface/ScriptTimelineOverviewGraph.css: Added.
+        (.timeline-overview-graph.script &gt; .timeline-record-bar):
+        (.timeline-overview-graph.script &gt; .timeline-record-bar &gt; .segment):
+
+        * UserInterface/ScriptTimelineOverviewGraph.js: Added.
+        (WebInspector.ScriptTimelineOverviewGraph.prototype.reset):
+        (WebInspector.ScriptTimelineOverviewGraph.prototype.updateLayout):
+        (WebInspector.ScriptTimelineOverviewGraph.prototype._scriptTimelineRecordAdded):
+
+        * UserInterface/TimelineContentView.js:
+        (WebInspector.TimelineContentView.prototype._showTimelineView):
+        (WebInspector.TimelineContentView.prototype._update):
+        (WebInspector.TimelineContentView.prototype._recordingReset):
+        Create and keep the graphs informed.
+
+        * UserInterface/TimelineDataGridNode.js:
+        (WebInspector.TimelineDataGridNode):
+        (WebInspector.TimelineDataGridNode.prototype.refreshGraph):
+        Combine records that might overlap.
+
+        * UserInterface/TimelineOverview.css:
+        (.timeline-overview &gt; .graphs-container):
+        (.timeline-overview &gt; .graphs-container &gt; .timeline-overview-graph):
+        (.timeline-overview &gt; .graphs-container &gt; .timeline-overview-graph:nth-child(even)):
+        (.timeline-overview &gt; .graphs-container &gt; .timeline-overview-graph:not(:first-child)):
+        Add the graph rows with alternating stripe.
+
+        * UserInterface/TimelineOverview.js:
+        (WebInspector.TimelineOverview):
+        (WebInspector.TimelineOverview.prototype.set startTime):
+        (WebInspector.TimelineOverview.prototype.get currentTime):
+        (WebInspector.TimelineOverview.prototype.set currentTime):
+        (WebInspector.TimelineOverview.prototype.updateLayout):
+        (WebInspector.TimelineOverview.prototype.updateLayoutIfNeeded):
+        Track currentTime in a member variable and let TimelineOverview manage the current time marker.
+
+        * UserInterface/TimelineOverviewGraph.js: Added.
+        (WebInspector.TimelineOverviewGraph):
+        (WebInspector.TimelineOverviewGraph.prototype.get zeroTime):
+        (WebInspector.TimelineOverviewGraph.prototype.set zeroTime):
+        (WebInspector.TimelineOverviewGraph.prototype.get startTime):
+        (WebInspector.TimelineOverviewGraph.prototype.set startTime):
+        (WebInspector.TimelineOverviewGraph.prototype.get endTime):
+        (WebInspector.TimelineOverviewGraph.prototype.set endTime):
+        (WebInspector.TimelineOverviewGraph.prototype.get currentTime):
+        (WebInspector.TimelineOverviewGraph.prototype.set currentTime):
+        (WebInspector.TimelineOverviewGraph.prototype.reset):
+        (WebInspector.TimelineOverviewGraph.prototype.updateLayout):
+        (WebInspector.TimelineOverviewGraph.prototype.updateLayoutIfNeeded):
+        (WebInspector.TimelineOverviewGraph.prototype.needsLayout):
+
+        * UserInterface/TimelineRecordBar.css:
+        (.timeline-record-bar &gt; .segment):
+        (.timeline-record-bar.unfinished &gt; .segment):
+        (.timeline-record-bar &gt; .segment.inactive + .segment):
+        (.timeline-record-bar.timeline-record-type-network &gt; .segment.inactive):
+
+        * UserInterface/TimelineRecordBar.js:
+        (WebInspector.TimelineRecordBar):
+        (WebInspector.TimelineRecordBar.recordsCannotBeCombined):
+        (WebInspector.TimelineRecordBar.prototype.get records):
+        (WebInspector.TimelineRecordBar.prototype.set records):
+        (WebInspector.TimelineRecordBar.prototype.refresh):
+        Make TimelineRecordBar support multiple records.
+
+        * UserInterface/TimelineRuler.css:
+        (.timeline-ruler &gt; .markers):
+        (.timeline-ruler &gt; .selection-handle):
+        (.timeline-ruler &gt; .shaded-area):
+        Add some z-index values to stay above graph elements.
+
</ins><span class="cx"> 2014-01-16  Timothy Hatcher  &lt;timothy@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Clean up Timelines code by using ES6 features and less global access of TimelineRecording.
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceBinarySearchjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/BinarySearch.js (162418 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/BinarySearch.js        2014-01-21 02:56:17 UTC (rev 162418)
+++ trunk/Source/WebInspectorUI/UserInterface/BinarySearch.js        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -78,3 +78,8 @@
</span><span class="cx">         return index;
</span><span class="cx">     }
</span><span class="cx"> }
</span><ins>+
+function insertObjectIntoSortedArray(value, array, compareFunction)
+{
+   array.splice(insertionIndexForObjectInListSortedByFunction(value, array, compareFunction), 0, value);
+}
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceLayoutTimelineOverviewGraphcssfromrev162418trunkSourceWebInspectorUIUserInterfaceTimelineOverviewcss"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebInspectorUI/UserInterface/LayoutTimelineOverviewGraph.css (from rev 162418, trunk/Source/WebInspectorUI/UserInterface/TimelineOverview.css) (0 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/LayoutTimelineOverviewGraph.css                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/LayoutTimelineOverviewGraph.css        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -0,0 +1,33 @@
</span><ins>+/*
+ * Copyright (C) 2014 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.layout &gt; .timeline-record-bar {
+    margin-top: 8px;
+    height: 20px;
+}
+
+.timeline-overview-graph.layout &gt; .timeline-record-bar &gt; .segment {
+    border-radius: 2px;
+}
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceLayoutTimelineOverviewGraphjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/LayoutTimelineOverviewGraph.js (0 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/LayoutTimelineOverviewGraph.js                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/LayoutTimelineOverviewGraph.js        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -0,0 +1,119 @@
</span><ins>+/*
+ * Copyright (C) 2014 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.LayoutTimelineOverviewGraph = function(recording)
+{
+    WebInspector.TimelineOverviewGraph.call(this, recording);
+
+    this.element.classList.add(WebInspector.LayoutTimelineOverviewGraph.StyleClassName);
+
+    this._layoutTimeline = recording.timelines.get(WebInspector.TimelineRecord.Type.Layout);
+    this._layoutTimeline.addEventListener(WebInspector.Timeline.Event.RecordAdded, this._layoutTimelineRecordAdded, this);
+
+    this._timelineRecordBars = [];
+
+    this.reset();
+};
+
+WebInspector.LayoutTimelineOverviewGraph.StyleClassName = &quot;layout&quot;;
+
+WebInspector.LayoutTimelineOverviewGraph.prototype = {
+    constructor: WebInspector.LayoutTimelineOverviewGraph,
+    __proto__: WebInspector.TimelineOverviewGraph.prototype,
+
+    // Public
+
+    reset: function()
+    {
+        WebInspector.TimelineOverviewGraph.prototype.reset.call(this);
+
+        this._timelineRecordBarMap = new Map;
+
+        this.element.removeChildren();
+    },
+
+    updateLayout: function()
+    {
+        WebInspector.TimelineOverviewGraph.prototype.updateLayout.call(this);
+
+        var startTime = this.startTime;
+        var currentTime = this.currentTime;
+        var endTime = this.endTime;
+        var duration = (endTime - startTime);
+
+        var visibleWidth = this.element.offsetWidth;
+        var secondsPerPixel = duration / visibleWidth;
+        var recordBarIndex = 0;
+        var barRecords = [];
+
+        function createBar(barRecords)
+        {
+            var timelineRecordBar = this._timelineRecordBars[recordBarIndex];
+            if (!timelineRecordBar)
+                timelineRecordBar = this._timelineRecordBars[recordBarIndex] = new WebInspector.TimelineRecordBar;
+            timelineRecordBar.records = barRecords;
+            timelineRecordBar.refresh(this);
+            if (!timelineRecordBar.element.parentNode)
+                this.element.appendChild(timelineRecordBar.element);
+            ++recordBarIndex;
+        }
+
+        for (var record of this._layoutTimeline.records) {
+            // If this bar is completely before the bounds of the graph, skip this record.
+            if (record.endTime &lt; 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 &gt; currentTime || record.startTime &gt; endTime)
+                break;
+
+            // Check if the previous record is a different type or far enough away to create the bar.
+            if (barRecords.length &amp;&amp; WebInspector.TimelineRecordBar.recordsCannotBeCombined(barRecords, record, secondsPerPixel)) {
+                createBar.call(this, barRecords);
+                barRecords = [];
+            }
+
+            barRecords.push(record);
+        }
+
+        // Create the bar for the last record if needed.
+        if (barRecords.length)
+            createBar.call(this, barRecords);
+
+        // Remove the remaining unused TimelineRecordBars.
+        for (; recordBarIndex &lt; this._timelineRecordBars.length; ++recordBarIndex) {
+            this._timelineRecordBars[recordBarIndex].records = null;
+            this._timelineRecordBars[recordBarIndex].element.remove();
+        }
+    },
+
+    // Private
+
+    _layoutTimelineRecordAdded: function(event)
+    {
+        this.needsLayout();
+    }
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceMainhtml"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (162418 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Main.html        2014-01-21 02:56:17 UTC (rev 162418)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -92,6 +92,9 @@
</span><span class="cx">     &lt;link rel=&quot;stylesheet&quot; href=&quot;TimelineDataGrid.css&quot;&gt;
</span><span class="cx">     &lt;link rel=&quot;stylesheet&quot; href=&quot;TimelineRecordBar.css&quot;&gt;
</span><span class="cx">     &lt;link rel=&quot;stylesheet&quot; href=&quot;TimelineOverview.css&quot;&gt;
</span><ins>+    &lt;link rel=&quot;stylesheet&quot; href=&quot;NetworkTimelineOverviewGraph.css&quot;&gt;
+    &lt;link rel=&quot;stylesheet&quot; href=&quot;LayoutTimelineOverviewGraph.css&quot;&gt;
+    &lt;link rel=&quot;stylesheet&quot; href=&quot;ScriptTimelineOverviewGraph.css&quot;&gt;
</ins><span class="cx">     &lt;link rel=&quot;stylesheet&quot; href=&quot;ProfileView.css&quot;&gt;
</span><span class="cx">     &lt;link rel=&quot;stylesheet&quot; href=&quot;JavaScriptProfileView.css&quot;&gt;
</span><span class="cx">     &lt;link rel=&quot;stylesheet&quot; href=&quot;CSSStyleDetailsSidebarPanel.css&quot;&gt;
</span><span class="lines">@@ -367,6 +370,10 @@
</span><span class="cx">     &lt;script src=&quot;SourceCodeTimelineTimelineDataGridNode.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;TreeOutlineDataGridSynchronizer.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;TimelineOverview.js&quot;&gt;&lt;/script&gt;
</span><ins>+    &lt;script src=&quot;TimelineOverviewGraph.js&quot;&gt;&lt;/script&gt;
+    &lt;script src=&quot;NetworkTimelineOverviewGraph.js&quot;&gt;&lt;/script&gt;
+    &lt;script src=&quot;LayoutTimelineOverviewGraph.js&quot;&gt;&lt;/script&gt;
+    &lt;script src=&quot;ScriptTimelineOverviewGraph.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx">     &lt;script src=&quot;ProfileManager.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;ProfileType.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;ProfileView.js&quot;&gt;&lt;/script&gt;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceNetworkTimelineOverviewGraphcssfromrev162418trunkSourceWebInspectorUIUserInterfaceTimelineRecordBarcss"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebInspectorUI/UserInterface/NetworkTimelineOverviewGraph.css (from rev 162418, trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.css) (0 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/NetworkTimelineOverviewGraph.css                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/NetworkTimelineOverviewGraph.css        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -0,0 +1,66 @@
</span><ins>+/*
+ * Copyright (C) 2014 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.network {
+    padding-top: 2px
+}
+
+.timeline-overview-graph.network &gt; .graph-row {
+    position: relative;
+    height: 5px;
+}
+
+.timeline-overview-graph.network &gt; .graph-row &gt; .bar {
+    position: absolute;
+    height: 4px;
+    background-color: rgb(120, 176, 225);
+    border: 1px solid rgb(61, 147, 200);
+    border-radius: 2px;
+    margin-top: 1px;
+    min-width: 3px;
+}
+
+.timeline-overview-graph.network &gt; .graph-row &gt; .bar.inactive {
+    background-color: rgb(167, 204, 237);
+    border-color: rgb(127, 185, 220);
+}
+
+.timeline-overview-graph.network &gt; .graph-row &gt; .bar.inactive,
+.timeline-overview-graph.network &gt; .graph-row &gt; .bar.unfinished {
+    border-top-right-radius: 0;
+    border-bottom-right-radius: 0;
+    border-right: none;
+}
+
+.timeline-overview-graph.network &gt; .graph-row &gt; .bar:not(.inactive) {
+    border-top-left-radius: 0;
+    border-bottom-left-radius: 0;
+    z-index: 1;
+    box-shadow: white 1px 0 0;
+}
+
+.timeline-overview-graph.network:nth-child(even) &gt; .graph-row &gt; .bar:not(.inactive) {
+    box-shadow: rgb(247, 247, 247) 1px 0 0;
+}
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceNetworkTimelineOverviewGraphjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/NetworkTimelineOverviewGraph.js (0 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/NetworkTimelineOverviewGraph.js                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/NetworkTimelineOverviewGraph.js        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -0,0 +1,257 @@
</span><ins>+
+/*
+ * Copyright (C) 2014 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.NetworkTimelineOverviewGraph = function(recording)
+{
+    WebInspector.TimelineOverviewGraph.call(this, recording);
+
+    this.element.classList.add(WebInspector.NetworkTimelineOverviewGraph.StyleClassName);
+
+    var networkTimeline = recording.timelines.get(WebInspector.TimelineRecord.Type.Network);
+    networkTimeline.addEventListener(WebInspector.Timeline.Event.RecordAdded, this._networkTimelineRecordAdded, this);
+    networkTimeline.addEventListener(WebInspector.Timeline.Event.TimesUpdated, this.needsLayout, this);
+
+    this.reset();
+};
+
+WebInspector.NetworkTimelineOverviewGraph.StyleClassName = &quot;network&quot;;
+WebInspector.NetworkTimelineOverviewGraph.GraphRowStyleClassName = &quot;graph-row&quot;;
+WebInspector.NetworkTimelineOverviewGraph.BarStyleClassName = &quot;bar&quot;;
+WebInspector.NetworkTimelineOverviewGraph.InactiveBarStyleClassName = &quot;inactive&quot;;
+WebInspector.NetworkTimelineOverviewGraph.UnfinishedStyleClassName = &quot;unfinished&quot;;
+WebInspector.NetworkTimelineOverviewGraph.MaximumRowCount = 6;
+WebInspector.NetworkTimelineOverviewGraph.MinimumBarPaddingPixels = 5;
+
+WebInspector.NetworkTimelineOverviewGraph.prototype = {
+    constructor: WebInspector.NetworkTimelineOverviewGraph,
+    __proto__: WebInspector.TimelineOverviewGraph.prototype,
+
+    // Public
+
+    reset: function()
+    {
+        WebInspector.TimelineOverviewGraph.prototype.reset.call(this);
+
+        this._nextDumpRow = 0;
+        this._timelineRecordGridRows = [];
+
+        for (var i = 0; i &lt; WebInspector.NetworkTimelineOverviewGraph.MaximumRowCount; ++i)
+            this._timelineRecordGridRows.push([]);
+
+        this.element.removeChildren();
+    },
+
+    updateLayout: function()
+    {
+        WebInspector.TimelineOverviewGraph.prototype.updateLayout.call(this);
+
+        var startTime = this.startTime;
+        var currentTime = this.currentTime;
+        var endTime = this.endTime;
+        var duration = (endTime - startTime);
+
+        var visibleWidth = this.element.offsetWidth;
+        var secondsPerPixel = duration / visibleWidth;
+
+        function 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 + &quot;%&quot;;
+        }
+
+        function createBar(barElementCache, rowElement, barStartTime, barEndTime, inactive)
+        {
+            if (barStartTime &gt; currentTime)
+                return;
+
+            var barElement = barElementCache.shift();
+            if (!barElement) {
+                barElement = document.createElement(&quot;div&quot;);
+                barElement.classList.add(WebInspector.NetworkTimelineOverviewGraph.BarStyleClassName);
+            }
+
+            barElement.classList.toggle(WebInspector.NetworkTimelineOverviewGraph.InactiveBarStyleClassName, inactive);
+
+            if (barEndTime &gt;= currentTime) {
+                barEndTime = currentTime;
+                barElement.classList.add(WebInspector.NetworkTimelineOverviewGraph.UnfinishedStyleClassName);
+            } else
+                barElement.classList.remove(WebInspector.NetworkTimelineOverviewGraph.UnfinishedStyleClassName);
+
+            if (inactive) {
+                var newBarRightPosition = 1 - ((barEndTime - startTime) / duration);
+                updateElementPosition(barElement, newBarRightPosition, &quot;right&quot;);
+                barElement.style.removeProperty(&quot;left&quot;);
+            } else {
+                var newBarLeftPosition = (barStartTime - startTime) / duration;
+                updateElementPosition(barElement, newBarLeftPosition, &quot;left&quot;);
+                barElement.style.removeProperty(&quot;right&quot;);
+            }
+
+            var newBarWidth = ((barEndTime - barStartTime) / duration);
+            updateElementPosition(barElement, newBarWidth, &quot;width&quot;);
+
+            if (!barElement.parendNode)
+                rowElement.appendChild(barElement);
+        }
+
+        for (var rowRecords of this._timelineRecordGridRows) {
+            var rowElement = rowRecords.__rowElement;
+            if (!rowElement) {
+                rowElement = rowRecords.__rowElement = document.createElement(&quot;div&quot;);
+                rowElement.className = WebInspector.NetworkTimelineOverviewGraph.GraphRowStyleClassName;
+                this.element.appendChild(rowElement);
+            }
+
+            if (!rowRecords.length)
+                continue;
+
+            // Save the current bar elements to reuse.
+            var barElementCache = Array.prototype.slice.call(rowElement.childNodes);
+
+            var inactiveStartTime = NaN;
+            var inactiveEndTime = NaN;
+            var activeStartTime = NaN;
+            var activeEndTime = NaN;
+
+            for (var record of rowRecords) {
+                if (isNaN(record.startTime))
+                    continue;
+
+                // If this bar is completely before the bounds of the graph, skip this record.
+                if (record.endTime &lt; 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 &gt; currentTime || record.startTime &gt; endTime)
+                    break;
+
+                // Check if the previous record is far enough away to create the inactive bar.
+                if (!isNaN(inactiveStartTime) &amp;&amp; inactiveEndTime + (secondsPerPixel * WebInspector.NetworkTimelineOverviewGraph.MinimumBarPaddingPixels) &lt;= record.startTime) {
+                    createBar.call(this, barElementCache, rowElement, inactiveStartTime, inactiveEndTime, true);
+                    inactiveStartTime = NaN;
+                    inactiveEndTime = NaN;
+                }
+
+                // If this is a new bar, peg the start time.
+                if (isNaN(inactiveStartTime))
+                    inactiveStartTime = record.startTime;
+
+                // Update the end time to be the maximum we encounter. inactiveEndTime might be NaN, so &quot;|| 0&quot; to prevent Math.max from returning NaN.
+                inactiveEndTime = Math.max(inactiveEndTime || 0, record.activeStartTime);
+
+                // Check if the previous record is far enough away to create the active bar. We also create it now if the current record has no active state time.
+                if (!isNaN(activeStartTime) &amp;&amp; (activeEndTime + (secondsPerPixel * WebInspector.NetworkTimelineOverviewGraph.MinimumBarPaddingPixels) &lt;= record.activeStartTime || isNaN(record.activeStartTime))) {
+                    if (!isNaN(activeEndTime)) {
+                        createBar.call(this, barElementCache, rowElement, activeStartTime, activeEndTime);
+                        activeStartTime = NaN;
+                        activeEndTime = NaN;
+                    }
+                }
+
+                if (isNaN(record.activeStartTime))
+                    continue;
+
+                // If this is a new bar, peg the start time.
+                if (isNaN(activeStartTime))
+                    activeStartTime = record.activeStartTime;
+
+                // Update the end time to be the maximum we encounter. activeEndTime might be NaN, so &quot;|| 0&quot; to prevent Math.max from returning NaN.
+                if (!isNaN(record.endTime))
+                    activeEndTime = Math.max(activeEndTime || 0, record.endTime);
+            }
+
+            // Create the inactive bar for the last record if needed.
+            if (!isNaN(inactiveStartTime))
+                createBar.call(this, barElementCache, rowElement, inactiveStartTime, inactiveEndTime || currentTime, true);
+
+            // Create the active bar for the last record if needed.
+            if (!isNaN(activeStartTime))
+                createBar.call(this, barElementCache, rowElement, activeStartTime, activeEndTime || currentTime);
+
+            // Remove any unused bar elements.
+            for (var barElement of barElementCache)
+                barElement.remove();
+        }
+    },
+
+    // Private
+
+    _networkTimelineRecordAdded: function(event)
+    {
+        var resourceTimelineRecord = event.data.record;
+        console.assert(resourceTimelineRecord instanceof WebInspector.ResourceTimelineRecord);
+
+        function compareByStartTime(a, b)
+        {
+            return a.startTime - b.startTime;
+        }
+
+        // Try to find a row that has room and does not overlap a previous record.
+        var foundRowForRecord = false;
+        for (var i = 0; i &lt; this._timelineRecordGridRows.length; ++i) {
+            var rowRecords = this._timelineRecordGridRows[i];
+            var lastRecord = rowRecords.lastValue;
+
+            if (!lastRecord || lastRecord.endTime + WebInspector.NetworkTimelineOverviewGraph.MinimumBarPaddingTime &lt;= resourceTimelineRecord.startTime) {
+                insertObjectIntoSortedArray(resourceTimelineRecord, rowRecords, compareByStartTime);
+                this._nextDumpRow = i + 1;
+                foundRowForRecord = true;
+                break;
+            }
+        }
+
+        if (!foundRowForRecord) {
+            // Try to find a row that does not overlap a previous record's active time, but it can overlap the inactive time.
+            for (var i = 0; i &lt; this._timelineRecordGridRows.length; ++i) {
+                var rowRecords = this._timelineRecordGridRows[i];
+                var lastRecord = rowRecords.lastValue;
+                console.assert(lastRecord);
+
+                if (lastRecord.activeStartTime + WebInspector.NetworkTimelineOverviewGraph.MinimumBarPaddingTime &lt;= resourceTimelineRecord.startTime) {
+                    insertObjectIntoSortedArray(resourceTimelineRecord, rowRecords, compareByStartTime);
+                    this._nextDumpRow = i + 1;
+                    foundRowForRecord = true;
+                    break;
+                }
+            }
+        }
+
+        // We didn't find a empty spot, so dump into the designated dump row.
+        if (!foundRowForRecord) {
+            if (this._nextDumpRow &gt;= WebInspector.NetworkTimelineOverviewGraph.MaximumRowCount)
+                this._nextDumpRow = 0;
+            insertObjectIntoSortedArray(resourceTimelineRecord, this._timelineRecordGridRows[this._nextDumpRow++], compareByStartTime);
+        }
+
+        this.needsLayout();
+    }
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceScriptTimelineOverviewGraphcssfromrev162418trunkSourceWebInspectorUIUserInterfaceTimelineOverviewcss"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebInspectorUI/UserInterface/ScriptTimelineOverviewGraph.css (from rev 162418, trunk/Source/WebInspectorUI/UserInterface/TimelineOverview.css) (0 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/ScriptTimelineOverviewGraph.css                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/ScriptTimelineOverviewGraph.css        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -0,0 +1,33 @@
</span><ins>+/*
+ * Copyright (C) 2014 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.script &gt; .timeline-record-bar {
+    margin-top: 8px;
+    height: 20px;
+}
+
+.timeline-overview-graph.script &gt; .timeline-record-bar &gt; .segment {
+    border-radius: 2px;
+}
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceScriptTimelineOverviewGraphjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/ScriptTimelineOverviewGraph.js (0 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/ScriptTimelineOverviewGraph.js                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/ScriptTimelineOverviewGraph.js        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -0,0 +1,119 @@
</span><ins>+/*
+ * Copyright (C) 2014 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.ScriptTimelineOverviewGraph = function(recording)
+{
+    WebInspector.TimelineOverviewGraph.call(this, recording);
+
+    this.element.classList.add(WebInspector.ScriptTimelineOverviewGraph.StyleClassName);
+
+    this._scriptTimeline = recording.timelines.get(WebInspector.TimelineRecord.Type.Script);
+    this._scriptTimeline.addEventListener(WebInspector.Timeline.Event.RecordAdded, this._scriptTimelineRecordAdded, this);
+
+    this._timelineRecordBars = [];
+
+    this.reset();
+};
+
+WebInspector.ScriptTimelineOverviewGraph.StyleClassName = &quot;script&quot;;
+
+WebInspector.ScriptTimelineOverviewGraph.prototype = {
+    constructor: WebInspector.ScriptTimelineOverviewGraph,
+    __proto__: WebInspector.TimelineOverviewGraph.prototype,
+
+    // Public
+
+    reset: function()
+    {
+        WebInspector.TimelineOverviewGraph.prototype.reset.call(this);
+
+        this._timelineRecordBarMap = new Map;
+
+        this.element.removeChildren();
+    },
+
+    updateLayout: function()
+    {
+        WebInspector.TimelineOverviewGraph.prototype.updateLayout.call(this);
+
+        var startTime = this.startTime;
+        var currentTime = this.currentTime;
+        var endTime = this.endTime;
+        var duration = (endTime - startTime);
+
+        var visibleWidth = this.element.offsetWidth;
+        var secondsPerPixel = duration / visibleWidth;
+        var recordBarIndex = 0;
+        var barRecords = [];
+
+        function createBar(barRecords)
+        {
+            var timelineRecordBar = this._timelineRecordBars[recordBarIndex];
+            if (!timelineRecordBar)
+                timelineRecordBar = this._timelineRecordBars[recordBarIndex] = new WebInspector.TimelineRecordBar;
+            timelineRecordBar.records = barRecords;
+            timelineRecordBar.refresh(this);
+            if (!timelineRecordBar.element.parentNode)
+                this.element.appendChild(timelineRecordBar.element);
+            ++recordBarIndex;
+        }
+
+        for (var record of this._scriptTimeline.records) {
+            // If this bar is completely before the bounds of the graph, skip this record.
+            if (record.endTime &lt; 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 &gt; currentTime || record.startTime &gt; endTime)
+                break;
+
+            // Check if the previous record is a different type or far enough away to create the bar.
+            if (barRecords.length &amp;&amp; WebInspector.TimelineRecordBar.recordsCannotBeCombined(barRecords, record, secondsPerPixel)) {
+                createBar.call(this, barRecords);
+                barRecords = [];
+            }
+
+            barRecords.push(record);
+        }
+
+        // Create the bar for the last record if needed.
+        if (barRecords.length)
+            createBar.call(this, barRecords);
+
+        // Remove the remaining unused TimelineRecordBars.
+        for (; recordBarIndex &lt; this._timelineRecordBars.length; ++recordBarIndex) {
+            this._timelineRecordBars[recordBarIndex].records = null;
+            this._timelineRecordBars[recordBarIndex].element.remove();
+        }
+    },
+
+    // Private
+
+    _scriptTimelineRecordAdded: function(event)
+    {
+        this.needsLayout();
+    }
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTimelineContentViewjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/TimelineContentView.js (162418 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/TimelineContentView.js        2014-01-21 02:56:17 UTC (rev 162418)
+++ trunk/Source/WebInspectorUI/UserInterface/TimelineContentView.js        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -31,13 +31,15 @@
</span><span class="cx"> 
</span><span class="cx">     this.element.classList.add(WebInspector.TimelineContentView.StyleClassName);
</span><span class="cx"> 
</span><del>-    this._timelineOverview = new WebInspector.TimelineOverview;
</del><ins>+    this._discreteTimelineOverviewGraphMap = new Map;
+    this._discreteTimelineOverviewGraphMap.set(WebInspector.TimelineRecord.Type.Network, new WebInspector.NetworkTimelineOverviewGraph(recording));
+    this._discreteTimelineOverviewGraphMap.set(WebInspector.TimelineRecord.Type.Layout, new WebInspector.LayoutTimelineOverviewGraph(recording));
+    this._discreteTimelineOverviewGraphMap.set(WebInspector.TimelineRecord.Type.Script, new WebInspector.ScriptTimelineOverviewGraph(recording));
+
+    this._timelineOverview = new WebInspector.TimelineOverview(this._discreteTimelineOverviewGraphMap);
</ins><span class="cx">     this._timelineOverview.addEventListener(WebInspector.TimelineOverview.Event.TimeRangeSelectionChanged, this._timeRangeSelectionChanged, this);
</span><span class="cx">     this.element.appendChild(this._timelineOverview.element);
</span><span class="cx"> 
</span><del>-    this._currentTimeMarker = new WebInspector.TimelineMarker(0, WebInspector.TimelineMarker.Type.CurrentTime);
-    this._timelineOverview.addMarker(this._currentTimeMarker);
-
</del><span class="cx">     this._viewContainer = document.createElement(&quot;div&quot;);
</span><span class="cx">     this._viewContainer.classList.add(WebInspector.TimelineContentView.ViewContainerStyleClassName);
</span><span class="cx">     this.element.appendChild(this._viewContainer);
</span><span class="lines">@@ -159,7 +161,7 @@
</span><span class="cx"> 
</span><span class="cx">         var startTime = this._timelineOverview.selectionStartTime;
</span><span class="cx">         var endTime = this._timelineOverview.selectionStartTime + this._timelineOverview.selectionDuration;
</span><del>-        var currentTime = this._currentTimeMarker.time || this._recording.startTime;
</del><ins>+        var currentTime = this._currentTime || this._recording.startTime;
</ins><span class="cx"> 
</span><span class="cx">         function checkTimeBounds(itemStartTime, itemEndTime)
</span><span class="cx">         {
</span><span class="lines">@@ -228,7 +230,7 @@
</span><span class="cx"> 
</span><span class="cx">             this._currentTimelineView.startTime = this._timelineOverview.selectionStartTime;
</span><span class="cx">             this._currentTimelineView.endTime = this._timelineOverview.selectionStartTime + this._timelineOverview.selectionDuration;
</span><del>-            this._currentTimelineView.currentTime = this._currentTimeMarker.time;
</del><ins>+            this._currentTimelineView.currentTime = this._currentTime;
</ins><span class="cx"> 
</span><span class="cx">             this._currentTimelineView.shown();
</span><span class="cx">             this._currentTimelineView.updateLayout();
</span><span class="lines">@@ -240,7 +242,7 @@
</span><span class="cx">     _update: function(timestamp)
</span><span class="cx">     {
</span><span class="cx">         var startTime = this._recording.startTime;
</span><del>-        var currentTime = this._currentTimeMarker.time || startTime;
</del><ins>+        var currentTime = this._currentTime || startTime;
</ins><span class="cx">         var endTime = this._recording.endTime;
</span><span class="cx">         var timespanSinceLastUpdate = (timestamp - this._lastUpdateTimestamp) / 1000 || 0;
</span><span class="cx"> 
</span><span class="lines">@@ -261,11 +263,10 @@
</span><span class="cx"> 
</span><span class="cx">         this._timelineOverview.endTime = Math.max(endTime, currentTime);
</span><span class="cx"> 
</span><del>-        this._currentTimeMarker.time = currentTime;
</del><ins>+        this._currentTime = currentTime;
+        this._timelineOverview.currentTime = currentTime;
</ins><span class="cx">         this._currentTimelineView.currentTime = currentTime;
</span><span class="cx"> 
</span><del>-        this._timelineOverview.revealMarker(this._currentTimeMarker);
-
</del><span class="cx">         // Force a layout now since we are already in an animation frame and don't need to delay it until the next.
</span><span class="cx">         this._timelineOverview.updateLayoutIfNeeded();
</span><span class="cx">         this._currentTimelineView.updateLayoutIfNeeded();
</span><span class="lines">@@ -314,11 +315,14 @@
</span><span class="cx">     _recordingReset: function(event)
</span><span class="cx">     {
</span><span class="cx">         this._startTimeNeedsReset = true;
</span><del>-        this._currentTimeMarker.time = 0;
</del><ins>+        this._currentTime = NaN;
</ins><span class="cx"> 
</span><span class="cx">         this._overviewTimelineView.reset();
</span><span class="cx">         for (var timelineView of this._discreteTimelineViewMap.values())
</span><span class="cx">             timelineView.reset();
</span><ins>+
+        for (var timelineOverviewGraph of this._discreteTimelineOverviewGraphMap.values())
+            timelineOverviewGraph.reset();
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     _timeRangeSelectionChanged: function(event)
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTimelineDataGridNodejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/TimelineDataGridNode.js (162418 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/TimelineDataGridNode.js        2014-01-21 02:56:17 UTC (rev 162418)
+++ trunk/Source/WebInspectorUI/UserInterface/TimelineDataGridNode.js        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -32,7 +32,7 @@
</span><span class="cx"> 
</span><span class="cx">     if (graphDataSource) {
</span><span class="cx">         this._graphContainerElement = document.createElement(&quot;div&quot;);
</span><del>-        this._timelineRecordBarMap = new Map;
</del><ins>+        this._timelineRecordBars = [];
</ins><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -198,21 +198,90 @@
</span><span class="cx">             delete this._scheduledGraphRefreshIdentifier;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        var records = this.records || [];
-        for (var record of records) {
-            var timelineRecordBar = this._timelineRecordBarMap.get(record);
-            if (!timelineRecordBar) {
-                timelineRecordBar = new WebInspector.TimelineRecordBar(record);
-                this._timelineRecordBarMap.set(record, timelineRecordBar);
</del><ins>+        var records = this.records;
+        if (!records || !records.length)
+            return;
+
+        // Fast path for single records.
+        if (records.length === 1) {
+            var record = records[0];
+            var timelineRecordBar = this._timelineRecordBars[0];
+
+            if (timelineRecordBar &amp;&amp; timelineRecordBar.record !== record) {
+                timelineRecordBar.element.remove();
+                timelineRecordBar = null;
</ins><span class="cx">             }
</span><span class="cx"> 
</span><ins>+            if (!timelineRecordBar)
+                timelineRecordBar = this._timelineRecordBars[0] = new WebInspector.TimelineRecordBar(record);
+
</ins><span class="cx">             if (timelineRecordBar.refresh(this._graphDataSource)) {
</span><span class="cx">                 if (!timelineRecordBar.element.parentNode)
</span><span class="cx">                     this._graphContainerElement.appendChild(timelineRecordBar.element);
</span><del>-            } else {
</del><ins>+            } else
</ins><span class="cx">                 timelineRecordBar.element.remove();
</span><ins>+
+            return;
+        }
+
+        // Multiple records attempt to share a bar if their time is close to prevent overlapping bars.
+        var startTime = this._graphDataSource.startTime;
+        var currentTime = this._graphDataSource.currentTime;
+        var endTime = this._graphDataSource.endTime;
+        var duration = endTime - startTime;
+        var visibleWidth = this._graphContainerElement.offsetWidth;
+        var secondsPerPixel = duration / visibleWidth;
+
+        var recordBarIndex = 0;
+        var barRecords = [];
+
+        function createBar(barRecords)
+        {
+            var timelineRecordBar = this._timelineRecordBars[recordBarIndex];
+            if (!timelineRecordBar)
+                timelineRecordBar = this._timelineRecordBars[recordBarIndex] = new WebInspector.TimelineRecordBar;
+            timelineRecordBar.records = barRecords;
+            timelineRecordBar.refresh(this._graphDataSource);
+            if (!timelineRecordBar.element.parentNode)
+                this._graphContainerElement.appendChild(timelineRecordBar.element);
+            ++recordBarIndex;
+        }
+
+        for (var record of records) {
+            // Combining multiple record bars is not supported with records that have inactive time.
+            // ResourceTimelineRecord is the only one right, and it is always a single record handled above.
+            console.assert(!record.usesActiveStartTime);
+
+            if (isNaN(record.startTime))
+                continue;
+
+            // If this bar is completely before the bounds of the graph, skip this record.
+            if (record.endTime &lt; 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 &gt; currentTime || record.startTime &gt; endTime)
+                break;
+
+            // Check if the previous record can be combined with the current record, if not make a new bar.
+            if (barRecords.length &amp;&amp; WebInspector.TimelineRecordBar.recordsCannotBeCombined(barRecords, record, secondsPerPixel)) {
+                createBar.call(this, barRecords);
+                barRecords = [];
</ins><span class="cx">             }
</span><ins>+
+            barRecords.push(record);
</ins><span class="cx">         }
</span><ins>+
+        // Create the bar for the last record if needed.
+        if (barRecords.length)
+            createBar.call(this, barRecords);
+
+        // Remove the remaining unused TimelineRecordBars.
+        for (; recordBarIndex &lt; this._timelineRecordBars.length; ++recordBarIndex) {
+            this._timelineRecordBars[recordBarIndex].records = null;
+            this._timelineRecordBars[recordBarIndex].element.remove();
+        }
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     needsGraphRefresh: function()
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTimelineOverviewcss"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/TimelineOverview.css (162418 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/TimelineOverview.css        2014-01-21 02:56:17 UTC (rev 162418)
+++ trunk/Source/WebInspectorUI/UserInterface/TimelineOverview.css        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -50,6 +50,27 @@
</span><span class="cx">     right: 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+.timeline-overview &gt; .graphs-container {
+    position: absolute;
+    top: 22px;
+    left: 0;
+    bottom: 0;
+    right: 0;
+}
+
+.timeline-overview &gt; .graphs-container &gt; .timeline-overview-graph {
+    height: 36px;
+}
+
+.timeline-overview &gt; .graphs-container &gt; .timeline-overview-graph:nth-child(even) {
+    background-color: rgb(247, 247, 247);
+    background-clip: padding-box;
+}
+
+.timeline-overview &gt; .graphs-container &gt; .timeline-overview-graph:not(:first-child) {
+    border-top: 1px solid rgba(0, 0, 0, 0.09);
+}
+
</ins><span class="cx"> .timeline-overview &gt; .scroll-container &gt; .scroll-width-sizer {
</span><span class="cx">     position: absolute;
</span><span class="cx">     top: 0;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTimelineOverviewjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/TimelineOverview.js (162418 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/TimelineOverview.js        2014-01-21 02:56:17 UTC (rev 162418)
+++ trunk/Source/WebInspectorUI/UserInterface/TimelineOverview.js        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -23,7 +23,7 @@
</span><span class="cx">  * THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx">  */
</span><span class="cx"> 
</span><del>-WebInspector.TimelineOverview = function()
</del><ins>+WebInspector.TimelineOverview = function(timelineOverviewGraphsMap)
</ins><span class="cx"> {
</span><span class="cx">     WebInspector.Object.call(this);
</span><span class="cx"> 
</span><span class="lines">@@ -31,12 +31,24 @@
</span><span class="cx">     this._element.className = WebInspector.TimelineOverview.StyleClassName;
</span><span class="cx">     this._element.addEventListener(&quot;wheel&quot;, this._handleWheelEvent.bind(this));
</span><span class="cx"> 
</span><ins>+    this._graphsContainer = document.createElement(&quot;div&quot;);
+    this._graphsContainer.className = WebInspector.TimelineOverview.GraphsContainerStyleClassName;
+    this._element.appendChild(this._graphsContainer);
+
+    this._timelineOverviewGraphsMap = timelineOverviewGraphsMap;
+
+    for (var timelineOverviewGraph of this._timelineOverviewGraphsMap.values())
+        this._graphsContainer.appendChild(timelineOverviewGraph.element);
+
</ins><span class="cx">     this._timelineRuler = new WebInspector.TimelineRuler;
</span><span class="cx">     this._timelineRuler.allowsClippedLabels = true;
</span><span class="cx">     this._timelineRuler.allowsTimeRangeSelection = true;
</span><span class="cx">     this._timelineRuler.addEventListener(WebInspector.TimelineRuler.Event.TimeRangeSelectionChanged, this._timeRangeSelectionChanged, this);
</span><span class="cx">     this._element.appendChild(this._timelineRuler.element);
</span><span class="cx"> 
</span><ins>+    this._currentTimeMarker = new WebInspector.TimelineMarker(0, WebInspector.TimelineMarker.Type.CurrentTime);
+    this._timelineRuler.addMarker(this._currentTimeMarker);
+
</ins><span class="cx">     this._scrollContainer = document.createElement(&quot;div&quot;);
</span><span class="cx">     this._scrollContainer.className = WebInspector.TimelineOverview.ScrollContainerStyleClassName;
</span><span class="cx">     this._scrollContainer.addEventListener(&quot;scroll&quot;, this._handleScrollEvent.bind(this));
</span><span class="lines">@@ -47,6 +59,7 @@
</span><span class="cx">     this._scrollContainer.appendChild(this._scrollWidthSizer);
</span><span class="cx"> 
</span><span class="cx">     this._startTime = 0;
</span><ins>+    this._currentTime = 0;
</ins><span class="cx">     this._endTime = 0;
</span><span class="cx">     this._secondsPerPixel = 0.0025;
</span><span class="cx">     this._scrollStartTime = 0;
</span><span class="lines">@@ -56,6 +69,7 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> WebInspector.TimelineOverview.StyleClassName = &quot;timeline-overview&quot;;
</span><ins>+WebInspector.TimelineOverview.GraphsContainerStyleClassName = &quot;graphs-container&quot;;
</ins><span class="cx"> WebInspector.TimelineOverview.ScrollContainerStyleClassName = &quot;scroll-container&quot;;
</span><span class="cx"> WebInspector.TimelineOverview.ScrollWidthSizerStyleClassName = &quot;scroll-width-sizer&quot;;
</span><span class="cx"> WebInspector.TimelineOverview.MinimumSecondsPerPixel = 0.001;
</span><span class="lines">@@ -86,11 +100,27 @@
</span><span class="cx">         if (this._startTime === x)
</span><span class="cx">             return;
</span><span class="cx"> 
</span><del>-        this._startTime = x;
</del><ins>+        this._startTime = x || 0;
</ins><span class="cx"> 
</span><span class="cx">         this._needsLayout();
</span><span class="cx">     },
</span><span class="cx"> 
</span><ins>+    get currentTime()
+    {
+        return this._currentTime;
+    },
+
+    set currentTime(x)
+    {
+        if (this._currentTime === x)
+            return;
+
+        this._currentTime = x || 0;
+        this._revealCurrentTime = true;
+
+        this._needsLayout();
+    },
+
</ins><span class="cx">     get secondsPerPixel()
</span><span class="cx">     {
</span><span class="cx">         return this._secondsPerPixel;
</span><span class="lines">@@ -192,6 +222,13 @@
</span><span class="cx">         // Update all relevant elements to the new required width.
</span><span class="cx">         this._updateElementWidth(this._scrollWidthSizer, newWidth);
</span><span class="cx"> 
</span><ins>+        this._currentTimeMarker.time = this._currentTime;
+
+        if (this._revealCurrentTime) {
+            this.revealMarker(this._currentTimeMarker);
+            delete this._revealCurrentTime;
+        }
+
</ins><span class="cx">         // Clamp the scroll start time to match what the scroll bar would allow.
</span><span class="cx">         var scrollStartTime = Math.min(this._scrollStartTime, this._endTime - this.visibleDuration);
</span><span class="cx">         scrollStartTime = Math.max(this._startTime, scrollStartTime);
</span><span class="lines">@@ -206,15 +243,27 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         this._timelineRuler.updateLayout();
</span><ins>+
+        for (var timelineOverviewGraph of this._timelineOverviewGraphsMap.values()) {
+            timelineOverviewGraph.zeroTime = this._startTime;
+            timelineOverviewGraph.startTime = scrollStartTime;
+            timelineOverviewGraph.currentTime = this._currentTime;
+            timelineOverviewGraph.endTime = scrollStartTime + this.visibleDuration;
+            timelineOverviewGraph.updateLayout();
+        }
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     updateLayoutIfNeeded: function()
</span><span class="cx">     {
</span><ins>+        if (this._scheduledLayoutUpdateIdentifier) {
+            this.updateLayout();
+            return;
+        }
+
</ins><span class="cx">         this._timelineRuler.updateLayoutIfNeeded();
</span><span class="cx"> 
</span><del>-        if (!this._scheduledLayoutUpdateIdentifier)
-            return;
-        this.updateLayout();
</del><ins>+        for (var timelineOverviewGraph of this._timelineOverviewGraphsMap.values())
+            timelineOverviewGraph.updateLayoutIfNeeded();
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     // Private
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTimelineOverviewGraphjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/TimelineOverviewGraph.js (0 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/TimelineOverviewGraph.js                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/TimelineOverviewGraph.js        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -0,0 +1,141 @@
</span><ins>+/*
+ * Copyright (C) 2014 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.TimelineOverviewGraph = function(recording)
+{
+    WebInspector.Object.call(this);
+
+    this.element = document.createElement(&quot;div&quot;);
+    this.element.classList.add(WebInspector.TimelineOverviewGraph.StyleClassName);
+
+    this._zeroTime = 0;
+    this._startTime = 0;
+    this._endTime = 5;
+    this._currentTime = 0;
+};
+
+WebInspector.TimelineOverviewGraph.StyleClassName = &quot;timeline-overview-graph&quot;;
+
+WebInspector.TimelineOverviewGraph.prototype = {
+    constructor: WebInspector.TimelineOverviewGraph,
+    __proto__: WebInspector.Object.prototype,
+
+    // Public
+
+    get zeroTime()
+    {
+        return this._zeroTime;
+    },
+
+    set zeroTime(x)
+    {
+        if (this._zeroTime === x)
+            return;
+
+        this._zeroTime = x || 0;
+
+        this.needsLayout();
+    },
+
+    get startTime()
+    {
+        return this._startTime;
+    },
+
+    set startTime(x)
+    {
+        if (this._startTime === x)
+            return;
+
+        this._startTime = x || 0;
+
+        this.needsLayout();
+    },
+
+    get endTime()
+    {
+        return this._endTime;
+    },
+
+    set endTime(x)
+    {
+        if (this._endTime === x)
+            return;
+
+        this._endTime = x || 0;
+
+        this.needsLayout();
+    },
+
+    get currentTime()
+    {
+        return this._currentTime;
+    },
+
+    set currentTime(x)
+    {
+        if (this._currentTime === x)
+            return;
+
+        var oldCurrentTime = this._currentTime;
+
+        this._currentTime = x || 0;
+
+        if ((this._startTime &lt;= oldCurrentTime &amp;&amp; oldCurrentTime &lt;= this._endTime) || (this._startTime &lt;= this._currentTime &amp;&amp; this._currentTime &lt;= this._endTime))
+            this.needsLayout();
+    },
+
+    reset: function()
+    {
+        // Implemented by sub-classes if needed.
+    },
+
+    updateLayout: function()
+    {
+        if (this._scheduledLayoutUpdateIdentifier) {
+            cancelAnimationFrame(this._scheduledLayoutUpdateIdentifier);
+            delete this._scheduledLayoutUpdateIdentifier;
+        }
+
+        // Implemented by sub-classes if needed.
+    },
+
+    updateLayoutIfNeeded: function()
+    {
+        if (!this._scheduledLayoutUpdateIdentifier)
+            return;
+        this.updateLayout();
+    },
+
+    // Protected
+
+    needsLayout: function()
+    {
+        if (this._scheduledLayoutUpdateIdentifier)
+            return;
+
+        this._scheduledLayoutUpdateIdentifier = requestAnimationFrame(this.updateLayout.bind(this));
+    }
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTimelineRecordBarcss"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.css (162418 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.css        2014-01-21 02:56:17 UTC (rev 162418)
+++ trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.css        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -30,7 +30,7 @@
</span><span class="cx"> 
</span><span class="cx"> .timeline-record-bar &gt; .segment {
</span><span class="cx">     position: absolute;
</span><del>-    height: 12px;
</del><ins>+    height: 100%;
</ins><span class="cx">     background-color: rgb(225, 225, 225);
</span><span class="cx">     border: 1px solid rgb(200, 200, 200);
</span><span class="cx">     border-radius: 3px;
</span><span class="lines">@@ -44,14 +44,14 @@
</span><span class="cx"> 
</span><span class="cx"> .timeline-record-bar &gt; .segment.inactive,
</span><span class="cx"> .timeline-record-bar.unfinished &gt; .segment {
</span><del>-    border-top-right-radius: 0;
-    border-bottom-right-radius: 0;
</del><ins>+    border-top-right-radius: 0 !important;
+    border-bottom-right-radius: 0 !important;
</ins><span class="cx">     border-right: none;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> .timeline-record-bar &gt; .segment.inactive + .segment {
</span><del>-    border-top-left-radius: 0;
-    border-bottom-left-radius: 0;
</del><ins>+    border-top-left-radius: 0 !important;
+    border-bottom-left-radius: 0 !important;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> :focus .selected .timeline-record-bar &gt; .segment {
</span><span class="lines">@@ -59,15 +59,16 @@
</span><span class="cx">     border-color: white !important;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-.timeline-record-bar &gt; .segment.inactive {
-    opacity: 0.5;
-}
-
</del><span class="cx"> .timeline-record-bar.timeline-record-type-network &gt; .segment {
</span><span class="cx">     background-color: rgb(120, 176, 225);
</span><span class="cx">     border-color: rgb(61, 147, 200);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+.timeline-record-bar.timeline-record-type-network &gt; .segment.inactive {
+    background-color: rgb(167, 204, 237);
+    border-color: rgb(127, 185, 220);
+}
+
</ins><span class="cx"> .timeline-record-bar.timeline-record-type-layout &gt; .segment {
</span><span class="cx">     background-color: rgb(234, 153, 153);
</span><span class="cx">     border-color: rgb(212, 108, 108);
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTimelineRecordBarjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.js (162418 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.js        2014-01-21 02:56:17 UTC (rev 162418)
+++ trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.js        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -23,31 +23,18 @@
</span><span class="cx">  * THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx">  */
</span><span class="cx"> 
</span><del>-WebInspector.TimelineRecordBar = function(record)
</del><ins>+WebInspector.TimelineRecordBar = function(records)
</ins><span class="cx"> {
</span><span class="cx">     WebInspector.Object.call(this);
</span><span class="cx"> 
</span><del>-    console.assert(record);
-
-    this._record = record;
-
</del><span class="cx">     this._element = document.createElement(&quot;div&quot;);
</span><span class="cx">     this._element.classList.add(WebInspector.TimelineRecordBar.StyleClassName);
</span><del>-    this._element.classList.add(record.type);
</del><span class="cx"> 
</span><del>-    if (record.usesActiveStartTime) {
-        this._inactiveBarElement = document.createElement(&quot;div&quot;);
-        this._inactiveBarElement.classList.add(WebInspector.TimelineRecordBar.BarSegmentStyleClassName);
-        this._inactiveBarElement.classList.add(WebInspector.TimelineRecordBar.InactiveStyleClassName);
-        this._element.classList.add(WebInspector.TimelineRecordBar.HasInactiveSegmentStyleClassName);
-    }
-
</del><span class="cx">     this._activeBarElement = document.createElement(&quot;div&quot;);
</span><span class="cx">     this._activeBarElement.classList.add(WebInspector.TimelineRecordBar.BarSegmentStyleClassName);
</span><ins>+    this._element.appendChild(this._activeBarElement);
</ins><span class="cx"> 
</span><del>-    if (this._inactiveBarElement)
-        this._element.appendChild(this._inactiveBarElement);
-    this._element.appendChild(this._activeBarElement);
</del><ins>+    this.records = records;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> WebInspector.Object.addConstructorFunctions(WebInspector.TimelineRecordBar);
</span><span class="lines">@@ -57,7 +44,36 @@
</span><span class="cx"> WebInspector.TimelineRecordBar.InactiveStyleClassName = &quot;inactive&quot;;
</span><span class="cx"> WebInspector.TimelineRecordBar.UnfinishedStyleClassName = &quot;unfinished&quot;;
</span><span class="cx"> WebInspector.TimelineRecordBar.HasInactiveSegmentStyleClassName = &quot;has-inactive-segment&quot;;
</span><ins>+WebInspector.TimelineRecordBar.MinimumWidthPixels = 4;
+WebInspector.TimelineRecordBar.MinimumMarginPixels = 1;
</ins><span class="cx"> 
</span><ins>+WebInspector.TimelineRecordBar.recordsCannotBeCombined = function(records, candidateRecord, secondsPerPixel)
+{
+    console.assert(records instanceof Array || records instanceof WebInspector.TimelineRecord);
+    console.assert(candidateRecord instanceof WebInspector.TimelineRecord);
+
+    if (records instanceof WebInspector.TimelineRecord)
+        records = [records];
+
+    if (!records.length)
+        return true;
+
+    var lastRecord = records.lastValue;
+    if (lastRecord.type !== candidateRecord.type)
+        return true;
+
+    if (isNaN(candidateRecord.startTime))
+        return true;
+
+    var firstRecord = records[0];
+    var totalDuration = lastRecord.endTime - firstRecord.startTime;
+
+    var minimumMargin = WebInspector.TimelineRecordBar.MinimumMarginPixels * secondsPerPixel;
+    var minimumDuration = WebInspector.TimelineRecordBar.MinimumWidthPixels * secondsPerPixel;
+
+    return firstRecord.startTime + Math.max(minimumDuration, totalDuration) + minimumMargin &lt;= candidateRecord.startTime;
+};
+
</ins><span class="cx"> WebInspector.TimelineRecordBar.prototype = {
</span><span class="cx">     constructor: WebInspector.TimelineRecordBar,
</span><span class="cx">     __proto__: WebInspector.Object.prototype,
</span><span class="lines">@@ -69,10 +85,53 @@
</span><span class="cx">         return this._element;
</span><span class="cx">     },
</span><span class="cx"> 
</span><ins>+    get records()
+    {
+        return this._records;
+    },
+
+    set records(records)
+    {
+        if (this._records &amp;&amp; this._records.length)
+            this._element.classList.remove(this._records[0].type);
+
+        records = records || [];
+
+        if (!(records instanceof Array))
+            records = [records];
+
+        this._records = records;
+
+        // Combining multiple record bars is not supported with records that have inactive time.
+        console.assert(this._records.length &lt;= 1 || !this._records[0].usesActiveStartTime);
+
+        // Inactive time is only supported with one record.
+        if (this._records.length === 1 &amp;&amp; this._records[0].usesActiveStartTime) {
+            if (!this._inactiveBarElement) {
+                this._inactiveBarElement = document.createElement(&quot;div&quot;);
+                this._inactiveBarElement.classList.add(WebInspector.TimelineRecordBar.BarSegmentStyleClassName);
+                this._inactiveBarElement.classList.add(WebInspector.TimelineRecordBar.InactiveStyleClassName);
+                this._element.classList.add(WebInspector.TimelineRecordBar.HasInactiveSegmentStyleClassName);
+                this._element.insertBefore(this._inactiveBarElement, this._activeBarElement);
+            }
+        } else if (this._inactiveBarElement) {
+            this._inactiveBarElement.remove();
+            delete this._inactiveBarElement;
+        }
+
+        // Assume all records are the same type.
+        if (this._records.length)
+            this._element.classList.add(this._records[0].type);
+    },
+
</ins><span class="cx">     refresh: function(graphDataSource)
</span><span class="cx">     {
</span><del>-        var barStartTime = this._record.startTime;
</del><ins>+        if (!this._records || !this._records.length)
+            return;
</ins><span class="cx"> 
</span><ins>+        var firstRecord = this._records[0];
+        var barStartTime = firstRecord.startTime;
+
</ins><span class="cx">         // If this bar has no time info, return early.
</span><span class="cx">         if (isNaN(barStartTime))
</span><span class="cx">             return false;
</span><span class="lines">@@ -81,13 +140,14 @@
</span><span class="cx">         var graphEndTime = graphDataSource.endTime;
</span><span class="cx">         var graphCurrentTime = graphDataSource.currentTime;
</span><span class="cx"> 
</span><del>-        var barEndTime = this._record.endTime;
</del><ins>+        var lastRecord = this._records.lastValue;
+        var barEndTime = lastRecord.endTime;
</ins><span class="cx"> 
</span><del>-        // If this bar is completly after the current time, return early.
</del><ins>+        // If this bar is completely after the current time, return early.
</ins><span class="cx">         if (barStartTime &gt; graphCurrentTime)
</span><span class="cx">             return false;
</span><span class="cx"> 
</span><del>-        // If this bar is completly before or after the bounds of the graph, return early.
</del><ins>+        // If this bar is completely before or after the bounds of the graph, return early.
</ins><span class="cx">         if (barEndTime &lt; graphStartTime || barStartTime &gt; graphEndTime)
</span><span class="cx">             return false;
</span><span class="cx"> 
</span><span class="lines">@@ -105,10 +165,12 @@
</span><span class="cx">         var newBarWidth = ((barEndTime - graphStartTime) / graphDuration) - newBarLeftPosition;
</span><span class="cx">         this._updateElementPosition(this._element, newBarWidth, &quot;width&quot;);
</span><span class="cx"> 
</span><del>-        if (!this._record.usesActiveStartTime)
</del><ins>+        if (!this._inactiveBarElement)
</ins><span class="cx">             return true;
</span><span class="cx"> 
</span><del>-        var barActiveStartTime = Math.max(barStartTime, Math.min(this._record.activeStartTime, barEndTime));
</del><ins>+        console.assert(firstRecord === lastRecord);
+
+        var barActiveStartTime = Math.max(barStartTime, Math.min(firstRecord.activeStartTime, barEndTime));
</ins><span class="cx">         var barDuration = barEndTime - barStartTime;
</span><span class="cx"> 
</span><span class="cx">         var inactiveUnfinished = isNaN(barActiveStartTime) || barActiveStartTime &gt;= graphCurrentTime;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTimelineRulercss"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/TimelineRuler.css (162418 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/TimelineRuler.css        2014-01-21 02:56:17 UTC (rev 162418)
+++ trunk/Source/WebInspectorUI/UserInterface/TimelineRuler.css        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -71,7 +71,7 @@
</span><span class="cx">     left: 0;
</span><span class="cx">     right: 0;
</span><span class="cx">     bottom: 0;
</span><del>-    z-index: 1;
</del><ins>+    z-index: 10;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> .timeline-ruler &gt; .markers &gt; .divider {
</span><span class="lines">@@ -148,6 +148,7 @@
</span><span class="cx">     border: 1px solid white;
</span><span class="cx">     cursor: col-resize;
</span><span class="cx">     pointer-events: all;
</span><ins>+    z-index: 15;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> .timeline-ruler &gt; .selection-handle.left {
</span><span class="lines">@@ -163,6 +164,7 @@
</span><span class="cx">     top: 0;
</span><span class="cx">     bottom: 0;
</span><span class="cx">     background-color: rgba(0, 0, 0, 0.1);
</span><ins>+    z-index: 15;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> .timeline-ruler &gt; .shaded-area.left {
</span></span></pre>
</div>
</div>

</body>
</html>