<!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 > .graph-row > .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 > .segment):
(.timeline-record-bar.has-inactive-segment > .segment:not(.inactive)):
(:focus .selected .timeline-record-bar > .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 <timothy@apple.com>
+
+ 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 > .graph-row > .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 > .segment):
+ (.timeline-record-bar.has-inactive-segment > .segment:not(.inactive)):
+ (:focus .selected .timeline-record-bar > .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 <timothy@apple.com>
</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 < 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 > currentTime || record.startTime > endTime)
- break;
-
- // Check if the previous record is a different type or far enough away to create the bar.
- if (barRecords.length && 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 < 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 > .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 > .graph-row > .bar {
- position: absolute;
</del><ins>+.timeline-overview-graph.network > .graph-row > .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 > .graph-row > .bar.inactive {
- background-color: rgb(167, 204, 237);
- border-color: rgb(127, 185, 220);
-}
-
-.timeline-overview-graph.network > .graph-row > .bar.inactive,
-.timeline-overview-graph.network > .graph-row > .bar.unfinished {
- border-top-right-radius: 0;
- border-bottom-right-radius: 0;
- border-right: none;
-}
-
-.timeline-overview-graph.network > .graph-row > .bar:not(.inactive) {
- border-top-left-radius: 0;
- border-bottom-left-radius: 0;
- z-index: 1;
</del><ins>+.timeline-overview-graph.network > .graph-row > .timeline-record-bar > .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) > .graph-row > .bar:not(.inactive) {
</del><ins>+.timeline-overview-graph.network:nth-child(even) > .graph-row > .timeline-record-bar > .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 = "inactive";
</span><span class="cx"> WebInspector.NetworkTimelineOverviewGraph.UnfinishedStyleClassName = "unfinished";
</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("div");
+ 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 + "%";
- }
-
- function createBar(barElementCache, rowElement, barStartTime, barEndTime, inactive)
</del><ins>+ function createBar(rowElement, rowRecordBars, records, renderMode)
</ins><span class="cx"> {
</span><del>- if (barStartTime > currentTime)
- return;
-
- var barElement = barElementCache.shift();
- if (!barElement) {
- barElement = document.createElement("div");
- barElement.classList.add(WebInspector.NetworkTimelineOverviewGraph.BarStyleClassName);
- }
-
- barElement.classList.toggle(WebInspector.NetworkTimelineOverviewGraph.InactiveBarStyleClassName, inactive);
-
- if (barEndTime >= 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, "right");
- barElement.style.removeProperty("left");
- } else {
- var newBarLeftPosition = (barStartTime - startTime) / duration;
- updateElementPosition(barElement, newBarLeftPosition, "left");
- barElement.style.removeProperty("right");
- }
-
- var newBarWidth = ((barEndTime - barStartTime) / duration);
- updateElementPosition(barElement, newBarWidth, "width");
-
- 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("div");
- 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 < startTime)
- continue;
-
- // If this record is completely after the current time or end time, break out now.
- // Records are sorted, so all records after this will be beyond the current or end time too.
- if (record.startTime > currentTime || record.startTime > endTime)
- break;
-
- // Check if the previous record is far enough away to create the inactive bar.
- if (!isNaN(inactiveStartTime) && inactiveEndTime + (secondsPerPixel * WebInspector.NetworkTimelineOverviewGraph.MinimumBarPaddingPixels) <= 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 "|| 0" 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) && (activeEndTime + (secondsPerPixel * WebInspector.NetworkTimelineOverviewGraph.MinimumBarPaddingPixels) <= 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 "|| 0" 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 < 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 < 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 > currentTime || record.startTime > endTime)
- break;
-
- // Check if the previous record is a different type or far enough away to create the bar.
- if (barRecords.length && 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 < 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 < startTime)
- continue;
-
- // If this record is completely after the current time or end time, break out now.
- // Records are sorted, so all records after this will be beyond the current or end time too.
- if (record.startTime > currentTime || record.startTime > endTime)
- break;
-
- // Check if the previous record can be combined with the current record, if not make a new bar.
- if (barRecords.length && 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 > .segment.inactive + .segment {
</del><ins>+.timeline-record-bar.has-inactive-segment > .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 > .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 > .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("div");
</span><span class="cx"> this._element.classList.add(WebInspector.TimelineRecordBar.StyleClassName);
</span><span class="cx">
</span><del>- this._activeBarElement = document.createElement("div");
- 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: "timeline-record-bar-normal-render-mode",
+ InactiveOnly: "timeline-record-bar-inactive-only-render-mode",
+ ActiveOnly: "timeline-record-bar-active-only-render-mode"
+};
+
+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 < 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 > currentTime || record.startTime > 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 <= 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) && inactiveStartTime + Math.max(inactiveEndTime - inactiveStartTime, minimumDuration) + minimumMargin <= 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 "|| 0" 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 ? "activeStartTime" : "startTime";
+
+ 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) && (activeStartTime + Math.max(activeEndTime - activeStartTime, minimumDuration) + minimumMargin <= record[startTimeProperty]
+ || (isNaN(record[startTimeProperty]) && !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 "|| 0" to prevent Math.max from returning NaN.
+ if (!isNaN(record.endTime))
+ activeEndTime = Math.max(activeEndTime || 0, record.endTime);
+
+ activeRecords.push(record);
+ }
+
+ // Create the active 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 <= 1 || !this._records[0].usesActiveStartTime);
-
- // Inactive time is only supported with one record.
- if (this._records.length === 1 && this._records[0].usesActiveStartTime) {
- if (!this._inactiveBarElement) {
- this._inactiveBarElement = document.createElement("div");
- 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 > 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, "width");
</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 && this._renderMode !== WebInspector.TimelineRecordBar.RenderMode.InactiveOnly) {
+ this._activeBarElement = document.createElement("div");
+ 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("left");
</span><span class="cx"> this._activeBarElement.style.removeProperty("width");
</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 >= 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, "right");
- this._updateElementPosition(this._inactiveBarElement, middlePercentage, "width");
</del><ins>+ if (this._renderMode !== WebInspector.TimelineRecordBar.RenderMode.ActiveOnly) {
+ if (!this._inactiveBarElement) {
+ this._inactiveBarElement = document.createElement("div");
+ 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, "right");
+ this._updateElementPosition(this._inactiveBarElement, middlePercentage, "width");
</ins><span class="cx">
</span><ins>+ if (!this._inactiveBarElement.parentNode)
+ this._element.insertBefore(this._inactiveBarElement, this._element.firstChild);
+ }
+
+ if (!inactiveUnfinished && this._renderMode !== WebInspector.TimelineRecordBar.RenderMode.InactiveOnly) {
</ins><span class="cx"> this._updateElementPosition(this._activeBarElement, middlePercentage, "left");
</span><span class="cx"> this._updateElementPosition(this._activeBarElement, 1 - middlePercentage, "width");
</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>