<!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>[162681] 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/162681">162681</a></dd>
<dt>Author</dt> <dd>timothy@apple.com</dd>
<dt>Date</dt> <dd>2014-01-23 19:41:22 -0800 (Thu, 23 Jan 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Refactor TimelineRecordBar combining logic into a helper function.

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

Reviewed by Joseph Pecoraro.

* UserInterface/LayoutTimelineOverviewGraph.js:
(WebInspector.LayoutTimelineOverviewGraph.prototype.updateLayout.createBar):
(WebInspector.LayoutTimelineOverviewGraph.prototype.updateLayout):
Use TimelineRecordBar.createCombinedBars.

* UserInterface/NetworkTimelineOverviewGraph.css:
(.timeline-overview-graph.network):
(.timeline-overview-graph.network &gt; .graph-row &gt; .timeline-record-bar):
Cleaned up since we are using TimelineRecordBar.

* UserInterface/NetworkTimelineOverviewGraph.js:
(WebInspector.NetworkTimelineOverviewGraph.prototype.reset):
(WebInspector.NetworkTimelineOverviewGraph.prototype.updateLayout.createBar):
(WebInspector.NetworkTimelineOverviewGraph.prototype.updateLayout):
Use TimelineRecordBar.createCombinedBars.

* UserInterface/ScriptTimelineOverviewGraph.js:
(WebInspector.ScriptTimelineOverviewGraph.prototype.updateLayout.createBar):
(WebInspector.ScriptTimelineOverviewGraph.prototype.updateLayout):
Use TimelineRecordBar.createCombinedBars.

* UserInterface/TimelineDataGridNode.js:
(WebInspector.TimelineDataGridNode.prototype.refreshGraph.createBar):
(WebInspector.TimelineDataGridNode.prototype.refreshGraph):
Use TimelineRecordBar.createCombinedBars.

* UserInterface/TimelineRecordBar.css:
(.timeline-record-bar.unfinished &gt; .segment):
(.timeline-record-bar.has-inactive-segment &gt; .segment:not(.inactive)):
(:focus .selected .timeline-record-bar &gt; .segment.inactive):
Improved selected appearance and don't assume .segment.inactive exists.

* UserInterface/TimelineRecordBar.js:
(WebInspector.TimelineRecordBar):
(WebInspector.TimelineRecordBar.createCombinedBars.compareByActiveStartTime): Added.
(WebInspector.TimelineRecordBar.createCombinedBars): Added.
(WebInspector.TimelineRecordBar.prototype.get renderMode): Added.
(WebInspector.TimelineRecordBar.prototype.set renderMode): Added.
(WebInspector.TimelineRecordBar.prototype.set records):
(WebInspector.TimelineRecordBar.prototype.refresh):
Lazy create DOM elements. Support rendering one or both segments. Doing this lets
combined inactive segments to sit behind multiple active segments.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</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="#trunkSourceWebInspectorUIUserInterfaceScriptTimelineOverviewGraphjs">trunk/Source/WebInspectorUI/UserInterface/ScriptTimelineOverviewGraph.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTimelineDataGridNodejs">trunk/Source/WebInspectorUI/UserInterface/TimelineDataGridNode.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>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (162680 => 162681)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2014-01-24 03:08:56 UTC (rev 162680)
+++ trunk/Source/WebInspectorUI/ChangeLog        2014-01-24 03:41:22 UTC (rev 162681)
</span><span class="lines">@@ -1,3 +1,54 @@
</span><ins>+2014-01-23  Timothy Hatcher  &lt;timothy@apple.com&gt;
+
+        Refactor TimelineRecordBar combining logic into a helper function.
+
+        https://bugs.webkit.org/show_bug.cgi?id=127530
+
+        Reviewed by Joseph Pecoraro.
+
+        * UserInterface/LayoutTimelineOverviewGraph.js:
+        (WebInspector.LayoutTimelineOverviewGraph.prototype.updateLayout.createBar):
+        (WebInspector.LayoutTimelineOverviewGraph.prototype.updateLayout):
+        Use TimelineRecordBar.createCombinedBars.
+
+        * UserInterface/NetworkTimelineOverviewGraph.css:
+        (.timeline-overview-graph.network):
+        (.timeline-overview-graph.network &gt; .graph-row &gt; .timeline-record-bar):
+        Cleaned up since we are using TimelineRecordBar.
+
+        * UserInterface/NetworkTimelineOverviewGraph.js:
+        (WebInspector.NetworkTimelineOverviewGraph.prototype.reset):
+        (WebInspector.NetworkTimelineOverviewGraph.prototype.updateLayout.createBar):
+        (WebInspector.NetworkTimelineOverviewGraph.prototype.updateLayout):
+        Use TimelineRecordBar.createCombinedBars.
+
+        * UserInterface/ScriptTimelineOverviewGraph.js:
+        (WebInspector.ScriptTimelineOverviewGraph.prototype.updateLayout.createBar):
+        (WebInspector.ScriptTimelineOverviewGraph.prototype.updateLayout):
+        Use TimelineRecordBar.createCombinedBars.
+
+        * UserInterface/TimelineDataGridNode.js:
+        (WebInspector.TimelineDataGridNode.prototype.refreshGraph.createBar):
+        (WebInspector.TimelineDataGridNode.prototype.refreshGraph):
+        Use TimelineRecordBar.createCombinedBars.
+
+        * UserInterface/TimelineRecordBar.css:
+        (.timeline-record-bar.unfinished &gt; .segment):
+        (.timeline-record-bar.has-inactive-segment &gt; .segment:not(.inactive)):
+        (:focus .selected .timeline-record-bar &gt; .segment.inactive):
+        Improved selected appearance and don't assume .segment.inactive exists.
+
+        * UserInterface/TimelineRecordBar.js:
+        (WebInspector.TimelineRecordBar):
+        (WebInspector.TimelineRecordBar.createCombinedBars.compareByActiveStartTime): Added.
+        (WebInspector.TimelineRecordBar.createCombinedBars): Added.
+        (WebInspector.TimelineRecordBar.prototype.get renderMode): Added.
+        (WebInspector.TimelineRecordBar.prototype.set renderMode): Added.
+        (WebInspector.TimelineRecordBar.prototype.set records):
+        (WebInspector.TimelineRecordBar.prototype.refresh):
+        Lazily create DOM elements. Support rendering one or both segments. Doing this lets
+        combined inactive segments sit behind multiple active segments.
+
</ins><span class="cx"> 2014-01-22  Timothy Hatcher  &lt;timothy@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Improve collapsing of TimelineDataGridNode graphs up to ancestors.
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceLayoutTimelineOverviewGraphjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/LayoutTimelineOverviewGraph.js (162680 => 162681)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/LayoutTimelineOverviewGraph.js        2014-01-24 03:08:56 UTC (rev 162680)
+++ trunk/Source/WebInspectorUI/UserInterface/LayoutTimelineOverviewGraph.js        2014-01-24 03:41:22 UTC (rev 162681)
</span><span class="lines">@@ -58,51 +58,26 @@
</span><span class="cx">     {
</span><span class="cx">         WebInspector.TimelineOverviewGraph.prototype.updateLayout.call(this);
</span><span class="cx"> 
</span><del>-        var startTime = this.startTime;
-        var currentTime = this.currentTime;
-        var endTime = this.endTime;
-        var duration = (endTime - startTime);
-
</del><span class="cx">         var visibleWidth = this.element.offsetWidth;
</span><del>-        var secondsPerPixel = duration / visibleWidth;
</del><ins>+        var secondsPerPixel = (this.endTime - this.startTime) / visibleWidth;
+
</ins><span class="cx">         var recordBarIndex = 0;
</span><del>-        var barRecords = [];
</del><span class="cx"> 
</span><del>-        function createBar(barRecords)
</del><ins>+        function createBar(records, renderMode)
</ins><span class="cx">         {
</span><span class="cx">             var timelineRecordBar = this._timelineRecordBars[recordBarIndex];
</span><span class="cx">             if (!timelineRecordBar)
</span><span class="cx">                 timelineRecordBar = this._timelineRecordBars[recordBarIndex] = new WebInspector.TimelineRecordBar;
</span><del>-            timelineRecordBar.records = barRecords;
</del><ins>+            timelineRecordBar.renderMode = renderMode;
+            timelineRecordBar.records = records;
</ins><span class="cx">             timelineRecordBar.refresh(this);
</span><span class="cx">             if (!timelineRecordBar.element.parentNode)
</span><span class="cx">                 this.element.appendChild(timelineRecordBar.element);
</span><span class="cx">             ++recordBarIndex;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        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;
</del><ins>+        WebInspector.TimelineRecordBar.createCombinedBars(this._layoutTimeline.records, secondsPerPixel, this, createBar.bind(this));
</ins><span class="cx"> 
</span><del>-            // 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);
-
</del><span class="cx">         // Remove the remaining unused TimelineRecordBars.
</span><span class="cx">         for (; recordBarIndex &lt; this._timelineRecordBars.length; ++recordBarIndex) {
</span><span class="cx">             this._timelineRecordBars[recordBarIndex].records = null;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceNetworkTimelineOverviewGraphcss"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/NetworkTimelineOverviewGraph.css (162680 => 162681)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/NetworkTimelineOverviewGraph.css        2014-01-24 03:08:56 UTC (rev 162680)
+++ trunk/Source/WebInspectorUI/UserInterface/NetworkTimelineOverviewGraph.css        2014-01-24 03:41:22 UTC (rev 162681)
</span><span class="lines">@@ -24,43 +24,22 @@
</span><span class="cx">  */
</span><span class="cx"> 
</span><span class="cx"> .timeline-overview-graph.network {
</span><del>-    padding-top: 2px
</del><ins>+    padding-top: 3px;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> .timeline-overview-graph.network &gt; .graph-row {
</span><del>-    position: relative;
</del><span class="cx">     height: 5px;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-.timeline-overview-graph.network &gt; .graph-row &gt; .bar {
-    position: absolute;
</del><ins>+.timeline-overview-graph.network &gt; .graph-row &gt; .timeline-record-bar {
</ins><span class="cx">     height: 4px;
</span><del>-    background-color: rgb(120, 176, 225);
-    border: 1px solid rgb(61, 147, 200);
-    border-radius: 2px;
</del><span class="cx">     margin-top: 1px;
</span><del>-    min-width: 3px;
</del><span class="cx"> }
</span><span class="cx"> 
</span><del>-.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;
</del><ins>+.timeline-overview-graph.network &gt; .graph-row &gt; .timeline-record-bar &gt; .segment:not(.inactive) {
</ins><span class="cx">     box-shadow: white 1px 0 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-.timeline-overview-graph.network:nth-child(even) &gt; .graph-row &gt; .bar:not(.inactive) {
</del><ins>+.timeline-overview-graph.network:nth-child(even) &gt; .graph-row &gt; .timeline-record-bar &gt; .segment:not(.inactive) {
</ins><span class="cx">     box-shadow: rgb(247, 247, 247) 1px 0 0;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceNetworkTimelineOverviewGraphjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/NetworkTimelineOverviewGraph.js (162680 => 162681)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/NetworkTimelineOverviewGraph.js        2014-01-24 03:08:56 UTC (rev 162680)
+++ trunk/Source/WebInspectorUI/UserInterface/NetworkTimelineOverviewGraph.js        2014-01-24 03:41:22 UTC (rev 162681)
</span><span class="lines">@@ -43,7 +43,6 @@
</span><span class="cx"> WebInspector.NetworkTimelineOverviewGraph.InactiveBarStyleClassName = &quot;inactive&quot;;
</span><span class="cx"> WebInspector.NetworkTimelineOverviewGraph.UnfinishedStyleClassName = &quot;unfinished&quot;;
</span><span class="cx"> WebInspector.NetworkTimelineOverviewGraph.MaximumRowCount = 6;
</span><del>-WebInspector.NetworkTimelineOverviewGraph.MinimumBarPaddingPixels = 5;
</del><span class="cx"> 
</span><span class="cx"> WebInspector.NetworkTimelineOverviewGraph.prototype = {
</span><span class="cx">     constructor: WebInspector.NetworkTimelineOverviewGraph,
</span><span class="lines">@@ -62,144 +61,51 @@
</span><span class="cx">             this._timelineRecordGridRows.push([]);
</span><span class="cx"> 
</span><span class="cx">         this.element.removeChildren();
</span><ins>+
+        for (var rowRecords of this._timelineRecordGridRows) {
+            rowRecords.__element = document.createElement(&quot;div&quot;);
+            rowRecords.__element.className = WebInspector.NetworkTimelineOverviewGraph.GraphRowStyleClassName;
+            this.element.appendChild(rowRecords.__element);
+
+            rowRecords.__recordBars = [];
+        }
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     updateLayout: function()
</span><span class="cx">     {
</span><span class="cx">         WebInspector.TimelineOverviewGraph.prototype.updateLayout.call(this);
</span><span class="cx"> 
</span><del>-        var startTime = this.startTime;
-        var currentTime = this.currentTime;
-        var endTime = this.endTime;
-        var duration = (endTime - startTime);
-
</del><span class="cx">         var visibleWidth = this.element.offsetWidth;
</span><del>-        var secondsPerPixel = duration / visibleWidth;
</del><ins>+        var secondsPerPixel = (this.endTime - this.startTime) / visibleWidth;
</ins><span class="cx"> 
</span><del>-        function updateElementPosition(element, newPosition, property)
-        {
-            newPosition *= 100;
-            newPosition = newPosition.toFixed(2);
</del><ins>+        var recordBarIndex = 0;
</ins><span class="cx"> 
</span><del>-            var currentPosition = parseFloat(element.style[property]).toFixed(2);
-            if (currentPosition !== newPosition)
-                element.style[property] = newPosition + &quot;%&quot;;
-        }
-
-        function createBar(barElementCache, rowElement, barStartTime, barEndTime, inactive)
</del><ins>+        function createBar(rowElement, rowRecordBars, records, renderMode)
</ins><span class="cx">         {
</span><del>-            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);
</del><ins>+            var timelineRecordBar = rowRecordBars[recordBarIndex];
+            if (!timelineRecordBar)
+                timelineRecordBar = rowRecordBars[recordBarIndex] = new WebInspector.TimelineRecordBar;
+            timelineRecordBar.renderMode = renderMode;
+            timelineRecordBar.records = records;
+            timelineRecordBar.refresh(this);
+            if (!timelineRecordBar.element.parentNode)
+                rowElement.appendChild(timelineRecordBar.element);
+            ++recordBarIndex;
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         for (var rowRecords of this._timelineRecordGridRows) {
</span><del>-            var rowElement = rowRecords.__rowElement;
-            if (!rowElement) {
-                rowElement = rowRecords.__rowElement = document.createElement(&quot;div&quot;);
-                rowElement.className = WebInspector.NetworkTimelineOverviewGraph.GraphRowStyleClassName;
-                this.element.appendChild(rowElement);
-            }
</del><ins>+            var rowElement = rowRecords.__element;
+            var rowRecordBars = rowRecords.__recordBars;
</ins><span class="cx"> 
</span><del>-            if (!rowRecords.length)
-                continue;
</del><ins>+            recordBarIndex = 0;
</ins><span class="cx"> 
</span><del>-            // Save the current bar elements to reuse.
-            var barElementCache = Array.prototype.slice.call(rowElement.childNodes);
</del><ins>+            WebInspector.TimelineRecordBar.createCombinedBars(rowRecords, secondsPerPixel, this, createBar.bind(this, rowElement, rowRecordBars));
</ins><span class="cx"> 
</span><del>-            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);
</del><ins>+            // Remove the remaining unused TimelineRecordBars.
+            for (; recordBarIndex &lt; rowRecordBars.length; ++recordBarIndex) {
+                rowRecordBars[recordBarIndex].records = null;
+                rowRecordBars[recordBarIndex].element.remove();
</ins><span class="cx">             }
</span><del>-
-            // 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();
</del><span class="cx">         }
</span><span class="cx">     },
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceScriptTimelineOverviewGraphjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/ScriptTimelineOverviewGraph.js (162680 => 162681)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/ScriptTimelineOverviewGraph.js        2014-01-24 03:08:56 UTC (rev 162680)
+++ trunk/Source/WebInspectorUI/UserInterface/ScriptTimelineOverviewGraph.js        2014-01-24 03:41:22 UTC (rev 162681)
</span><span class="lines">@@ -58,51 +58,26 @@
</span><span class="cx">     {
</span><span class="cx">         WebInspector.TimelineOverviewGraph.prototype.updateLayout.call(this);
</span><span class="cx"> 
</span><del>-        var startTime = this.startTime;
-        var currentTime = this.currentTime;
-        var endTime = this.endTime;
-        var duration = (endTime - startTime);
-
</del><span class="cx">         var visibleWidth = this.element.offsetWidth;
</span><del>-        var secondsPerPixel = duration / visibleWidth;
</del><ins>+        var secondsPerPixel = (this.endTime - this.startTime) / visibleWidth;
+
</ins><span class="cx">         var recordBarIndex = 0;
</span><del>-        var barRecords = [];
</del><span class="cx"> 
</span><del>-        function createBar(barRecords)
</del><ins>+        function createBar(records, renderMode)
</ins><span class="cx">         {
</span><span class="cx">             var timelineRecordBar = this._timelineRecordBars[recordBarIndex];
</span><span class="cx">             if (!timelineRecordBar)
</span><span class="cx">                 timelineRecordBar = this._timelineRecordBars[recordBarIndex] = new WebInspector.TimelineRecordBar;
</span><del>-            timelineRecordBar.records = barRecords;
</del><ins>+            timelineRecordBar.renderMode = renderMode;
+            timelineRecordBar.records = records;
</ins><span class="cx">             timelineRecordBar.refresh(this);
</span><span class="cx">             if (!timelineRecordBar.element.parentNode)
</span><span class="cx">                 this.element.appendChild(timelineRecordBar.element);
</span><span class="cx">             ++recordBarIndex;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        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;
</del><ins>+        WebInspector.TimelineRecordBar.createCombinedBars(this._scriptTimeline.records, secondsPerPixel, this, createBar.bind(this));
</ins><span class="cx"> 
</span><del>-            // 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);
-
</del><span class="cx">         // Remove the remaining unused TimelineRecordBars.
</span><span class="cx">         for (; recordBarIndex &lt; this._timelineRecordBars.length; ++recordBarIndex) {
</span><span class="cx">             this._timelineRecordBars[recordBarIndex].records = null;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTimelineDataGridNodejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/TimelineDataGridNode.js (162680 => 162681)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/TimelineDataGridNode.js        2014-01-24 03:08:56 UTC (rev 162680)
+++ trunk/Source/WebInspectorUI/UserInterface/TimelineDataGridNode.js        2014-01-24 03:41:22 UTC (rev 162681)
</span><span class="lines">@@ -242,52 +242,24 @@
</span><span class="cx">         var secondsPerPixel = duration / visibleWidth;
</span><span class="cx">         var recordBarIndex = 0;
</span><span class="cx"> 
</span><del>-        function createBar(barRecords)
</del><ins>+        function createBar(records, renderMode)
</ins><span class="cx">         {
</span><span class="cx">             var timelineRecordBar = this._timelineRecordBars[recordBarIndex];
</span><span class="cx">             if (!timelineRecordBar)
</span><span class="cx">                 timelineRecordBar = this._timelineRecordBars[recordBarIndex] = new WebInspector.TimelineRecordBar;
</span><del>-            timelineRecordBar.records = barRecords;
</del><ins>+            timelineRecordBar.renderMode = renderMode;
+            timelineRecordBar.records = records;
</ins><span class="cx">             timelineRecordBar.refresh(this._graphDataSource);
</span><span class="cx">             if (!timelineRecordBar.element.parentNode)
</span><span class="cx">                 this._graphContainerElement.appendChild(timelineRecordBar.element);
</span><span class="cx">             ++recordBarIndex;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        function createBarsForRecords(records)
-        {
-            var barRecords = [];
</del><ins>+        var boundCreateBar = createBar.bind(this);
</ins><span class="cx"> 
</span><del>-            for (var record of records) {
-                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 = [];
-                }
-
-                barRecords.push(record);
-            }
-
-            // Create the bar for the last record if needed.
-            if (barRecords.length)
-                createBar.call(this, barRecords);
-        }
-
</del><span class="cx">         if (this.expanded) {
</span><span class="cx">             // When expanded just use the records for this node.
</span><del>-            createBarsForRecords.call(this, this.records);
</del><ins>+            WebInspector.TimelineRecordBar.createCombinedBars(this.records, secondsPerPixel, this._graphDataSource, boundCreateBar);
</ins><span class="cx">         } else {
</span><span class="cx">             // When collapsed use the records for this node and its descendants.
</span><span class="cx">             // To share bars better, group records by type.
</span><span class="lines">@@ -317,7 +289,7 @@
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="cx">             for (var records of recordTypeMap.values())
</span><del>-                createBarsForRecords.call(this, records);
</del><ins>+                WebInspector.TimelineRecordBar.createCombinedBars(records, secondsPerPixel, this._graphDataSource, boundCreateBar);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         // Remove the remaining unused TimelineRecordBars.
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTimelineRecordBarcss"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.css (162680 => 162681)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.css        2014-01-24 03:08:56 UTC (rev 162680)
+++ trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.css        2014-01-24 03:41:22 UTC (rev 162681)
</span><span class="lines">@@ -52,10 +52,9 @@
</span><span class="cx">     border-top-right-radius: 0 !important;
</span><span class="cx">     border-bottom-right-radius: 0 !important;
</span><span class="cx">     border-right: none;
</span><del>-    margin-right: -1px;
</del><span class="cx"> }
</span><span class="cx"> 
</span><del>-.timeline-record-bar &gt; .segment.inactive + .segment {
</del><ins>+.timeline-record-bar.has-inactive-segment &gt; .segment:not(.inactive) {
</ins><span class="cx">     border-top-left-radius: 0 !important;
</span><span class="cx">     border-bottom-left-radius: 0 !important;
</span><span class="cx"> }
</span><span class="lines">@@ -66,7 +65,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> :focus .selected .timeline-record-bar &gt; .segment.inactive {
</span><del>-    opacity: 0.7;
</del><ins>+    background-color: rgb(196, 215, 242) !important;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> :focus .selected .timeline-record-bar.has-inactive-segment &gt; .segment:not(.inactive) {
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTimelineRecordBarjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.js (162680 => 162681)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.js        2014-01-24 03:08:56 UTC (rev 162680)
+++ trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.js        2014-01-24 03:41:22 UTC (rev 162681)
</span><span class="lines">@@ -23,17 +23,14 @@
</span><span class="cx">  * THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx">  */
</span><span class="cx"> 
</span><del>-WebInspector.TimelineRecordBar = function(records)
</del><ins>+WebInspector.TimelineRecordBar = function(records, renderMode)
</ins><span class="cx"> {
</span><span class="cx">     WebInspector.Object.call(this);
</span><span class="cx"> 
</span><span class="cx">     this._element = document.createElement(&quot;div&quot;);
</span><span class="cx">     this._element.classList.add(WebInspector.TimelineRecordBar.StyleClassName);
</span><span class="cx"> 
</span><del>-    this._activeBarElement = document.createElement(&quot;div&quot;);
-    this._activeBarElement.classList.add(WebInspector.TimelineRecordBar.BarSegmentStyleClassName);
-    this._element.appendChild(this._activeBarElement);
-
</del><ins>+    this.renderMode = renderMode;
</ins><span class="cx">     this.records = records;
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -47,37 +44,136 @@
</span><span class="cx"> WebInspector.TimelineRecordBar.MinimumWidthPixels = 4;
</span><span class="cx"> WebInspector.TimelineRecordBar.MinimumMarginPixels = 1;
</span><span class="cx"> 
</span><del>-WebInspector.TimelineRecordBar.recordsCannotBeCombined = function(records, candidateRecord, secondsPerPixel)
</del><ins>+WebInspector.TimelineRecordBar.RenderMode = {
+    Normal: &quot;timeline-record-bar-normal-render-mode&quot;,
+    InactiveOnly: &quot;timeline-record-bar-inactive-only-render-mode&quot;,
+    ActiveOnly: &quot;timeline-record-bar-active-only-render-mode&quot;
+};
+
+WebInspector.TimelineRecordBar.createCombinedBars = function(records, secondsPerPixel, graphDataSource, createBarCallback)
</ins><span class="cx"> {
</span><del>-    console.assert(records instanceof Array || records instanceof WebInspector.TimelineRecord);
-    console.assert(candidateRecord instanceof WebInspector.TimelineRecord);
</del><ins>+    if (!records.length)
+        return;
</ins><span class="cx"> 
</span><del>-    if (records instanceof WebInspector.TimelineRecord)
-        records = [records];
</del><ins>+    var startTime = graphDataSource.startTime;
+    var currentTime = graphDataSource.currentTime;
+    var endTime = graphDataSource.endTime;
</ins><span class="cx"> 
</span><del>-    if (!records.length)
-        return true;
</del><ins>+    var visibleRecords = [];
+    var usesActiveStartTime = false;
+    var lastRecordType = null;
</ins><span class="cx"> 
</span><del>-    if (candidateRecord.usesActiveStartTime)
-        return true;
</del><ins>+    // FIXME: Do a binary search for records that fall inside start and current time.
</ins><span class="cx"> 
</span><del>-    var lastRecord = records.lastValue;
-    if (lastRecord.usesActiveStartTime)
-        return true;
</del><ins>+    for (var record of records) {
+        if (isNaN(record.startTime))
+            continue;
</ins><span class="cx"> 
</span><del>-    if (lastRecord.type !== candidateRecord.type)
-        return true;
</del><ins>+        // If this bar is completely before the bounds of the graph, skip this record.
+        if (record.endTime &lt; startTime)
+            continue;
</ins><span class="cx"> 
</span><del>-    if (isNaN(candidateRecord.startTime))
-        return true;
</del><ins>+        // 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;
</ins><span class="cx"> 
</span><del>-    var firstRecord = records[0];
-    var totalDuration = lastRecord.endTime - firstRecord.startTime;
</del><ins>+        if (record.usesActiveStartTime)
+            usesActiveStartTime = true;
</ins><span class="cx"> 
</span><del>-    var minimumMargin = WebInspector.TimelineRecordBar.MinimumMarginPixels * secondsPerPixel;
-    var minimumDuration = WebInspector.TimelineRecordBar.MinimumWidthPixels * secondsPerPixel;
</del><ins>+        // If one record uses active time the rest are assumed to use it.
+        console.assert(record.usesActiveStartTime === usesActiveStartTime);
</ins><span class="cx"> 
</span><del>-    return firstRecord.startTime + Math.max(minimumDuration, totalDuration) + minimumMargin &lt;= candidateRecord.startTime;
</del><ins>+        // Only a single record type is supported right now.
+        console.assert(!lastRecordType || record.type === lastRecordType);
+
+        visibleRecords.push(record);
+
+        lastRecordType = record.type;
+    }
+
+    if (!visibleRecords.length)
+        return;
+
+    if (visibleRecords.length === 1) {
+        createBarCallback(visibleRecords, WebInspector.TimelineRecordBar.RenderMode.Normal);
+        return;
+    }
+
+    function compareByActiveStartTime(a, b)
+    {
+        return a.activeStartTime - b.activeStartTime;
+    }
+
+    var minimumDuration = secondsPerPixel * WebInspector.TimelineRecordBar.MinimumWidthPixels;
+    var minimumMargin = secondsPerPixel * WebInspector.TimelineRecordBar.MinimumMarginPixels;
+
+    if (usesActiveStartTime) {
+        var inactiveStartTime = NaN;
+        var inactiveEndTime = NaN;
+        var inactiveRecords = [];
+
+        for (var record of visibleRecords) {
+            // Check if the previous record is far enough away to create the inactive bar.
+            if (!isNaN(inactiveStartTime) &amp;&amp; inactiveStartTime + Math.max(inactiveEndTime - inactiveStartTime, minimumDuration) + minimumMargin &lt;= record.startTime) {
+                createBarCallback(inactiveRecords, WebInspector.TimelineRecordBar.RenderMode.InactiveOnly);
+                inactiveRecords = [];
+                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);
+
+            inactiveRecords.push(record);
+        }
+
+        // Create the inactive bar for the last record if needed.
+        if (!isNaN(inactiveStartTime))
+            createBarCallback(inactiveRecords, WebInspector.TimelineRecordBar.RenderMode.InactiveOnly);
+
+        visibleRecords.sort(compareByActiveStartTime);
+    }
+
+    lastRecordType = null;
+
+    var activeStartTime = NaN;
+    var activeEndTime = NaN;
+    var activeRecords = [];
+
+    var startTimeProperty = usesActiveStartTime ? &quot;activeStartTime&quot; : &quot;startTime&quot;;
+
+    for (var record of visibleRecords) {
+        // 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; (activeStartTime + Math.max(activeEndTime - activeStartTime, minimumDuration) + minimumMargin &lt;= record[startTimeProperty]
+            || (isNaN(record[startTimeProperty]) &amp;&amp; !isNaN(activeEndTime)))) {
+            createBarCallback(activeRecords, WebInspector.TimelineRecordBar.RenderMode.ActiveOnly);
+            activeRecords = [];
+            activeStartTime = NaN;
+            activeEndTime = NaN;
+        }
+
+        if (isNaN(record[startTimeProperty]))
+            continue;
+
+        // If this is a new bar, peg the start time.
+        if (isNaN(activeStartTime))
+            activeStartTime = record[startTimeProperty];
+
+        // 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);
+
+        activeRecords.push(record);
+    }
+
+    // Create the active bar for the last record if needed.
+    if (!isNaN(activeStartTime))
+        createBarCallback(activeRecords, WebInspector.TimelineRecordBar.RenderMode.ActiveOnly);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> WebInspector.TimelineRecordBar.prototype = {
</span><span class="lines">@@ -91,6 +187,16 @@
</span><span class="cx">         return this._element;
</span><span class="cx">     },
</span><span class="cx"> 
</span><ins>+    get renderMode()
+    {
+        return this._renderMode;
+    },
+
+    set renderMode(renderMode)
+    {
+        this._renderMode = renderMode || WebInspector.TimelineRecordBar.RenderMode.Normal;
+    },
+
</ins><span class="cx">     get records()
</span><span class="cx">     {
</span><span class="cx">         return this._records;
</span><span class="lines">@@ -108,24 +214,6 @@
</span><span class="cx"> 
</span><span class="cx">         this._records = records;
</span><span class="cx"> 
</span><del>-        // 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._element.firstChild);
-            }
-        } else if (this._inactiveBarElement) {
-            this._element.classList.remove(WebInspector.TimelineRecordBar.HasInactiveSegmentStyleClassName);
-            this._inactiveBarElement.remove();
-            delete this._inactiveBarElement;
-        }
-
</del><span class="cx">         // Assume all records are the same type.
</span><span class="cx">         if (this._records.length)
</span><span class="cx">             this._element.classList.add(this._records[0].type);
</span><span class="lines">@@ -134,7 +222,7 @@
</span><span class="cx">     refresh: function(graphDataSource)
</span><span class="cx">     {
</span><span class="cx">         if (!this._records || !this._records.length)
</span><del>-            return;
</del><ins>+            return false;
</ins><span class="cx"> 
</span><span class="cx">         var firstRecord = this._records[0];
</span><span class="cx">         var barStartTime = firstRecord.startTime;
</span><span class="lines">@@ -147,8 +235,7 @@
</span><span class="cx">         var graphEndTime = graphDataSource.endTime;
</span><span class="cx">         var graphCurrentTime = graphDataSource.currentTime;
</span><span class="cx"> 
</span><del>-        var lastRecord = this._records.lastValue;
-        var barEndTime = lastRecord.endTime;
</del><ins>+        var barEndTime = this._records.reduce(function(previousValue, currentValue) { return Math.max(previousValue, currentValue.endTime); }, 0);
</ins><span class="cx"> 
</span><span class="cx">         // If this bar is completely after the current time, return early.
</span><span class="cx">         if (barStartTime &gt; graphCurrentTime)
</span><span class="lines">@@ -172,19 +259,43 @@
</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._inactiveBarElement) {
-            // If this TimelineRecordBar is reused and had an inactive bar previously,
-            // we might need to remove some styles and add the active element back.
</del><ins>+        if (!this._activeBarElement &amp;&amp; this._renderMode !== WebInspector.TimelineRecordBar.RenderMode.InactiveOnly) {
+            this._activeBarElement = document.createElement(&quot;div&quot;);
+            this._activeBarElement.classList.add(WebInspector.TimelineRecordBar.BarSegmentStyleClassName);
+        }
+
+        if (!firstRecord.usesActiveStartTime) {
+            this._element.classList.remove(WebInspector.TimelineRecordBar.HasInactiveSegmentStyleClassName);
+
+            if (this._inactiveBarElement)
+                this._inactiveBarElement.remove();
+
+            if (this._renderMode === WebInspector.TimelineRecordBar.RenderMode.InactiveOnly) {
+                if (this._activeBarElement)
+                    this._activeBarElement.remove();
+
+                return false;
+            }
+
+            // If this TimelineRecordBar is reused and had an inactive bar previously, clean it up.
</ins><span class="cx">             this._activeBarElement.style.removeProperty(&quot;left&quot;);
</span><span class="cx">             this._activeBarElement.style.removeProperty(&quot;width&quot;);
</span><ins>+
</ins><span class="cx">             if (!this._activeBarElement.parentNode)
</span><span class="cx">                 this._element.appendChild(this._activeBarElement);
</span><ins>+
</ins><span class="cx">             return true;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        console.assert(firstRecord === lastRecord);
</del><ins>+        this._element.classList.add(WebInspector.TimelineRecordBar.HasInactiveSegmentStyleClassName);
</ins><span class="cx"> 
</span><del>-        var barActiveStartTime = Math.max(barStartTime, Math.min(firstRecord.activeStartTime, barEndTime));
</del><ins>+        // Find the earliest active start time for active only rendering, and the latest for the other modes.
+        // This matches the values that TimelineRecordBar.createCombinedBars uses when combining.
+        if (this._renderMode === WebInspector.TimelineRecordBar.RenderMode.ActiveOnly)
+            var barActiveStartTime = this._records.reduce(function(previousValue, currentValue) { return Math.min(previousValue, currentValue.activeStartTime); }, Infinity);
+        else
+            var barActiveStartTime = this._records.reduce(function(previousValue, currentValue) { return Math.max(previousValue, currentValue.activeStartTime); }, 0);
+
</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 class="lines">@@ -195,16 +306,27 @@
</span><span class="cx"> 
</span><span class="cx">         var middlePercentage = (barActiveStartTime - barStartTime) / barDuration;
</span><span class="cx"> 
</span><del>-        this._updateElementPosition(this._inactiveBarElement, 1 - middlePercentage, &quot;right&quot;);
-        this._updateElementPosition(this._inactiveBarElement, middlePercentage, &quot;width&quot;);
</del><ins>+        if (this._renderMode !== WebInspector.TimelineRecordBar.RenderMode.ActiveOnly) {
+            if (!this._inactiveBarElement) {
+                this._inactiveBarElement = document.createElement(&quot;div&quot;);
+                this._inactiveBarElement.classList.add(WebInspector.TimelineRecordBar.BarSegmentStyleClassName);
+                this._inactiveBarElement.classList.add(WebInspector.TimelineRecordBar.InactiveStyleClassName);
+            }
</ins><span class="cx"> 
</span><del>-        if (!inactiveUnfinished) {
-            if (!this._activeBarElement.parentNode)
-                this._element.appendChild(this._activeBarElement);
</del><ins>+            this._updateElementPosition(this._inactiveBarElement, 1 - middlePercentage, &quot;right&quot;);
+            this._updateElementPosition(this._inactiveBarElement, middlePercentage, &quot;width&quot;);
</ins><span class="cx"> 
</span><ins>+            if (!this._inactiveBarElement.parentNode)
+                this._element.insertBefore(this._inactiveBarElement, this._element.firstChild);
+        }
+
+        if (!inactiveUnfinished &amp;&amp; this._renderMode !== WebInspector.TimelineRecordBar.RenderMode.InactiveOnly) {
</ins><span class="cx">             this._updateElementPosition(this._activeBarElement, middlePercentage, &quot;left&quot;);
</span><span class="cx">             this._updateElementPosition(this._activeBarElement, 1 - middlePercentage, &quot;width&quot;);
</span><del>-        } else
</del><ins>+
+            if (!this._activeBarElement.parentNode)
+                this._element.appendChild(this._activeBarElement);
+        } else if (this._activeBarElement)
</ins><span class="cx">             this._activeBarElement.remove();
</span><span class="cx"> 
</span><span class="cx">         return true;
</span></span></pre>
</div>
</div>

</body>
</html>