<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[162419] trunk/Source/WebInspectorUI</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/162419">162419</a></dd>
<dt>Author</dt> <dd>timothy@apple.com</dd>
<dt>Date</dt> <dd>2014-01-20 18:56:29 -0800 (Mon, 20 Jan 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>Implement basic versions of the TimelineOverview graphs.
https://bugs.webkit.org/show_bug.cgi?id=127184
Reviewed by Joseph Pecoraro.
* UserInterface/LayoutTimelineOverviewGraph.css: Added.
(.timeline-overview-graph.layout > .timeline-record-bar):
(.timeline-overview-graph.layout > .timeline-record-bar > .segment):
* UserInterface/LayoutTimelineOverviewGraph.js: Added.
(WebInspector.LayoutTimelineOverviewGraph.prototype.reset):
(WebInspector.LayoutTimelineOverviewGraph.prototype.updateLayout):
(WebInspector.LayoutTimelineOverviewGraph.prototype._layoutTimelineRecordAdded):
* UserInterface/Main.html: Added new files.
* UserInterface/NetworkTimelineOverviewGraph.css: Added.
(.timeline-overview-graph.network):
(.timeline-overview-graph.network > .graph-row):
(.timeline-overview-graph.network > .graph-row > .bar):
(.timeline-overview-graph.network > .graph-row > .bar.inactive):
(.timeline-overview-graph.network > .graph-row > .bar.unfinished):
(.timeline-overview-graph.network > .graph-row > .bar:not(.inactive)):
(.timeline-overview-graph.network:nth-child(even) > .graph-row > .bar:not(.inactive)):
* UserInterface/NetworkTimelineOverviewGraph.js: Added.
(WebInspector.NetworkTimelineOverviewGraph.prototype.reset):
(WebInspector.NetworkTimelineOverviewGraph.prototype.updateLayout.updateElementPosition):
(WebInspector.NetworkTimelineOverviewGraph.prototype.updateLayout.createBar):
(WebInspector.NetworkTimelineOverviewGraph.prototype.updateLayout):
(WebInspector.NetworkTimelineOverviewGraph.prototype._networkTimelineRecordAdded.compareByStartTime):
(WebInspector.NetworkTimelineOverviewGraph.prototype._networkTimelineRecordAdded.insertObjectIntoSortedArray):
(WebInspector.NetworkTimelineOverviewGraph.prototype._networkTimelineRecordAdded):
* UserInterface/ScriptTimelineOverviewGraph.css: Added.
(.timeline-overview-graph.script > .timeline-record-bar):
(.timeline-overview-graph.script > .timeline-record-bar > .segment):
* UserInterface/ScriptTimelineOverviewGraph.js: Added.
(WebInspector.ScriptTimelineOverviewGraph.prototype.reset):
(WebInspector.ScriptTimelineOverviewGraph.prototype.updateLayout):
(WebInspector.ScriptTimelineOverviewGraph.prototype._scriptTimelineRecordAdded):
* UserInterface/TimelineContentView.js:
(WebInspector.TimelineContentView.prototype._showTimelineView):
(WebInspector.TimelineContentView.prototype._update):
(WebInspector.TimelineContentView.prototype._recordingReset):
Create and keep the graphs informed.
* UserInterface/TimelineDataGridNode.js:
(WebInspector.TimelineDataGridNode):
(WebInspector.TimelineDataGridNode.prototype.refreshGraph):
Combine records that might overlap.
* UserInterface/TimelineOverview.css:
(.timeline-overview > .graphs-container):
(.timeline-overview > .graphs-container > .timeline-overview-graph):
(.timeline-overview > .graphs-container > .timeline-overview-graph:nth-child(even)):
(.timeline-overview > .graphs-container > .timeline-overview-graph:not(:first-child)):
Add the graph rows with alternating stripe.
* UserInterface/TimelineOverview.js:
(WebInspector.TimelineOverview):
(WebInspector.TimelineOverview.prototype.set startTime):
(WebInspector.TimelineOverview.prototype.get currentTime):
(WebInspector.TimelineOverview.prototype.set currentTime):
(WebInspector.TimelineOverview.prototype.updateLayout):
(WebInspector.TimelineOverview.prototype.updateLayoutIfNeeded):
Track currentTime in a member variable and let TimelineOverview manage the current time marker.
* UserInterface/TimelineOverviewGraph.js: Added.
(WebInspector.TimelineOverviewGraph):
(WebInspector.TimelineOverviewGraph.prototype.get zeroTime):
(WebInspector.TimelineOverviewGraph.prototype.set zeroTime):
(WebInspector.TimelineOverviewGraph.prototype.get startTime):
(WebInspector.TimelineOverviewGraph.prototype.set startTime):
(WebInspector.TimelineOverviewGraph.prototype.get endTime):
(WebInspector.TimelineOverviewGraph.prototype.set endTime):
(WebInspector.TimelineOverviewGraph.prototype.get currentTime):
(WebInspector.TimelineOverviewGraph.prototype.set currentTime):
(WebInspector.TimelineOverviewGraph.prototype.reset):
(WebInspector.TimelineOverviewGraph.prototype.updateLayout):
(WebInspector.TimelineOverviewGraph.prototype.updateLayoutIfNeeded):
(WebInspector.TimelineOverviewGraph.prototype.needsLayout):
* UserInterface/TimelineRecordBar.css:
(.timeline-record-bar > .segment):
(.timeline-record-bar.unfinished > .segment):
(.timeline-record-bar > .segment.inactive + .segment):
(.timeline-record-bar.timeline-record-type-network > .segment.inactive):
* UserInterface/TimelineRecordBar.js:
(WebInspector.TimelineRecordBar):
(WebInspector.TimelineRecordBar.recordsCannotBeCombined):
(WebInspector.TimelineRecordBar.prototype.get records):
(WebInspector.TimelineRecordBar.prototype.set records):
(WebInspector.TimelineRecordBar.prototype.refresh):
Make TimelineRecordBar support multiple records.
* UserInterface/TimelineRuler.css:
(.timeline-ruler > .markers):
(.timeline-ruler > .selection-handle):
(.timeline-ruler > .shaded-area):
Add some z-index values to stay above graph elements.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceBinarySearchjs">trunk/Source/WebInspectorUI/UserInterface/BinarySearch.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceMainhtml">trunk/Source/WebInspectorUI/UserInterface/Main.html</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTimelineContentViewjs">trunk/Source/WebInspectorUI/UserInterface/TimelineContentView.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTimelineDataGridNodejs">trunk/Source/WebInspectorUI/UserInterface/TimelineDataGridNode.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTimelineOverviewcss">trunk/Source/WebInspectorUI/UserInterface/TimelineOverview.css</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTimelineOverviewjs">trunk/Source/WebInspectorUI/UserInterface/TimelineOverview.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTimelineRecordBarcss">trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.css</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTimelineRecordBarjs">trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTimelineRulercss">trunk/Source/WebInspectorUI/UserInterface/TimelineRuler.css</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceLayoutTimelineOverviewGraphcss">trunk/Source/WebInspectorUI/UserInterface/LayoutTimelineOverviewGraph.css</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceLayoutTimelineOverviewGraphjs">trunk/Source/WebInspectorUI/UserInterface/LayoutTimelineOverviewGraph.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceNetworkTimelineOverviewGraphcss">trunk/Source/WebInspectorUI/UserInterface/NetworkTimelineOverviewGraph.css</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceNetworkTimelineOverviewGraphjs">trunk/Source/WebInspectorUI/UserInterface/NetworkTimelineOverviewGraph.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceScriptTimelineOverviewGraphcss">trunk/Source/WebInspectorUI/UserInterface/ScriptTimelineOverviewGraph.css</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceScriptTimelineOverviewGraphjs">trunk/Source/WebInspectorUI/UserInterface/ScriptTimelineOverviewGraph.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTimelineOverviewGraphjs">trunk/Source/WebInspectorUI/UserInterface/TimelineOverviewGraph.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (162418 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2014-01-21 02:56:17 UTC (rev 162418)
+++ trunk/Source/WebInspectorUI/ChangeLog        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -1,3 +1,111 @@
</span><ins>+2014-01-19 Timothy Hatcher <timothy@apple.com>
+
+ Implement basic versions of the TimelineOverview graphs.
+
+ https://bugs.webkit.org/show_bug.cgi?id=127184
+
+ Reviewed by Joseph Pecoraro.
+
+ * UserInterface/LayoutTimelineOverviewGraph.css: Added.
+ (.timeline-overview-graph.layout > .timeline-record-bar):
+ (.timeline-overview-graph.layout > .timeline-record-bar > .segment):
+
+ * UserInterface/LayoutTimelineOverviewGraph.js: Added.
+ (WebInspector.LayoutTimelineOverviewGraph.prototype.reset):
+ (WebInspector.LayoutTimelineOverviewGraph.prototype.updateLayout):
+ (WebInspector.LayoutTimelineOverviewGraph.prototype._layoutTimelineRecordAdded):
+
+ * UserInterface/Main.html: Added new files.
+
+ * UserInterface/NetworkTimelineOverviewGraph.css: Added.
+ (.timeline-overview-graph.network):
+ (.timeline-overview-graph.network > .graph-row):
+ (.timeline-overview-graph.network > .graph-row > .bar):
+ (.timeline-overview-graph.network > .graph-row > .bar.inactive):
+ (.timeline-overview-graph.network > .graph-row > .bar.unfinished):
+ (.timeline-overview-graph.network > .graph-row > .bar:not(.inactive)):
+ (.timeline-overview-graph.network:nth-child(even) > .graph-row > .bar:not(.inactive)):
+
+ * UserInterface/NetworkTimelineOverviewGraph.js: Added.
+ (WebInspector.NetworkTimelineOverviewGraph.prototype.reset):
+ (WebInspector.NetworkTimelineOverviewGraph.prototype.updateLayout.updateElementPosition):
+ (WebInspector.NetworkTimelineOverviewGraph.prototype.updateLayout.createBar):
+ (WebInspector.NetworkTimelineOverviewGraph.prototype.updateLayout):
+ (WebInspector.NetworkTimelineOverviewGraph.prototype._networkTimelineRecordAdded.compareByStartTime):
+ (WebInspector.NetworkTimelineOverviewGraph.prototype._networkTimelineRecordAdded.insertObjectIntoSortedArray):
+ (WebInspector.NetworkTimelineOverviewGraph.prototype._networkTimelineRecordAdded):
+
+ * UserInterface/ScriptTimelineOverviewGraph.css: Added.
+ (.timeline-overview-graph.script > .timeline-record-bar):
+ (.timeline-overview-graph.script > .timeline-record-bar > .segment):
+
+ * UserInterface/ScriptTimelineOverviewGraph.js: Added.
+ (WebInspector.ScriptTimelineOverviewGraph.prototype.reset):
+ (WebInspector.ScriptTimelineOverviewGraph.prototype.updateLayout):
+ (WebInspector.ScriptTimelineOverviewGraph.prototype._scriptTimelineRecordAdded):
+
+ * UserInterface/TimelineContentView.js:
+ (WebInspector.TimelineContentView.prototype._showTimelineView):
+ (WebInspector.TimelineContentView.prototype._update):
+ (WebInspector.TimelineContentView.prototype._recordingReset):
+ Create and keep the graphs informed.
+
+ * UserInterface/TimelineDataGridNode.js:
+ (WebInspector.TimelineDataGridNode):
+ (WebInspector.TimelineDataGridNode.prototype.refreshGraph):
+ Combine records that might overlap.
+
+ * UserInterface/TimelineOverview.css:
+ (.timeline-overview > .graphs-container):
+ (.timeline-overview > .graphs-container > .timeline-overview-graph):
+ (.timeline-overview > .graphs-container > .timeline-overview-graph:nth-child(even)):
+ (.timeline-overview > .graphs-container > .timeline-overview-graph:not(:first-child)):
+ Add the graph rows with alternating stripe.
+
+ * UserInterface/TimelineOverview.js:
+ (WebInspector.TimelineOverview):
+ (WebInspector.TimelineOverview.prototype.set startTime):
+ (WebInspector.TimelineOverview.prototype.get currentTime):
+ (WebInspector.TimelineOverview.prototype.set currentTime):
+ (WebInspector.TimelineOverview.prototype.updateLayout):
+ (WebInspector.TimelineOverview.prototype.updateLayoutIfNeeded):
+ Track currentTime in a member variable and let TimelineOverview manage the current time marker.
+
+ * UserInterface/TimelineOverviewGraph.js: Added.
+ (WebInspector.TimelineOverviewGraph):
+ (WebInspector.TimelineOverviewGraph.prototype.get zeroTime):
+ (WebInspector.TimelineOverviewGraph.prototype.set zeroTime):
+ (WebInspector.TimelineOverviewGraph.prototype.get startTime):
+ (WebInspector.TimelineOverviewGraph.prototype.set startTime):
+ (WebInspector.TimelineOverviewGraph.prototype.get endTime):
+ (WebInspector.TimelineOverviewGraph.prototype.set endTime):
+ (WebInspector.TimelineOverviewGraph.prototype.get currentTime):
+ (WebInspector.TimelineOverviewGraph.prototype.set currentTime):
+ (WebInspector.TimelineOverviewGraph.prototype.reset):
+ (WebInspector.TimelineOverviewGraph.prototype.updateLayout):
+ (WebInspector.TimelineOverviewGraph.prototype.updateLayoutIfNeeded):
+ (WebInspector.TimelineOverviewGraph.prototype.needsLayout):
+
+ * UserInterface/TimelineRecordBar.css:
+ (.timeline-record-bar > .segment):
+ (.timeline-record-bar.unfinished > .segment):
+ (.timeline-record-bar > .segment.inactive + .segment):
+ (.timeline-record-bar.timeline-record-type-network > .segment.inactive):
+
+ * UserInterface/TimelineRecordBar.js:
+ (WebInspector.TimelineRecordBar):
+ (WebInspector.TimelineRecordBar.recordsCannotBeCombined):
+ (WebInspector.TimelineRecordBar.prototype.get records):
+ (WebInspector.TimelineRecordBar.prototype.set records):
+ (WebInspector.TimelineRecordBar.prototype.refresh):
+ Make TimelineRecordBar support multiple records.
+
+ * UserInterface/TimelineRuler.css:
+ (.timeline-ruler > .markers):
+ (.timeline-ruler > .selection-handle):
+ (.timeline-ruler > .shaded-area):
+ Add some z-index values to stay above graph elements.
+
</ins><span class="cx"> 2014-01-16 Timothy Hatcher <timothy@apple.com>
</span><span class="cx">
</span><span class="cx"> Clean up Timelines code by using ES6 features and less global access of TimelineRecording.
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceBinarySearchjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/BinarySearch.js (162418 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/BinarySearch.js        2014-01-21 02:56:17 UTC (rev 162418)
+++ trunk/Source/WebInspectorUI/UserInterface/BinarySearch.js        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -78,3 +78,8 @@
</span><span class="cx"> return index;
</span><span class="cx"> }
</span><span class="cx"> }
</span><ins>+
+function insertObjectIntoSortedArray(value, array, compareFunction)
+{
+ array.splice(insertionIndexForObjectInListSortedByFunction(value, array, compareFunction), 0, value);
+}
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceLayoutTimelineOverviewGraphcssfromrev162418trunkSourceWebInspectorUIUserInterfaceTimelineOverviewcss"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebInspectorUI/UserInterface/LayoutTimelineOverviewGraph.css (from rev 162418, trunk/Source/WebInspectorUI/UserInterface/TimelineOverview.css) (0 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/LayoutTimelineOverviewGraph.css         (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/LayoutTimelineOverviewGraph.css        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -0,0 +1,33 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+.timeline-overview-graph.layout > .timeline-record-bar {
+ margin-top: 8px;
+ height: 20px;
+}
+
+.timeline-overview-graph.layout > .timeline-record-bar > .segment {
+ border-radius: 2px;
+}
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceLayoutTimelineOverviewGraphjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/LayoutTimelineOverviewGraph.js (0 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/LayoutTimelineOverviewGraph.js         (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/LayoutTimelineOverviewGraph.js        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -0,0 +1,119 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.LayoutTimelineOverviewGraph = function(recording)
+{
+ WebInspector.TimelineOverviewGraph.call(this, recording);
+
+ this.element.classList.add(WebInspector.LayoutTimelineOverviewGraph.StyleClassName);
+
+ this._layoutTimeline = recording.timelines.get(WebInspector.TimelineRecord.Type.Layout);
+ this._layoutTimeline.addEventListener(WebInspector.Timeline.Event.RecordAdded, this._layoutTimelineRecordAdded, this);
+
+ this._timelineRecordBars = [];
+
+ this.reset();
+};
+
+WebInspector.LayoutTimelineOverviewGraph.StyleClassName = "layout";
+
+WebInspector.LayoutTimelineOverviewGraph.prototype = {
+ constructor: WebInspector.LayoutTimelineOverviewGraph,
+ __proto__: WebInspector.TimelineOverviewGraph.prototype,
+
+ // Public
+
+ reset: function()
+ {
+ WebInspector.TimelineOverviewGraph.prototype.reset.call(this);
+
+ this._timelineRecordBarMap = new Map;
+
+ this.element.removeChildren();
+ },
+
+ updateLayout: function()
+ {
+ WebInspector.TimelineOverviewGraph.prototype.updateLayout.call(this);
+
+ var startTime = this.startTime;
+ var currentTime = this.currentTime;
+ var endTime = this.endTime;
+ var duration = (endTime - startTime);
+
+ var visibleWidth = this.element.offsetWidth;
+ var secondsPerPixel = duration / visibleWidth;
+ var recordBarIndex = 0;
+ var barRecords = [];
+
+ function createBar(barRecords)
+ {
+ var timelineRecordBar = this._timelineRecordBars[recordBarIndex];
+ if (!timelineRecordBar)
+ timelineRecordBar = this._timelineRecordBars[recordBarIndex] = new WebInspector.TimelineRecordBar;
+ timelineRecordBar.records = barRecords;
+ timelineRecordBar.refresh(this);
+ if (!timelineRecordBar.element.parentNode)
+ this.element.appendChild(timelineRecordBar.element);
+ ++recordBarIndex;
+ }
+
+ for (var record of this._layoutTimeline.records) {
+ // If this bar is completely before the bounds of the graph, skip this record.
+ if (record.endTime < 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 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);
+
+ // Remove the remaining unused TimelineRecordBars.
+ for (; recordBarIndex < this._timelineRecordBars.length; ++recordBarIndex) {
+ this._timelineRecordBars[recordBarIndex].records = null;
+ this._timelineRecordBars[recordBarIndex].element.remove();
+ }
+ },
+
+ // Private
+
+ _layoutTimelineRecordAdded: function(event)
+ {
+ this.needsLayout();
+ }
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceMainhtml"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (162418 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Main.html        2014-01-21 02:56:17 UTC (rev 162418)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -92,6 +92,9 @@
</span><span class="cx"> <link rel="stylesheet" href="TimelineDataGrid.css">
</span><span class="cx"> <link rel="stylesheet" href="TimelineRecordBar.css">
</span><span class="cx"> <link rel="stylesheet" href="TimelineOverview.css">
</span><ins>+ <link rel="stylesheet" href="NetworkTimelineOverviewGraph.css">
+ <link rel="stylesheet" href="LayoutTimelineOverviewGraph.css">
+ <link rel="stylesheet" href="ScriptTimelineOverviewGraph.css">
</ins><span class="cx"> <link rel="stylesheet" href="ProfileView.css">
</span><span class="cx"> <link rel="stylesheet" href="JavaScriptProfileView.css">
</span><span class="cx"> <link rel="stylesheet" href="CSSStyleDetailsSidebarPanel.css">
</span><span class="lines">@@ -367,6 +370,10 @@
</span><span class="cx"> <script src="SourceCodeTimelineTimelineDataGridNode.js"></script>
</span><span class="cx"> <script src="TreeOutlineDataGridSynchronizer.js"></script>
</span><span class="cx"> <script src="TimelineOverview.js"></script>
</span><ins>+ <script src="TimelineOverviewGraph.js"></script>
+ <script src="NetworkTimelineOverviewGraph.js"></script>
+ <script src="LayoutTimelineOverviewGraph.js"></script>
+ <script src="ScriptTimelineOverviewGraph.js"></script>
</ins><span class="cx"> <script src="ProfileManager.js"></script>
</span><span class="cx"> <script src="ProfileType.js"></script>
</span><span class="cx"> <script src="ProfileView.js"></script>
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceNetworkTimelineOverviewGraphcssfromrev162418trunkSourceWebInspectorUIUserInterfaceTimelineRecordBarcss"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebInspectorUI/UserInterface/NetworkTimelineOverviewGraph.css (from rev 162418, trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.css) (0 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/NetworkTimelineOverviewGraph.css         (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/NetworkTimelineOverviewGraph.css        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -0,0 +1,66 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+.timeline-overview-graph.network {
+ padding-top: 2px
+}
+
+.timeline-overview-graph.network > .graph-row {
+ position: relative;
+ height: 5px;
+}
+
+.timeline-overview-graph.network > .graph-row > .bar {
+ position: absolute;
+ height: 4px;
+ background-color: rgb(120, 176, 225);
+ border: 1px solid rgb(61, 147, 200);
+ border-radius: 2px;
+ margin-top: 1px;
+ min-width: 3px;
+}
+
+.timeline-overview-graph.network > .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;
+ box-shadow: white 1px 0 0;
+}
+
+.timeline-overview-graph.network:nth-child(even) > .graph-row > .bar:not(.inactive) {
+ box-shadow: rgb(247, 247, 247) 1px 0 0;
+}
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceNetworkTimelineOverviewGraphjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/NetworkTimelineOverviewGraph.js (0 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/NetworkTimelineOverviewGraph.js         (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/NetworkTimelineOverviewGraph.js        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -0,0 +1,257 @@
</span><ins>+
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.NetworkTimelineOverviewGraph = function(recording)
+{
+ WebInspector.TimelineOverviewGraph.call(this, recording);
+
+ this.element.classList.add(WebInspector.NetworkTimelineOverviewGraph.StyleClassName);
+
+ var networkTimeline = recording.timelines.get(WebInspector.TimelineRecord.Type.Network);
+ networkTimeline.addEventListener(WebInspector.Timeline.Event.RecordAdded, this._networkTimelineRecordAdded, this);
+ networkTimeline.addEventListener(WebInspector.Timeline.Event.TimesUpdated, this.needsLayout, this);
+
+ this.reset();
+};
+
+WebInspector.NetworkTimelineOverviewGraph.StyleClassName = "network";
+WebInspector.NetworkTimelineOverviewGraph.GraphRowStyleClassName = "graph-row";
+WebInspector.NetworkTimelineOverviewGraph.BarStyleClassName = "bar";
+WebInspector.NetworkTimelineOverviewGraph.InactiveBarStyleClassName = "inactive";
+WebInspector.NetworkTimelineOverviewGraph.UnfinishedStyleClassName = "unfinished";
+WebInspector.NetworkTimelineOverviewGraph.MaximumRowCount = 6;
+WebInspector.NetworkTimelineOverviewGraph.MinimumBarPaddingPixels = 5;
+
+WebInspector.NetworkTimelineOverviewGraph.prototype = {
+ constructor: WebInspector.NetworkTimelineOverviewGraph,
+ __proto__: WebInspector.TimelineOverviewGraph.prototype,
+
+ // Public
+
+ reset: function()
+ {
+ WebInspector.TimelineOverviewGraph.prototype.reset.call(this);
+
+ this._nextDumpRow = 0;
+ this._timelineRecordGridRows = [];
+
+ for (var i = 0; i < WebInspector.NetworkTimelineOverviewGraph.MaximumRowCount; ++i)
+ this._timelineRecordGridRows.push([]);
+
+ this.element.removeChildren();
+ },
+
+ updateLayout: function()
+ {
+ WebInspector.TimelineOverviewGraph.prototype.updateLayout.call(this);
+
+ var startTime = this.startTime;
+ var currentTime = this.currentTime;
+ var endTime = this.endTime;
+ var duration = (endTime - startTime);
+
+ var visibleWidth = this.element.offsetWidth;
+ var secondsPerPixel = duration / visibleWidth;
+
+ function updateElementPosition(element, newPosition, property)
+ {
+ newPosition *= 100;
+ newPosition = newPosition.toFixed(2);
+
+ var currentPosition = parseFloat(element.style[property]).toFixed(2);
+ if (currentPosition !== newPosition)
+ element.style[property] = newPosition + "%";
+ }
+
+ function createBar(barElementCache, rowElement, barStartTime, barEndTime, inactive)
+ {
+ 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);
+ }
+
+ for (var rowRecords of this._timelineRecordGridRows) {
+ var rowElement = rowRecords.__rowElement;
+ if (!rowElement) {
+ rowElement = rowRecords.__rowElement = document.createElement("div");
+ rowElement.className = WebInspector.NetworkTimelineOverviewGraph.GraphRowStyleClassName;
+ this.element.appendChild(rowElement);
+ }
+
+ if (!rowRecords.length)
+ continue;
+
+ // Save the current bar elements to reuse.
+ var barElementCache = Array.prototype.slice.call(rowElement.childNodes);
+
+ var inactiveStartTime = NaN;
+ var inactiveEndTime = NaN;
+ var activeStartTime = NaN;
+ var activeEndTime = NaN;
+
+ for (var record of rowRecords) {
+ if (isNaN(record.startTime))
+ continue;
+
+ // If this bar is completely before the bounds of the graph, skip this record.
+ if (record.endTime < 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);
+ }
+
+ // Create the inactive bar for the last record if needed.
+ if (!isNaN(inactiveStartTime))
+ createBar.call(this, barElementCache, rowElement, inactiveStartTime, inactiveEndTime || currentTime, true);
+
+ // Create the active bar for the last record if needed.
+ if (!isNaN(activeStartTime))
+ createBar.call(this, barElementCache, rowElement, activeStartTime, activeEndTime || currentTime);
+
+ // Remove any unused bar elements.
+ for (var barElement of barElementCache)
+ barElement.remove();
+ }
+ },
+
+ // Private
+
+ _networkTimelineRecordAdded: function(event)
+ {
+ var resourceTimelineRecord = event.data.record;
+ console.assert(resourceTimelineRecord instanceof WebInspector.ResourceTimelineRecord);
+
+ function compareByStartTime(a, b)
+ {
+ return a.startTime - b.startTime;
+ }
+
+ // Try to find a row that has room and does not overlap a previous record.
+ var foundRowForRecord = false;
+ for (var i = 0; i < this._timelineRecordGridRows.length; ++i) {
+ var rowRecords = this._timelineRecordGridRows[i];
+ var lastRecord = rowRecords.lastValue;
+
+ if (!lastRecord || lastRecord.endTime + WebInspector.NetworkTimelineOverviewGraph.MinimumBarPaddingTime <= resourceTimelineRecord.startTime) {
+ insertObjectIntoSortedArray(resourceTimelineRecord, rowRecords, compareByStartTime);
+ this._nextDumpRow = i + 1;
+ foundRowForRecord = true;
+ break;
+ }
+ }
+
+ if (!foundRowForRecord) {
+ // Try to find a row that does not overlap a previous record's active time, but it can overlap the inactive time.
+ for (var i = 0; i < this._timelineRecordGridRows.length; ++i) {
+ var rowRecords = this._timelineRecordGridRows[i];
+ var lastRecord = rowRecords.lastValue;
+ console.assert(lastRecord);
+
+ if (lastRecord.activeStartTime + WebInspector.NetworkTimelineOverviewGraph.MinimumBarPaddingTime <= resourceTimelineRecord.startTime) {
+ insertObjectIntoSortedArray(resourceTimelineRecord, rowRecords, compareByStartTime);
+ this._nextDumpRow = i + 1;
+ foundRowForRecord = true;
+ break;
+ }
+ }
+ }
+
+ // We didn't find a empty spot, so dump into the designated dump row.
+ if (!foundRowForRecord) {
+ if (this._nextDumpRow >= WebInspector.NetworkTimelineOverviewGraph.MaximumRowCount)
+ this._nextDumpRow = 0;
+ insertObjectIntoSortedArray(resourceTimelineRecord, this._timelineRecordGridRows[this._nextDumpRow++], compareByStartTime);
+ }
+
+ this.needsLayout();
+ }
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceScriptTimelineOverviewGraphcssfromrev162418trunkSourceWebInspectorUIUserInterfaceTimelineOverviewcss"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebInspectorUI/UserInterface/ScriptTimelineOverviewGraph.css (from rev 162418, trunk/Source/WebInspectorUI/UserInterface/TimelineOverview.css) (0 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/ScriptTimelineOverviewGraph.css         (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/ScriptTimelineOverviewGraph.css        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -0,0 +1,33 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+.timeline-overview-graph.script > .timeline-record-bar {
+ margin-top: 8px;
+ height: 20px;
+}
+
+.timeline-overview-graph.script > .timeline-record-bar > .segment {
+ border-radius: 2px;
+}
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceScriptTimelineOverviewGraphjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/ScriptTimelineOverviewGraph.js (0 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/ScriptTimelineOverviewGraph.js         (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/ScriptTimelineOverviewGraph.js        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -0,0 +1,119 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.ScriptTimelineOverviewGraph = function(recording)
+{
+ WebInspector.TimelineOverviewGraph.call(this, recording);
+
+ this.element.classList.add(WebInspector.ScriptTimelineOverviewGraph.StyleClassName);
+
+ this._scriptTimeline = recording.timelines.get(WebInspector.TimelineRecord.Type.Script);
+ this._scriptTimeline.addEventListener(WebInspector.Timeline.Event.RecordAdded, this._scriptTimelineRecordAdded, this);
+
+ this._timelineRecordBars = [];
+
+ this.reset();
+};
+
+WebInspector.ScriptTimelineOverviewGraph.StyleClassName = "script";
+
+WebInspector.ScriptTimelineOverviewGraph.prototype = {
+ constructor: WebInspector.ScriptTimelineOverviewGraph,
+ __proto__: WebInspector.TimelineOverviewGraph.prototype,
+
+ // Public
+
+ reset: function()
+ {
+ WebInspector.TimelineOverviewGraph.prototype.reset.call(this);
+
+ this._timelineRecordBarMap = new Map;
+
+ this.element.removeChildren();
+ },
+
+ updateLayout: function()
+ {
+ WebInspector.TimelineOverviewGraph.prototype.updateLayout.call(this);
+
+ var startTime = this.startTime;
+ var currentTime = this.currentTime;
+ var endTime = this.endTime;
+ var duration = (endTime - startTime);
+
+ var visibleWidth = this.element.offsetWidth;
+ var secondsPerPixel = duration / visibleWidth;
+ var recordBarIndex = 0;
+ var barRecords = [];
+
+ function createBar(barRecords)
+ {
+ var timelineRecordBar = this._timelineRecordBars[recordBarIndex];
+ if (!timelineRecordBar)
+ timelineRecordBar = this._timelineRecordBars[recordBarIndex] = new WebInspector.TimelineRecordBar;
+ timelineRecordBar.records = barRecords;
+ timelineRecordBar.refresh(this);
+ if (!timelineRecordBar.element.parentNode)
+ this.element.appendChild(timelineRecordBar.element);
+ ++recordBarIndex;
+ }
+
+ for (var record of this._scriptTimeline.records) {
+ // If this bar is completely before the bounds of the graph, skip this record.
+ if (record.endTime < 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 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);
+
+ // Remove the remaining unused TimelineRecordBars.
+ for (; recordBarIndex < this._timelineRecordBars.length; ++recordBarIndex) {
+ this._timelineRecordBars[recordBarIndex].records = null;
+ this._timelineRecordBars[recordBarIndex].element.remove();
+ }
+ },
+
+ // Private
+
+ _scriptTimelineRecordAdded: function(event)
+ {
+ this.needsLayout();
+ }
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTimelineContentViewjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/TimelineContentView.js (162418 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/TimelineContentView.js        2014-01-21 02:56:17 UTC (rev 162418)
+++ trunk/Source/WebInspectorUI/UserInterface/TimelineContentView.js        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -31,13 +31,15 @@
</span><span class="cx">
</span><span class="cx"> this.element.classList.add(WebInspector.TimelineContentView.StyleClassName);
</span><span class="cx">
</span><del>- this._timelineOverview = new WebInspector.TimelineOverview;
</del><ins>+ this._discreteTimelineOverviewGraphMap = new Map;
+ this._discreteTimelineOverviewGraphMap.set(WebInspector.TimelineRecord.Type.Network, new WebInspector.NetworkTimelineOverviewGraph(recording));
+ this._discreteTimelineOverviewGraphMap.set(WebInspector.TimelineRecord.Type.Layout, new WebInspector.LayoutTimelineOverviewGraph(recording));
+ this._discreteTimelineOverviewGraphMap.set(WebInspector.TimelineRecord.Type.Script, new WebInspector.ScriptTimelineOverviewGraph(recording));
+
+ this._timelineOverview = new WebInspector.TimelineOverview(this._discreteTimelineOverviewGraphMap);
</ins><span class="cx"> this._timelineOverview.addEventListener(WebInspector.TimelineOverview.Event.TimeRangeSelectionChanged, this._timeRangeSelectionChanged, this);
</span><span class="cx"> this.element.appendChild(this._timelineOverview.element);
</span><span class="cx">
</span><del>- this._currentTimeMarker = new WebInspector.TimelineMarker(0, WebInspector.TimelineMarker.Type.CurrentTime);
- this._timelineOverview.addMarker(this._currentTimeMarker);
-
</del><span class="cx"> this._viewContainer = document.createElement("div");
</span><span class="cx"> this._viewContainer.classList.add(WebInspector.TimelineContentView.ViewContainerStyleClassName);
</span><span class="cx"> this.element.appendChild(this._viewContainer);
</span><span class="lines">@@ -159,7 +161,7 @@
</span><span class="cx">
</span><span class="cx"> var startTime = this._timelineOverview.selectionStartTime;
</span><span class="cx"> var endTime = this._timelineOverview.selectionStartTime + this._timelineOverview.selectionDuration;
</span><del>- var currentTime = this._currentTimeMarker.time || this._recording.startTime;
</del><ins>+ var currentTime = this._currentTime || this._recording.startTime;
</ins><span class="cx">
</span><span class="cx"> function checkTimeBounds(itemStartTime, itemEndTime)
</span><span class="cx"> {
</span><span class="lines">@@ -228,7 +230,7 @@
</span><span class="cx">
</span><span class="cx"> this._currentTimelineView.startTime = this._timelineOverview.selectionStartTime;
</span><span class="cx"> this._currentTimelineView.endTime = this._timelineOverview.selectionStartTime + this._timelineOverview.selectionDuration;
</span><del>- this._currentTimelineView.currentTime = this._currentTimeMarker.time;
</del><ins>+ this._currentTimelineView.currentTime = this._currentTime;
</ins><span class="cx">
</span><span class="cx"> this._currentTimelineView.shown();
</span><span class="cx"> this._currentTimelineView.updateLayout();
</span><span class="lines">@@ -240,7 +242,7 @@
</span><span class="cx"> _update: function(timestamp)
</span><span class="cx"> {
</span><span class="cx"> var startTime = this._recording.startTime;
</span><del>- var currentTime = this._currentTimeMarker.time || startTime;
</del><ins>+ var currentTime = this._currentTime || startTime;
</ins><span class="cx"> var endTime = this._recording.endTime;
</span><span class="cx"> var timespanSinceLastUpdate = (timestamp - this._lastUpdateTimestamp) / 1000 || 0;
</span><span class="cx">
</span><span class="lines">@@ -261,11 +263,10 @@
</span><span class="cx">
</span><span class="cx"> this._timelineOverview.endTime = Math.max(endTime, currentTime);
</span><span class="cx">
</span><del>- this._currentTimeMarker.time = currentTime;
</del><ins>+ this._currentTime = currentTime;
+ this._timelineOverview.currentTime = currentTime;
</ins><span class="cx"> this._currentTimelineView.currentTime = currentTime;
</span><span class="cx">
</span><del>- this._timelineOverview.revealMarker(this._currentTimeMarker);
-
</del><span class="cx"> // Force a layout now since we are already in an animation frame and don't need to delay it until the next.
</span><span class="cx"> this._timelineOverview.updateLayoutIfNeeded();
</span><span class="cx"> this._currentTimelineView.updateLayoutIfNeeded();
</span><span class="lines">@@ -314,11 +315,14 @@
</span><span class="cx"> _recordingReset: function(event)
</span><span class="cx"> {
</span><span class="cx"> this._startTimeNeedsReset = true;
</span><del>- this._currentTimeMarker.time = 0;
</del><ins>+ this._currentTime = NaN;
</ins><span class="cx">
</span><span class="cx"> this._overviewTimelineView.reset();
</span><span class="cx"> for (var timelineView of this._discreteTimelineViewMap.values())
</span><span class="cx"> timelineView.reset();
</span><ins>+
+ for (var timelineOverviewGraph of this._discreteTimelineOverviewGraphMap.values())
+ timelineOverviewGraph.reset();
</ins><span class="cx"> },
</span><span class="cx">
</span><span class="cx"> _timeRangeSelectionChanged: function(event)
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTimelineDataGridNodejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/TimelineDataGridNode.js (162418 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/TimelineDataGridNode.js        2014-01-21 02:56:17 UTC (rev 162418)
+++ trunk/Source/WebInspectorUI/UserInterface/TimelineDataGridNode.js        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -32,7 +32,7 @@
</span><span class="cx">
</span><span class="cx"> if (graphDataSource) {
</span><span class="cx"> this._graphContainerElement = document.createElement("div");
</span><del>- this._timelineRecordBarMap = new Map;
</del><ins>+ this._timelineRecordBars = [];
</ins><span class="cx"> }
</span><span class="cx"> };
</span><span class="cx">
</span><span class="lines">@@ -198,21 +198,90 @@
</span><span class="cx"> delete this._scheduledGraphRefreshIdentifier;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- var records = this.records || [];
- for (var record of records) {
- var timelineRecordBar = this._timelineRecordBarMap.get(record);
- if (!timelineRecordBar) {
- timelineRecordBar = new WebInspector.TimelineRecordBar(record);
- this._timelineRecordBarMap.set(record, timelineRecordBar);
</del><ins>+ var records = this.records;
+ if (!records || !records.length)
+ return;
+
+ // Fast path for single records.
+ if (records.length === 1) {
+ var record = records[0];
+ var timelineRecordBar = this._timelineRecordBars[0];
+
+ if (timelineRecordBar && timelineRecordBar.record !== record) {
+ timelineRecordBar.element.remove();
+ timelineRecordBar = null;
</ins><span class="cx"> }
</span><span class="cx">
</span><ins>+ if (!timelineRecordBar)
+ timelineRecordBar = this._timelineRecordBars[0] = new WebInspector.TimelineRecordBar(record);
+
</ins><span class="cx"> if (timelineRecordBar.refresh(this._graphDataSource)) {
</span><span class="cx"> if (!timelineRecordBar.element.parentNode)
</span><span class="cx"> this._graphContainerElement.appendChild(timelineRecordBar.element);
</span><del>- } else {
</del><ins>+ } else
</ins><span class="cx"> timelineRecordBar.element.remove();
</span><ins>+
+ return;
+ }
+
+ // Multiple records attempt to share a bar if their time is close to prevent overlapping bars.
+ var startTime = this._graphDataSource.startTime;
+ var currentTime = this._graphDataSource.currentTime;
+ var endTime = this._graphDataSource.endTime;
+ var duration = endTime - startTime;
+ var visibleWidth = this._graphContainerElement.offsetWidth;
+ var secondsPerPixel = duration / visibleWidth;
+
+ var recordBarIndex = 0;
+ var barRecords = [];
+
+ function createBar(barRecords)
+ {
+ var timelineRecordBar = this._timelineRecordBars[recordBarIndex];
+ if (!timelineRecordBar)
+ timelineRecordBar = this._timelineRecordBars[recordBarIndex] = new WebInspector.TimelineRecordBar;
+ timelineRecordBar.records = barRecords;
+ timelineRecordBar.refresh(this._graphDataSource);
+ if (!timelineRecordBar.element.parentNode)
+ this._graphContainerElement.appendChild(timelineRecordBar.element);
+ ++recordBarIndex;
+ }
+
+ for (var record of records) {
+ // Combining multiple record bars is not supported with records that have inactive time.
+ // ResourceTimelineRecord is the only one right, and it is always a single record handled above.
+ console.assert(!record.usesActiveStartTime);
+
+ if (isNaN(record.startTime))
+ continue;
+
+ // If this bar is completely before the bounds of the graph, skip this record.
+ if (record.endTime < 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 = [];
</ins><span class="cx"> }
</span><ins>+
+ barRecords.push(record);
</ins><span class="cx"> }
</span><ins>+
+ // Create the bar for the last record if needed.
+ if (barRecords.length)
+ createBar.call(this, barRecords);
+
+ // Remove the remaining unused TimelineRecordBars.
+ for (; recordBarIndex < this._timelineRecordBars.length; ++recordBarIndex) {
+ this._timelineRecordBars[recordBarIndex].records = null;
+ this._timelineRecordBars[recordBarIndex].element.remove();
+ }
</ins><span class="cx"> },
</span><span class="cx">
</span><span class="cx"> needsGraphRefresh: function()
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTimelineOverviewcss"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/TimelineOverview.css (162418 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/TimelineOverview.css        2014-01-21 02:56:17 UTC (rev 162418)
+++ trunk/Source/WebInspectorUI/UserInterface/TimelineOverview.css        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -50,6 +50,27 @@
</span><span class="cx"> right: 0;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+.timeline-overview > .graphs-container {
+ position: absolute;
+ top: 22px;
+ left: 0;
+ bottom: 0;
+ right: 0;
+}
+
+.timeline-overview > .graphs-container > .timeline-overview-graph {
+ height: 36px;
+}
+
+.timeline-overview > .graphs-container > .timeline-overview-graph:nth-child(even) {
+ background-color: rgb(247, 247, 247);
+ background-clip: padding-box;
+}
+
+.timeline-overview > .graphs-container > .timeline-overview-graph:not(:first-child) {
+ border-top: 1px solid rgba(0, 0, 0, 0.09);
+}
+
</ins><span class="cx"> .timeline-overview > .scroll-container > .scroll-width-sizer {
</span><span class="cx"> position: absolute;
</span><span class="cx"> top: 0;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTimelineOverviewjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/TimelineOverview.js (162418 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/TimelineOverview.js        2014-01-21 02:56:17 UTC (rev 162418)
+++ trunk/Source/WebInspectorUI/UserInterface/TimelineOverview.js        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -23,7 +23,7 @@
</span><span class="cx"> * THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx"> */
</span><span class="cx">
</span><del>-WebInspector.TimelineOverview = function()
</del><ins>+WebInspector.TimelineOverview = function(timelineOverviewGraphsMap)
</ins><span class="cx"> {
</span><span class="cx"> WebInspector.Object.call(this);
</span><span class="cx">
</span><span class="lines">@@ -31,12 +31,24 @@
</span><span class="cx"> this._element.className = WebInspector.TimelineOverview.StyleClassName;
</span><span class="cx"> this._element.addEventListener("wheel", this._handleWheelEvent.bind(this));
</span><span class="cx">
</span><ins>+ this._graphsContainer = document.createElement("div");
+ this._graphsContainer.className = WebInspector.TimelineOverview.GraphsContainerStyleClassName;
+ this._element.appendChild(this._graphsContainer);
+
+ this._timelineOverviewGraphsMap = timelineOverviewGraphsMap;
+
+ for (var timelineOverviewGraph of this._timelineOverviewGraphsMap.values())
+ this._graphsContainer.appendChild(timelineOverviewGraph.element);
+
</ins><span class="cx"> this._timelineRuler = new WebInspector.TimelineRuler;
</span><span class="cx"> this._timelineRuler.allowsClippedLabels = true;
</span><span class="cx"> this._timelineRuler.allowsTimeRangeSelection = true;
</span><span class="cx"> this._timelineRuler.addEventListener(WebInspector.TimelineRuler.Event.TimeRangeSelectionChanged, this._timeRangeSelectionChanged, this);
</span><span class="cx"> this._element.appendChild(this._timelineRuler.element);
</span><span class="cx">
</span><ins>+ this._currentTimeMarker = new WebInspector.TimelineMarker(0, WebInspector.TimelineMarker.Type.CurrentTime);
+ this._timelineRuler.addMarker(this._currentTimeMarker);
+
</ins><span class="cx"> this._scrollContainer = document.createElement("div");
</span><span class="cx"> this._scrollContainer.className = WebInspector.TimelineOverview.ScrollContainerStyleClassName;
</span><span class="cx"> this._scrollContainer.addEventListener("scroll", this._handleScrollEvent.bind(this));
</span><span class="lines">@@ -47,6 +59,7 @@
</span><span class="cx"> this._scrollContainer.appendChild(this._scrollWidthSizer);
</span><span class="cx">
</span><span class="cx"> this._startTime = 0;
</span><ins>+ this._currentTime = 0;
</ins><span class="cx"> this._endTime = 0;
</span><span class="cx"> this._secondsPerPixel = 0.0025;
</span><span class="cx"> this._scrollStartTime = 0;
</span><span class="lines">@@ -56,6 +69,7 @@
</span><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> WebInspector.TimelineOverview.StyleClassName = "timeline-overview";
</span><ins>+WebInspector.TimelineOverview.GraphsContainerStyleClassName = "graphs-container";
</ins><span class="cx"> WebInspector.TimelineOverview.ScrollContainerStyleClassName = "scroll-container";
</span><span class="cx"> WebInspector.TimelineOverview.ScrollWidthSizerStyleClassName = "scroll-width-sizer";
</span><span class="cx"> WebInspector.TimelineOverview.MinimumSecondsPerPixel = 0.001;
</span><span class="lines">@@ -86,11 +100,27 @@
</span><span class="cx"> if (this._startTime === x)
</span><span class="cx"> return;
</span><span class="cx">
</span><del>- this._startTime = x;
</del><ins>+ this._startTime = x || 0;
</ins><span class="cx">
</span><span class="cx"> this._needsLayout();
</span><span class="cx"> },
</span><span class="cx">
</span><ins>+ get currentTime()
+ {
+ return this._currentTime;
+ },
+
+ set currentTime(x)
+ {
+ if (this._currentTime === x)
+ return;
+
+ this._currentTime = x || 0;
+ this._revealCurrentTime = true;
+
+ this._needsLayout();
+ },
+
</ins><span class="cx"> get secondsPerPixel()
</span><span class="cx"> {
</span><span class="cx"> return this._secondsPerPixel;
</span><span class="lines">@@ -192,6 +222,13 @@
</span><span class="cx"> // Update all relevant elements to the new required width.
</span><span class="cx"> this._updateElementWidth(this._scrollWidthSizer, newWidth);
</span><span class="cx">
</span><ins>+ this._currentTimeMarker.time = this._currentTime;
+
+ if (this._revealCurrentTime) {
+ this.revealMarker(this._currentTimeMarker);
+ delete this._revealCurrentTime;
+ }
+
</ins><span class="cx"> // Clamp the scroll start time to match what the scroll bar would allow.
</span><span class="cx"> var scrollStartTime = Math.min(this._scrollStartTime, this._endTime - this.visibleDuration);
</span><span class="cx"> scrollStartTime = Math.max(this._startTime, scrollStartTime);
</span><span class="lines">@@ -206,15 +243,27 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> this._timelineRuler.updateLayout();
</span><ins>+
+ for (var timelineOverviewGraph of this._timelineOverviewGraphsMap.values()) {
+ timelineOverviewGraph.zeroTime = this._startTime;
+ timelineOverviewGraph.startTime = scrollStartTime;
+ timelineOverviewGraph.currentTime = this._currentTime;
+ timelineOverviewGraph.endTime = scrollStartTime + this.visibleDuration;
+ timelineOverviewGraph.updateLayout();
+ }
</ins><span class="cx"> },
</span><span class="cx">
</span><span class="cx"> updateLayoutIfNeeded: function()
</span><span class="cx"> {
</span><ins>+ if (this._scheduledLayoutUpdateIdentifier) {
+ this.updateLayout();
+ return;
+ }
+
</ins><span class="cx"> this._timelineRuler.updateLayoutIfNeeded();
</span><span class="cx">
</span><del>- if (!this._scheduledLayoutUpdateIdentifier)
- return;
- this.updateLayout();
</del><ins>+ for (var timelineOverviewGraph of this._timelineOverviewGraphsMap.values())
+ timelineOverviewGraph.updateLayoutIfNeeded();
</ins><span class="cx"> },
</span><span class="cx">
</span><span class="cx"> // Private
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTimelineOverviewGraphjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/TimelineOverviewGraph.js (0 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/TimelineOverviewGraph.js         (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/TimelineOverviewGraph.js        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -0,0 +1,141 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.TimelineOverviewGraph = function(recording)
+{
+ WebInspector.Object.call(this);
+
+ this.element = document.createElement("div");
+ this.element.classList.add(WebInspector.TimelineOverviewGraph.StyleClassName);
+
+ this._zeroTime = 0;
+ this._startTime = 0;
+ this._endTime = 5;
+ this._currentTime = 0;
+};
+
+WebInspector.TimelineOverviewGraph.StyleClassName = "timeline-overview-graph";
+
+WebInspector.TimelineOverviewGraph.prototype = {
+ constructor: WebInspector.TimelineOverviewGraph,
+ __proto__: WebInspector.Object.prototype,
+
+ // Public
+
+ get zeroTime()
+ {
+ return this._zeroTime;
+ },
+
+ set zeroTime(x)
+ {
+ if (this._zeroTime === x)
+ return;
+
+ this._zeroTime = x || 0;
+
+ this.needsLayout();
+ },
+
+ get startTime()
+ {
+ return this._startTime;
+ },
+
+ set startTime(x)
+ {
+ if (this._startTime === x)
+ return;
+
+ this._startTime = x || 0;
+
+ this.needsLayout();
+ },
+
+ get endTime()
+ {
+ return this._endTime;
+ },
+
+ set endTime(x)
+ {
+ if (this._endTime === x)
+ return;
+
+ this._endTime = x || 0;
+
+ this.needsLayout();
+ },
+
+ get currentTime()
+ {
+ return this._currentTime;
+ },
+
+ set currentTime(x)
+ {
+ if (this._currentTime === x)
+ return;
+
+ var oldCurrentTime = this._currentTime;
+
+ this._currentTime = x || 0;
+
+ if ((this._startTime <= oldCurrentTime && oldCurrentTime <= this._endTime) || (this._startTime <= this._currentTime && this._currentTime <= this._endTime))
+ this.needsLayout();
+ },
+
+ reset: function()
+ {
+ // Implemented by sub-classes if needed.
+ },
+
+ updateLayout: function()
+ {
+ if (this._scheduledLayoutUpdateIdentifier) {
+ cancelAnimationFrame(this._scheduledLayoutUpdateIdentifier);
+ delete this._scheduledLayoutUpdateIdentifier;
+ }
+
+ // Implemented by sub-classes if needed.
+ },
+
+ updateLayoutIfNeeded: function()
+ {
+ if (!this._scheduledLayoutUpdateIdentifier)
+ return;
+ this.updateLayout();
+ },
+
+ // Protected
+
+ needsLayout: function()
+ {
+ if (this._scheduledLayoutUpdateIdentifier)
+ return;
+
+ this._scheduledLayoutUpdateIdentifier = requestAnimationFrame(this.updateLayout.bind(this));
+ }
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTimelineRecordBarcss"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.css (162418 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.css        2014-01-21 02:56:17 UTC (rev 162418)
+++ trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.css        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -30,7 +30,7 @@
</span><span class="cx">
</span><span class="cx"> .timeline-record-bar > .segment {
</span><span class="cx"> position: absolute;
</span><del>- height: 12px;
</del><ins>+ height: 100%;
</ins><span class="cx"> background-color: rgb(225, 225, 225);
</span><span class="cx"> border: 1px solid rgb(200, 200, 200);
</span><span class="cx"> border-radius: 3px;
</span><span class="lines">@@ -44,14 +44,14 @@
</span><span class="cx">
</span><span class="cx"> .timeline-record-bar > .segment.inactive,
</span><span class="cx"> .timeline-record-bar.unfinished > .segment {
</span><del>- border-top-right-radius: 0;
- border-bottom-right-radius: 0;
</del><ins>+ border-top-right-radius: 0 !important;
+ border-bottom-right-radius: 0 !important;
</ins><span class="cx"> border-right: none;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> .timeline-record-bar > .segment.inactive + .segment {
</span><del>- border-top-left-radius: 0;
- border-bottom-left-radius: 0;
</del><ins>+ border-top-left-radius: 0 !important;
+ border-bottom-left-radius: 0 !important;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> :focus .selected .timeline-record-bar > .segment {
</span><span class="lines">@@ -59,15 +59,16 @@
</span><span class="cx"> border-color: white !important;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-.timeline-record-bar > .segment.inactive {
- opacity: 0.5;
-}
-
</del><span class="cx"> .timeline-record-bar.timeline-record-type-network > .segment {
</span><span class="cx"> background-color: rgb(120, 176, 225);
</span><span class="cx"> border-color: rgb(61, 147, 200);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+.timeline-record-bar.timeline-record-type-network > .segment.inactive {
+ background-color: rgb(167, 204, 237);
+ border-color: rgb(127, 185, 220);
+}
+
</ins><span class="cx"> .timeline-record-bar.timeline-record-type-layout > .segment {
</span><span class="cx"> background-color: rgb(234, 153, 153);
</span><span class="cx"> border-color: rgb(212, 108, 108);
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTimelineRecordBarjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.js (162418 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.js        2014-01-21 02:56:17 UTC (rev 162418)
+++ trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.js        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -23,31 +23,18 @@
</span><span class="cx"> * THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx"> */
</span><span class="cx">
</span><del>-WebInspector.TimelineRecordBar = function(record)
</del><ins>+WebInspector.TimelineRecordBar = function(records)
</ins><span class="cx"> {
</span><span class="cx"> WebInspector.Object.call(this);
</span><span class="cx">
</span><del>- console.assert(record);
-
- this._record = record;
-
</del><span class="cx"> this._element = document.createElement("div");
</span><span class="cx"> this._element.classList.add(WebInspector.TimelineRecordBar.StyleClassName);
</span><del>- this._element.classList.add(record.type);
</del><span class="cx">
</span><del>- if (record.usesActiveStartTime) {
- this._inactiveBarElement = document.createElement("div");
- this._inactiveBarElement.classList.add(WebInspector.TimelineRecordBar.BarSegmentStyleClassName);
- this._inactiveBarElement.classList.add(WebInspector.TimelineRecordBar.InactiveStyleClassName);
- this._element.classList.add(WebInspector.TimelineRecordBar.HasInactiveSegmentStyleClassName);
- }
-
</del><span class="cx"> this._activeBarElement = document.createElement("div");
</span><span class="cx"> this._activeBarElement.classList.add(WebInspector.TimelineRecordBar.BarSegmentStyleClassName);
</span><ins>+ this._element.appendChild(this._activeBarElement);
</ins><span class="cx">
</span><del>- if (this._inactiveBarElement)
- this._element.appendChild(this._inactiveBarElement);
- this._element.appendChild(this._activeBarElement);
</del><ins>+ this.records = records;
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> WebInspector.Object.addConstructorFunctions(WebInspector.TimelineRecordBar);
</span><span class="lines">@@ -57,7 +44,36 @@
</span><span class="cx"> WebInspector.TimelineRecordBar.InactiveStyleClassName = "inactive";
</span><span class="cx"> WebInspector.TimelineRecordBar.UnfinishedStyleClassName = "unfinished";
</span><span class="cx"> WebInspector.TimelineRecordBar.HasInactiveSegmentStyleClassName = "has-inactive-segment";
</span><ins>+WebInspector.TimelineRecordBar.MinimumWidthPixels = 4;
+WebInspector.TimelineRecordBar.MinimumMarginPixels = 1;
</ins><span class="cx">
</span><ins>+WebInspector.TimelineRecordBar.recordsCannotBeCombined = function(records, candidateRecord, secondsPerPixel)
+{
+ console.assert(records instanceof Array || records instanceof WebInspector.TimelineRecord);
+ console.assert(candidateRecord instanceof WebInspector.TimelineRecord);
+
+ if (records instanceof WebInspector.TimelineRecord)
+ records = [records];
+
+ if (!records.length)
+ return true;
+
+ var lastRecord = records.lastValue;
+ if (lastRecord.type !== candidateRecord.type)
+ return true;
+
+ if (isNaN(candidateRecord.startTime))
+ return true;
+
+ var firstRecord = records[0];
+ var totalDuration = lastRecord.endTime - firstRecord.startTime;
+
+ var minimumMargin = WebInspector.TimelineRecordBar.MinimumMarginPixels * secondsPerPixel;
+ var minimumDuration = WebInspector.TimelineRecordBar.MinimumWidthPixels * secondsPerPixel;
+
+ return firstRecord.startTime + Math.max(minimumDuration, totalDuration) + minimumMargin <= candidateRecord.startTime;
+};
+
</ins><span class="cx"> WebInspector.TimelineRecordBar.prototype = {
</span><span class="cx"> constructor: WebInspector.TimelineRecordBar,
</span><span class="cx"> __proto__: WebInspector.Object.prototype,
</span><span class="lines">@@ -69,10 +85,53 @@
</span><span class="cx"> return this._element;
</span><span class="cx"> },
</span><span class="cx">
</span><ins>+ get records()
+ {
+ return this._records;
+ },
+
+ set records(records)
+ {
+ if (this._records && this._records.length)
+ this._element.classList.remove(this._records[0].type);
+
+ records = records || [];
+
+ if (!(records instanceof Array))
+ records = [records];
+
+ this._records = records;
+
+ // Combining multiple record bars is not supported with records that have inactive time.
+ console.assert(this._records.length <= 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._activeBarElement);
+ }
+ } else if (this._inactiveBarElement) {
+ this._inactiveBarElement.remove();
+ delete this._inactiveBarElement;
+ }
+
+ // Assume all records are the same type.
+ if (this._records.length)
+ this._element.classList.add(this._records[0].type);
+ },
+
</ins><span class="cx"> refresh: function(graphDataSource)
</span><span class="cx"> {
</span><del>- var barStartTime = this._record.startTime;
</del><ins>+ if (!this._records || !this._records.length)
+ return;
</ins><span class="cx">
</span><ins>+ var firstRecord = this._records[0];
+ var barStartTime = firstRecord.startTime;
+
</ins><span class="cx"> // If this bar has no time info, return early.
</span><span class="cx"> if (isNaN(barStartTime))
</span><span class="cx"> return false;
</span><span class="lines">@@ -81,13 +140,14 @@
</span><span class="cx"> var graphEndTime = graphDataSource.endTime;
</span><span class="cx"> var graphCurrentTime = graphDataSource.currentTime;
</span><span class="cx">
</span><del>- var barEndTime = this._record.endTime;
</del><ins>+ var lastRecord = this._records.lastValue;
+ var barEndTime = lastRecord.endTime;
</ins><span class="cx">
</span><del>- // If this bar is completly after the current time, return early.
</del><ins>+ // If this bar is completely after the current time, return early.
</ins><span class="cx"> if (barStartTime > graphCurrentTime)
</span><span class="cx"> return false;
</span><span class="cx">
</span><del>- // If this bar is completly before or after the bounds of the graph, return early.
</del><ins>+ // If this bar is completely before or after the bounds of the graph, return early.
</ins><span class="cx"> if (barEndTime < graphStartTime || barStartTime > graphEndTime)
</span><span class="cx"> return false;
</span><span class="cx">
</span><span class="lines">@@ -105,10 +165,12 @@
</span><span class="cx"> var newBarWidth = ((barEndTime - graphStartTime) / graphDuration) - newBarLeftPosition;
</span><span class="cx"> this._updateElementPosition(this._element, newBarWidth, "width");
</span><span class="cx">
</span><del>- if (!this._record.usesActiveStartTime)
</del><ins>+ if (!this._inactiveBarElement)
</ins><span class="cx"> return true;
</span><span class="cx">
</span><del>- var barActiveStartTime = Math.max(barStartTime, Math.min(this._record.activeStartTime, barEndTime));
</del><ins>+ console.assert(firstRecord === lastRecord);
+
+ var barActiveStartTime = Math.max(barStartTime, Math.min(firstRecord.activeStartTime, barEndTime));
</ins><span class="cx"> var barDuration = barEndTime - barStartTime;
</span><span class="cx">
</span><span class="cx"> var inactiveUnfinished = isNaN(barActiveStartTime) || barActiveStartTime >= graphCurrentTime;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTimelineRulercss"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/TimelineRuler.css (162418 => 162419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/TimelineRuler.css        2014-01-21 02:56:17 UTC (rev 162418)
+++ trunk/Source/WebInspectorUI/UserInterface/TimelineRuler.css        2014-01-21 02:56:29 UTC (rev 162419)
</span><span class="lines">@@ -71,7 +71,7 @@
</span><span class="cx"> left: 0;
</span><span class="cx"> right: 0;
</span><span class="cx"> bottom: 0;
</span><del>- z-index: 1;
</del><ins>+ z-index: 10;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> .timeline-ruler > .markers > .divider {
</span><span class="lines">@@ -148,6 +148,7 @@
</span><span class="cx"> border: 1px solid white;
</span><span class="cx"> cursor: col-resize;
</span><span class="cx"> pointer-events: all;
</span><ins>+ z-index: 15;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> .timeline-ruler > .selection-handle.left {
</span><span class="lines">@@ -163,6 +164,7 @@
</span><span class="cx"> top: 0;
</span><span class="cx"> bottom: 0;
</span><span class="cx"> background-color: rgba(0, 0, 0, 0.1);
</span><ins>+ z-index: 15;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> .timeline-ruler > .shaded-area.left {
</span></span></pre>
</div>
</div>
</body>
</html>