<!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>[192070] 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/192070">192070</a></dd>
<dt>Author</dt> <dd>mattbaker@apple.com</dd>
<dt>Date</dt> <dd>2015-11-05 13:17:41 -0800 (Thu, 05 Nov 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Web Inspector: Convert TimelineRuler to View base class
https://bugs.webkit.org/show_bug.cgi?id=150703

Reviewed by Brian Burg.

Convert TimelineRuler to View base class. Ruler markers and selection elements
can be updated independent from its main layout. The logic for these additional
layouts is implemented as an override of View.prototype.needsLayout, and remains
largely unchanged.

* UserInterface/Views/OverviewTimelineView.js:
(WebInspector.OverviewTimelineView):
Add ruler as a subview.
(WebInspector.OverviewTimelineView.prototype.layout): Deleted.
Separate ruler layout no longer needed.

* UserInterface/Views/TimelineRuler.js:
(WebInspector.TimelineRuler):
(WebInspector.TimelineRuler.prototype.set allowsClippedLabels):
(WebInspector.TimelineRuler.prototype.set formatLabelCallback):
(WebInspector.TimelineRuler.prototype.set allowsTimeRangeSelection):
(WebInspector.TimelineRuler.prototype.set zeroTime):
(WebInspector.TimelineRuler.prototype.set startTime):
(WebInspector.TimelineRuler.prototype.set duration):
(WebInspector.TimelineRuler.prototype.get endTime):
(WebInspector.TimelineRuler.prototype.set endTime):
(WebInspector.TimelineRuler.prototype.get secondsPerPixel):
(WebInspector.TimelineRuler.prototype.set secondsPerPixel):
(WebInspector.TimelineRuler.prototype.updateLayoutIfNeeded):
(WebInspector.TimelineRuler.prototype.needsLayout):
(WebInspector.TimelineRuler.prototype.layout):
(WebInspector.TimelineRuler.prototype._needsMarkerLayout):
(WebInspector.TimelineRuler.prototype._needsSelectionLayout):
(WebInspector.TimelineRuler.prototype._recalculate):
(WebInspector.TimelineRuler.prototype._updateMarkers):
(WebInspector.TimelineRuler.prototype._updateSelection):
(WebInspector.TimelineRuler.prototype._handleMouseDown):
(WebInspector.TimelineRuler.prototype._handleMouseMove):
(WebInspector.TimelineRuler.prototype._handleMouseUp):
(WebInspector.TimelineRuler.prototype._handleSelectionHandleMouseDown):
(WebInspector.TimelineRuler.prototype._handleSelectionHandleMouseMove):
(WebInspector.TimelineRuler.prototype._handleSelectionHandleMouseUp):
Renamed methods to match new View.prototype methods and cleaned up
some code to use let, for...of.
(WebInspector.TimelineRuler.prototype.get element): Deleted.
No longer needed.
(WebInspector.TimelineRuler.prototype.updateLayout): Deleted.
Renamed to layout, overrides View.prototype.layout.
(WebInspector.TimelineRuler.prototype._needsLayout): Deleted.
Renamed to needsLayout, overrides View.prototype.needsLayout.
(WebInspector.TimelineRuler.prototype._needsMarkerLayout.update): Deleted.
(WebInspector.TimelineRuler.prototype._needsSelectionLayout.update): Deleted.

* UserInterface/Views/View.js:
(WebInspector.View.prototype.get isLayoutPending):
Added getter to check for pending layout.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsTimelineRulerjs">trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRuler.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsViewjs">trunk/Source/WebInspectorUI/UserInterface/Views/View.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (192069 => 192070)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2015-11-05 20:37:24 UTC (rev 192069)
+++ trunk/Source/WebInspectorUI/ChangeLog        2015-11-05 21:17:41 UTC (rev 192070)
</span><span class="lines">@@ -1,3 +1,62 @@
</span><ins>+2015-11-05  Matt Baker  &lt;mattbaker@apple.com&gt;
+
+        Web Inspector: Convert TimelineRuler to View base class
+        https://bugs.webkit.org/show_bug.cgi?id=150703
+
+        Reviewed by Brian Burg.
+
+        Convert TimelineRuler to View base class. Ruler markers and selection elements
+        can be updated independent from its main layout. The logic for these additional
+        layouts is implemented as an override of View.prototype.needsLayout, and remains
+        largely unchanged.
+
+        * UserInterface/Views/OverviewTimelineView.js:
+        (WebInspector.OverviewTimelineView):
+        Add ruler as a subview.
+        (WebInspector.OverviewTimelineView.prototype.layout): Deleted.
+        Separate ruler layout no longer needed.
+
+        * UserInterface/Views/TimelineRuler.js:
+        (WebInspector.TimelineRuler):
+        (WebInspector.TimelineRuler.prototype.set allowsClippedLabels):
+        (WebInspector.TimelineRuler.prototype.set formatLabelCallback):
+        (WebInspector.TimelineRuler.prototype.set allowsTimeRangeSelection):
+        (WebInspector.TimelineRuler.prototype.set zeroTime):
+        (WebInspector.TimelineRuler.prototype.set startTime):
+        (WebInspector.TimelineRuler.prototype.set duration):
+        (WebInspector.TimelineRuler.prototype.get endTime):
+        (WebInspector.TimelineRuler.prototype.set endTime):
+        (WebInspector.TimelineRuler.prototype.get secondsPerPixel):
+        (WebInspector.TimelineRuler.prototype.set secondsPerPixel):
+        (WebInspector.TimelineRuler.prototype.updateLayoutIfNeeded):
+        (WebInspector.TimelineRuler.prototype.needsLayout):
+        (WebInspector.TimelineRuler.prototype.layout):
+        (WebInspector.TimelineRuler.prototype._needsMarkerLayout):
+        (WebInspector.TimelineRuler.prototype._needsSelectionLayout):
+        (WebInspector.TimelineRuler.prototype._recalculate):
+        (WebInspector.TimelineRuler.prototype._updateMarkers):
+        (WebInspector.TimelineRuler.prototype._updateSelection):
+        (WebInspector.TimelineRuler.prototype._handleMouseDown):
+        (WebInspector.TimelineRuler.prototype._handleMouseMove):
+        (WebInspector.TimelineRuler.prototype._handleMouseUp):
+        (WebInspector.TimelineRuler.prototype._handleSelectionHandleMouseDown):
+        (WebInspector.TimelineRuler.prototype._handleSelectionHandleMouseMove):
+        (WebInspector.TimelineRuler.prototype._handleSelectionHandleMouseUp):
+        Renamed methods to match new View.prototype methods and cleaned up
+        some code to use let, for...of.
+        (WebInspector.TimelineRuler.prototype.get element): Deleted.
+        No longer needed.
+        (WebInspector.TimelineRuler.prototype.updateLayout): Deleted.
+        Renamed to layout, overrides View.prototype.layout.
+        (WebInspector.TimelineRuler.prototype._needsLayout): Deleted.
+        Renamed to needsLayout, overrides View.prototype.needsLayout.
+        (WebInspector.TimelineRuler.prototype._needsMarkerLayout.update): Deleted.
+        (WebInspector.TimelineRuler.prototype._needsSelectionLayout.update): Deleted.
+
+        * UserInterface/Views/View.js:
+        (WebInspector.View.prototype.get isLayoutPending):
+        Added getter to check for pending layout.
+
</ins><span class="cx"> 2015-11-05  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: ⌥⌘C sometimes ends ups up opening inspector without console prompt focused
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsTimelineRulerjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRuler.js (192069 => 192070)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRuler.js        2015-11-05 20:37:24 UTC (rev 192069)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRuler.js        2015-11-05 21:17:41 UTC (rev 192070)
</span><span class="lines">@@ -23,22 +23,21 @@
</span><span class="cx">  * THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx">  */
</span><span class="cx"> 
</span><del>-WebInspector.TimelineRuler = class TimelineRuler extends WebInspector.Object
</del><ins>+WebInspector.TimelineRuler = class TimelineRuler extends WebInspector.View
</ins><span class="cx"> {
</span><span class="cx">     constructor()
</span><span class="cx">     {
</span><span class="cx">         super();
</span><span class="cx"> 
</span><del>-        this._element = document.createElement(&quot;div&quot;);
-        this._element.classList.add(&quot;timeline-ruler&quot;);
</del><ins>+        this.element.classList.add(&quot;timeline-ruler&quot;);
</ins><span class="cx"> 
</span><span class="cx">         this._headerElement = document.createElement(&quot;div&quot;);
</span><span class="cx">         this._headerElement.classList.add(&quot;header&quot;);
</span><del>-        this._element.appendChild(this._headerElement);
</del><ins>+        this.element.appendChild(this._headerElement);
</ins><span class="cx"> 
</span><span class="cx">         this._markersElement = document.createElement(&quot;div&quot;);
</span><span class="cx">         this._markersElement.classList.add(&quot;markers&quot;);
</span><del>-        this._element.appendChild(this._markersElement);
</del><ins>+        this.element.appendChild(this._markersElement);
</ins><span class="cx"> 
</span><span class="cx">         this._zeroTime = 0;
</span><span class="cx">         this._startTime = 0;
</span><span class="lines">@@ -59,11 +58,6 @@
</span><span class="cx"> 
</span><span class="cx">     // Public
</span><span class="cx"> 
</span><del>-    get element()
-    {
-        return this._element;
-    }
-
</del><span class="cx">     get allowsClippedLabels()
</span><span class="cx">     {
</span><span class="cx">         return this._allowsClippedLabels;
</span><span class="lines">@@ -76,7 +70,7 @@
</span><span class="cx"> 
</span><span class="cx">         this._allowsClippedLabels = x || false;
</span><span class="cx"> 
</span><del>-        this._needsLayout();
</del><ins>+        this.needsLayout();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     set formatLabelCallback(x)
</span><span class="lines">@@ -88,7 +82,7 @@
</span><span class="cx"> 
</span><span class="cx">         this._formatLabelCallback = x || null;
</span><span class="cx"> 
</span><del>-        this._needsLayout();
</del><ins>+        this.needsLayout();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     get allowsTimeRangeSelection()
</span><span class="lines">@@ -105,7 +99,7 @@
</span><span class="cx"> 
</span><span class="cx">         if (x) {
</span><span class="cx">             this._mouseDownEventListener = this._handleMouseDown.bind(this);
</span><del>-            this._element.addEventListener(&quot;mousedown&quot;, this._mouseDownEventListener);
</del><ins>+            this.element.addEventListener(&quot;mousedown&quot;, this._mouseDownEventListener);
</ins><span class="cx"> 
</span><span class="cx">             this._leftShadedAreaElement = document.createElement(&quot;div&quot;);
</span><span class="cx">             this._leftShadedAreaElement.classList.add(&quot;shaded-area&quot;);
</span><span class="lines">@@ -130,7 +124,7 @@
</span><span class="cx"> 
</span><span class="cx">             this._needsSelectionLayout();
</span><span class="cx">         } else {
</span><del>-            this._element.removeEventListener(&quot;mousedown&quot;, this._mouseDownEventListener);
</del><ins>+            this.element.removeEventListener(&quot;mousedown&quot;, this._mouseDownEventListener);
</ins><span class="cx">             delete this._mouseDownEventListener;
</span><span class="cx"> 
</span><span class="cx">             this._leftShadedAreaElement.remove();
</span><span class="lines">@@ -169,7 +163,7 @@
</span><span class="cx"> 
</span><span class="cx">         this._zeroTime = x || 0;
</span><span class="cx"> 
</span><del>-        this._needsLayout();
</del><ins>+        this.needsLayout();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     get startTime()
</span><span class="lines">@@ -187,7 +181,7 @@
</span><span class="cx">         if (!isNaN(this._duration))
</span><span class="cx">             this._endTime = this._startTime + this._duration;
</span><span class="cx"> 
</span><del>-        this._needsLayout();
</del><ins>+        this.needsLayout();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     get duration()
</span><span class="lines">@@ -210,12 +204,12 @@
</span><span class="cx">         } else
</span><span class="cx">             this._endTimePinned = false;
</span><span class="cx"> 
</span><del>-        this._needsLayout();
</del><ins>+        this.needsLayout();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     get endTime()
</span><span class="cx">     {
</span><del>-        if (!this._endTimePinned &amp;&amp; this._scheduledLayoutUpdateIdentifier)
</del><ins>+        if (!this._endTimePinned &amp;&amp; this.layoutPending)
</ins><span class="cx">             this._recalculate();
</span><span class="cx">         return this._endTime;
</span><span class="cx">     }
</span><span class="lines">@@ -228,12 +222,12 @@
</span><span class="cx">         this._endTime = x || 0;
</span><span class="cx">         this._endTimePinned = true;
</span><span class="cx"> 
</span><del>-        this._needsLayout();
</del><ins>+        this.needsLayout();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     get secondsPerPixel()
</span><span class="cx">     {
</span><del>-        if (this._scheduledLayoutUpdateIdentifier)
</del><ins>+        if (this.layoutPending)
</ins><span class="cx">             this._recalculate();
</span><span class="cx">         return this._secondsPerPixel;
</span><span class="cx">     }
</span><span class="lines">@@ -247,7 +241,7 @@
</span><span class="cx">         this._endTimePinned = false;
</span><span class="cx">         this._currentSliceTime = 0;
</span><span class="cx"> 
</span><del>-        this._needsLayout();
</del><ins>+        this.needsLayout();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     get snapInterval()
</span><span class="lines">@@ -342,27 +336,61 @@
</span><span class="cx">         return this._markerElementMap.get(marker) || null;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    updateLayout()
</del><ins>+    updateLayoutIfNeeded()
</ins><span class="cx">     {
</span><del>-        if (this._scheduledLayoutUpdateIdentifier) {
-            cancelAnimationFrame(this._scheduledLayoutUpdateIdentifier);
-            delete this._scheduledLayoutUpdateIdentifier;
</del><ins>+        // If a layout is pending we can let the base class handle it and return, since that will update
+        // markers and the selection at the same time.
+        if (this.layoutPending) {
+            super.updateLayoutIfNeeded();
+            return;
</ins><span class="cx">         }
</span><span class="cx"> 
</span><del>-        var visibleWidth = this._recalculate();
</del><ins>+        let visibleWidth = this._recalculate();
</ins><span class="cx">         if (visibleWidth &lt;= 0)
</span><span class="cx">             return;
</span><span class="cx"> 
</span><del>-        var duration = this.duration;
</del><ins>+        if (this._scheduledMarkerLayoutUpdateIdentifier)
+            this._updateMarkers(visibleWidth, this.duration);
</ins><span class="cx"> 
</span><del>-        var pixelsPerSecond = visibleWidth / duration;
</del><ins>+        if (this._scheduledSelectionLayoutUpdateIdentifier)
+            this._updateSelection(visibleWidth, this.duration);
+    }
</ins><span class="cx"> 
</span><del>-        // Calculate a divider count based on the maximum allowed divider density.
-        var dividerCount = Math.round(visibleWidth / WebInspector.TimelineRuler.MinimumDividerSpacing);
</del><ins>+    needsLayout()
+    {
+        if (this.layoutPending)
+            return;
</ins><span class="cx"> 
</span><ins>+        if (this._scheduledMarkerLayoutUpdateIdentifier) {
+            cancelAnimationFrame(this._scheduledMarkerLayoutUpdateIdentifier);
+            this._scheduledMarkerLayoutUpdateIdentifier = undefined;
+        }
+
+        if (this._scheduledSelectionLayoutUpdateIdentifier) {
+            cancelAnimationFrame(this._scheduledSelectionLayoutUpdateIdentifier);
+            this._scheduledSelectionLayoutUpdateIdentifier = undefined;
+        }
+
+        super.needsLayout();
+    }
+
+    // Protected
+
+    layout()
+    {
+        let visibleWidth = this._recalculate();
+        if (visibleWidth &lt;= 0)
+            return;
+
+        let duration = this.duration;
+        let pixelsPerSecond = visibleWidth / duration;
+
+        // Calculate a divider count based on the maximum allowed divider density.
+        let dividerCount = Math.round(visibleWidth / WebInspector.TimelineRuler.MinimumDividerSpacing);
+        let sliceTime;
</ins><span class="cx">         if (this._endTimePinned || !this._currentSliceTime) {
</span><span class="cx">             // Calculate the slice time based on the rough divider count and the time span.
</span><del>-            var sliceTime = duration / dividerCount;
</del><ins>+            sliceTime = duration / dividerCount;
</ins><span class="cx"> 
</span><span class="cx">             // Snap the slice time to a nearest number (e.g. 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, etc.)
</span><span class="cx">             sliceTime = Math.pow(10, Math.ceil(Math.log(sliceTime) / Math.LN10));
</span><span class="lines">@@ -374,11 +402,11 @@
</span><span class="cx">             this._currentSliceTime = sliceTime;
</span><span class="cx">         } else {
</span><span class="cx">             // Reuse the last slice time since the time duration does not scale to fit when the end time isn't pinned.
</span><del>-            var sliceTime = this._currentSliceTime;
</del><ins>+            sliceTime = this._currentSliceTime;
</ins><span class="cx">         }
</span><span class="cx"> 
</span><del>-        var firstDividerTime = (Math.ceil((this._startTime - this._zeroTime) / sliceTime) * sliceTime) + this._zeroTime;
-        var lastDividerTime = this._endTime;
</del><ins>+        let firstDividerTime = (Math.ceil((this._startTime - this._zeroTime) / sliceTime) * sliceTime) + this._zeroTime;
+        let lastDividerTime = this._endTime;
</ins><span class="cx"> 
</span><span class="cx">         // Calculate the divider count now based on the final slice time.
</span><span class="cx">         dividerCount = Math.ceil((lastDividerTime - firstDividerTime) / sliceTime);
</span><span class="lines">@@ -387,7 +415,7 @@
</span><span class="cx">         if (!this._endTimePinned)
</span><span class="cx">             ++dividerCount;
</span><span class="cx"> 
</span><del>-        var dividerData = {
</del><ins>+        let dividerData = {
</ins><span class="cx">             count: dividerCount,
</span><span class="cx">             firstTime: firstDividerTime,
</span><span class="cx">             lastTime: lastDividerTime,
</span><span class="lines">@@ -401,32 +429,30 @@
</span><span class="cx"> 
</span><span class="cx">         this._currentDividers = dividerData;
</span><span class="cx"> 
</span><del>-        var markerDividers = this._markersElement.querySelectorAll(&quot;.&quot; + WebInspector.TimelineRuler.DividerElementStyleClassName);
</del><ins>+        let markerDividers = this._markersElement.querySelectorAll(&quot;.&quot; + WebInspector.TimelineRuler.DividerElementStyleClassName);
+        let dividerElement = this._headerElement.firstChild;
</ins><span class="cx"> 
</span><del>-        var dividerElement = this._headerElement.firstChild;
-
</del><span class="cx">         for (var i = 0; i &lt;= dividerCount; ++i) {
</span><span class="cx">             if (!dividerElement) {
</span><span class="cx">                 dividerElement = document.createElement(&quot;div&quot;);
</span><span class="cx">                 dividerElement.className = WebInspector.TimelineRuler.DividerElementStyleClassName;
</span><span class="cx">                 this._headerElement.appendChild(dividerElement);
</span><span class="cx"> 
</span><del>-                var labelElement = document.createElement(&quot;div&quot;);
</del><ins>+                let labelElement = document.createElement(&quot;div&quot;);
</ins><span class="cx">                 labelElement.className = WebInspector.TimelineRuler.DividerLabelElementStyleClassName;
</span><span class="cx">                 dividerElement.appendChild(labelElement);
</span><span class="cx">             }
</span><span class="cx"> 
</span><del>-            var markerDividerElement = markerDividers[i];
</del><ins>+            let markerDividerElement = markerDividers[i];
</ins><span class="cx">             if (!markerDividerElement) {
</span><span class="cx">                 markerDividerElement = document.createElement(&quot;div&quot;);
</span><span class="cx">                 markerDividerElement.className = WebInspector.TimelineRuler.DividerElementStyleClassName;
</span><span class="cx">                 this._markersElement.appendChild(markerDividerElement);
</span><span class="cx">             }
</span><span class="cx"> 
</span><del>-            var dividerTime = firstDividerTime + (sliceTime * i);
</del><ins>+            let dividerTime = firstDividerTime + (sliceTime * i);
+            let newLeftPosition = (dividerTime - this._startTime) / duration;
</ins><span class="cx"> 
</span><del>-            var newLeftPosition = (dividerTime - this._startTime) / duration;
-
</del><span class="cx">             if (!this._allowsClippedLabels) {
</span><span class="cx">                 // Don't allow dividers under 0% where they will be completely hidden.
</span><span class="cx">                 if (newLeftPosition &lt; 0)
</span><span class="lines">@@ -452,7 +478,7 @@
</span><span class="cx"> 
</span><span class="cx">         // Remove extra dividers.
</span><span class="cx">         while (dividerElement) {
</span><del>-            var nextDividerElement = dividerElement.nextSibling;
</del><ins>+            let nextDividerElement = dividerElement.nextSibling;
</ins><span class="cx">             dividerElement.remove();
</span><span class="cx">             dividerElement = nextDividerElement;
</span><span class="cx">         }
</span><span class="lines">@@ -464,67 +490,26 @@
</span><span class="cx">         this._updateSelection(visibleWidth, duration);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    updateLayoutIfNeeded()
-    {
-        // If there is a main layout scheduled we can just update layout and return, since that
-        // will update markers and the selection at the same time.
-        if (this._scheduledLayoutUpdateIdentifier) {
-            this.updateLayout();
-            return;
-        }
-
-        var visibleWidth = this._element.clientWidth;
-        if (visibleWidth &lt;= 0)
-            return;
-
-        if (this._scheduledMarkerLayoutUpdateIdentifier)
-            this._updateMarkers(visibleWidth, this.duration);
-
-        if (this._scheduledSelectionLayoutUpdateIdentifier)
-            this._updateSelection(visibleWidth, this.duration);
-    }
-
</del><span class="cx">     // Private
</span><span class="cx"> 
</span><del>-    _needsLayout()
-    {
-        if (this._scheduledLayoutUpdateIdentifier)
-            return;
-
-        if (this._scheduledMarkerLayoutUpdateIdentifier) {
-            cancelAnimationFrame(this._scheduledMarkerLayoutUpdateIdentifier);
-            delete this._scheduledMarkerLayoutUpdateIdentifier;
-        }
-
-        if (this._scheduledSelectionLayoutUpdateIdentifier) {
-            cancelAnimationFrame(this._scheduledSelectionLayoutUpdateIdentifier);
-            delete this._scheduledSelectionLayoutUpdateIdentifier;
-        }
-
-        this._scheduledLayoutUpdateIdentifier = requestAnimationFrame(this.updateLayout.bind(this));
-    }
-
</del><span class="cx">     _needsMarkerLayout()
</span><span class="cx">     {
</span><span class="cx">         // If layout is scheduled, abort since markers will be updated when layout happens.
</span><del>-        if (this._scheduledLayoutUpdateIdentifier)
</del><ins>+        if (this.layoutPending)
</ins><span class="cx">             return;
</span><span class="cx"> 
</span><span class="cx">         if (this._scheduledMarkerLayoutUpdateIdentifier)
</span><span class="cx">             return;
</span><span class="cx"> 
</span><del>-        function update()
-        {
-            delete this._scheduledMarkerLayoutUpdateIdentifier;
</del><ins>+        this._scheduledMarkerLayoutUpdateIdentifier = requestAnimationFrame(() =&gt; {
+            this._scheduledMarkerLayoutUpdateIdentifier = undefined;
</ins><span class="cx"> 
</span><del>-            var visibleWidth = this._element.clientWidth;
</del><ins>+            let visibleWidth = this.element.clientWidth;
</ins><span class="cx">             if (visibleWidth &lt;= 0)
</span><span class="cx">                 return;
</span><span class="cx"> 
</span><span class="cx">             this._updateMarkers(visibleWidth, this.duration);
</span><del>-        }
-
-        this._scheduledMarkerLayoutUpdateIdentifier = requestAnimationFrame(update.bind(this));
</del><ins>+        });
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     _needsSelectionLayout()
</span><span class="lines">@@ -533,36 +518,34 @@
</span><span class="cx">             return;
</span><span class="cx"> 
</span><span class="cx">         // If layout is scheduled, abort since the selection will be updated when layout happens.
</span><del>-        if (this._scheduledLayoutUpdateIdentifier)
</del><ins>+        if (this.layoutPending)
</ins><span class="cx">             return;
</span><span class="cx"> 
</span><span class="cx">         if (this._scheduledSelectionLayoutUpdateIdentifier)
</span><span class="cx">             return;
</span><span class="cx"> 
</span><del>-        function update()
-        {
-            delete this._scheduledSelectionLayoutUpdateIdentifier;
</del><ins>+        this._scheduledSelectionLayoutUpdateIdentifier = requestAnimationFrame(() =&gt; {
+            this._scheduledSelectionLayoutUpdateIdentifier = undefined;
</ins><span class="cx"> 
</span><del>-            var visibleWidth = this._element.clientWidth;
</del><ins>+            let visibleWidth = this.element.clientWidth;
</ins><span class="cx">             if (visibleWidth &lt;= 0)
</span><span class="cx">                 return;
</span><span class="cx"> 
</span><span class="cx">             this._updateSelection(visibleWidth, this.duration);
</span><del>-        }
-
-        this._scheduledSelectionLayoutUpdateIdentifier = requestAnimationFrame(update.bind(this));
</del><ins>+        });
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     _recalculate()
</span><span class="cx">     {
</span><del>-        var visibleWidth = this._element.clientWidth;
</del><ins>+        let visibleWidth = this.element.clientWidth;
</ins><span class="cx">         if (visibleWidth &lt;= 0)
</span><span class="cx">             return 0;
</span><span class="cx"> 
</span><ins>+        let duration;
</ins><span class="cx">         if (this._endTimePinned)
</span><del>-            var duration = this._endTime - this._startTime;
</del><ins>+            duration = this._endTime - this._startTime;
</ins><span class="cx">         else
</span><del>-            var duration = visibleWidth * this._secondsPerPixel;
</del><ins>+            duration = visibleWidth * this._secondsPerPixel;
</ins><span class="cx"> 
</span><span class="cx">         this._secondsPerPixel = duration / visibleWidth;
</span><span class="cx"> 
</span><span class="lines">@@ -588,27 +571,27 @@
</span><span class="cx">     {
</span><span class="cx">         if (this._scheduledMarkerLayoutUpdateIdentifier) {
</span><span class="cx">             cancelAnimationFrame(this._scheduledMarkerLayoutUpdateIdentifier);
</span><del>-            delete this._scheduledMarkerLayoutUpdateIdentifier;
</del><ins>+            this._scheduledMarkerLayoutUpdateIdentifier = undefined;
</ins><span class="cx">         }
</span><span class="cx"> 
</span><del>-        this._markerElementMap.forEach(function(markerElement, marker) {
-            var newLeftPosition = (marker.time - this._startTime) / duration;
</del><ins>+        for (let [marker, markerElement] of this._markerElementMap) {
+            let newLeftPosition = (marker.time - this._startTime) / duration;
</ins><span class="cx"> 
</span><span class="cx">             this._updatePositionOfElement(markerElement, newLeftPosition, visibleWidth);
</span><span class="cx"> 
</span><span class="cx">             if (!markerElement.parentNode)
</span><span class="cx">                 this._markersElement.appendChild(markerElement);
</span><del>-        }, this);
</del><ins>+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     _updateSelection(visibleWidth, duration)
</span><span class="cx">     {
</span><span class="cx">         if (this._scheduledSelectionLayoutUpdateIdentifier) {
</span><span class="cx">             cancelAnimationFrame(this._scheduledSelectionLayoutUpdateIdentifier);
</span><del>-            delete this._scheduledSelectionLayoutUpdateIdentifier;
</del><ins>+            this._scheduledSelectionLayoutUpdateIdentifier = undefined;
</ins><span class="cx">         }
</span><span class="cx"> 
</span><del>-        this._element.classList.toggle(WebInspector.TimelineRuler.AllowsTimeRangeSelectionStyleClassName, this._allowsTimeRangeSelection);
</del><ins>+        this.element.classList.toggle(WebInspector.TimelineRuler.AllowsTimeRangeSelectionStyleClassName, this._allowsTimeRangeSelection);
</ins><span class="cx"> 
</span><span class="cx">         if (!this._allowsTimeRangeSelection)
</span><span class="cx">             return;
</span><span class="lines">@@ -640,11 +623,11 @@
</span><span class="cx">         this._rightSelectionHandleElement.title = formattedEndTimeText;
</span><span class="cx"> 
</span><span class="cx">         if (!this._selectionDragElement.parentNode) {
</span><del>-            this._element.appendChild(this._selectionDragElement);
-            this._element.appendChild(this._leftShadedAreaElement);
-            this._element.appendChild(this._leftSelectionHandleElement);
-            this._element.appendChild(this._rightShadedAreaElement);
-            this._element.appendChild(this._rightSelectionHandleElement);
</del><ins>+            this.element.appendChild(this._selectionDragElement);
+            this.element.appendChild(this._leftShadedAreaElement);
+            this.element.appendChild(this._leftSelectionHandleElement);
+            this.element.appendChild(this._rightShadedAreaElement);
+            this.element.appendChild(this._rightSelectionHandleElement);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         this._dispatchTimeRangeSelectionChangedEvent();
</span><span class="lines">@@ -688,7 +671,7 @@
</span><span class="cx">             return;
</span><span class="cx"> 
</span><span class="cx">         this._selectionIsMove = event.target === this._selectionDragElement;
</span><del>-        this._rulerBoundingClientRect = this._element.getBoundingClientRect();
</del><ins>+        this._rulerBoundingClientRect = this.element.getBoundingClientRect();
</ins><span class="cx"> 
</span><span class="cx">         if (this._selectionIsMove) {
</span><span class="cx">             this._lastMousePosition = event.pageX;
</span><span class="lines">@@ -713,12 +696,13 @@
</span><span class="cx">     {
</span><span class="cx">         console.assert(event.button === 0);
</span><span class="cx"> 
</span><ins>+        let currentMousePosition;
</ins><span class="cx">         if (this._selectionIsMove) {
</span><del>-            var currentMousePosition = Math.max(this._moveSelectionMaximumLeftOffset, Math.min(this._moveSelectionMaximumRightOffset, event.pageX));
</del><ins>+            currentMousePosition = Math.max(this._moveSelectionMaximumLeftOffset, Math.min(this._moveSelectionMaximumRightOffset, event.pageX));
</ins><span class="cx"> 
</span><del>-            var offsetTime = (currentMousePosition - this._lastMousePosition) * this.secondsPerPixel;
-            var selectionDuration = this.selectionEndTime - this.selectionStartTime;
-            var oldSelectionStartTime = this.selectionStartTime;
</del><ins>+            let offsetTime = (currentMousePosition - this._lastMousePosition) * this.secondsPerPixel;
+            let selectionDuration = this.selectionEndTime - this.selectionStartTime;
+            let oldSelectionStartTime = this.selectionStartTime;
</ins><span class="cx"> 
</span><span class="cx">             this.selectionStartTime = Math.max(this.startTime, Math.min(this.selectionStartTime + offsetTime, this.endTime - selectionDuration));
</span><span class="cx">             this.selectionEndTime = this.selectionStartTime + selectionDuration;
</span><span class="lines">@@ -727,26 +711,26 @@
</span><span class="cx">                 // When snapping we need to check the mouse position delta relative to the last snap, rather than the
</span><span class="cx">                 // last mouse move. If a snap occurs we adjust for the amount the cursor drifted, so that the mouse
</span><span class="cx">                 // position relative to the selection remains constant.
</span><del>-                var snapOffset = this.selectionStartTime - oldSelectionStartTime;
</del><ins>+                let snapOffset = this.selectionStartTime - oldSelectionStartTime;
</ins><span class="cx">                 if (!snapOffset)
</span><span class="cx">                     return;
</span><span class="cx"> 
</span><del>-                var positionDrift = (offsetTime - snapOffset * this.snapInterval) / this.secondsPerPixel;
</del><ins>+                let positionDrift = (offsetTime - snapOffset * this.snapInterval) / this.secondsPerPixel;
</ins><span class="cx">                 currentMousePosition -= positionDrift;
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="cx">             this._lastMousePosition = currentMousePosition;
</span><span class="cx">         } else {
</span><del>-            var currentMousePosition = event.pageX - this._rulerBoundingClientRect.left;
</del><ins>+            currentMousePosition = event.pageX - this._rulerBoundingClientRect.left;
</ins><span class="cx"> 
</span><span class="cx">             this.selectionStartTime = Math.max(this.startTime, this.startTime + (Math.min(currentMousePosition, this._mouseDownPosition) * this.secondsPerPixel));
</span><span class="cx">             this.selectionEndTime = Math.min(this.startTime + (Math.max(currentMousePosition, this._mouseDownPosition) * this.secondsPerPixel), this.endTime);
</span><span class="cx"> 
</span><span class="cx">             // Turn on col-resize cursor style once dragging begins, rather than on the initial mouse down.
</span><del>-            this._element.classList.add(WebInspector.TimelineRuler.ResizingSelectionStyleClassName);
</del><ins>+            this.element.classList.add(WebInspector.TimelineRuler.ResizingSelectionStyleClassName);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><del>-        this._updateSelection(this._element.clientWidth, this.duration);
</del><ins>+        this._updateSelection(this.element.clientWidth, this.duration);
</ins><span class="cx"> 
</span><span class="cx">         event.preventDefault();
</span><span class="cx">         event.stopPropagation();
</span><span class="lines">@@ -757,7 +741,7 @@
</span><span class="cx">         console.assert(event.button === 0);
</span><span class="cx"> 
</span><span class="cx">         if (!this._selectionIsMove) {
</span><del>-            this._element.classList.remove(WebInspector.TimelineRuler.ResizingSelectionStyleClassName);
</del><ins>+            this.element.classList.remove(WebInspector.TimelineRuler.ResizingSelectionStyleClassName);
</ins><span class="cx"> 
</span><span class="cx">             if (this.selectionEndTime - this.selectionStartTime &lt; this.minimumSelectionDuration) {
</span><span class="cx">                 // The section is smaller than allowed, grow in the direction of the drag to meet the minumum.
</span><span class="lines">@@ -797,7 +781,7 @@
</span><span class="cx">             return;
</span><span class="cx"> 
</span><span class="cx">         this._dragHandleIsStartTime = event.target === this._leftSelectionHandleElement;
</span><del>-        this._mouseDownPosition = event.pageX - this._element.totalOffsetLeft;
</del><ins>+        this._mouseDownPosition = event.pageX - this.element.totalOffsetLeft;
</ins><span class="cx"> 
</span><span class="cx">         this._selectionHandleMouseMoveEventListener = this._handleSelectionHandleMouseMove.bind(this);
</span><span class="cx">         this._selectionHandleMouseUpEventListener = this._handleSelectionHandleMouseUp.bind(this);
</span><span class="lines">@@ -806,7 +790,7 @@
</span><span class="cx">         document.addEventListener(&quot;mousemove&quot;, this._selectionHandleMouseMoveEventListener);
</span><span class="cx">         document.addEventListener(&quot;mouseup&quot;, this._selectionHandleMouseUpEventListener);
</span><span class="cx"> 
</span><del>-        this._element.classList.add(WebInspector.TimelineRuler.ResizingSelectionStyleClassName);
</del><ins>+        this.element.classList.add(WebInspector.TimelineRuler.ResizingSelectionStyleClassName);
</ins><span class="cx"> 
</span><span class="cx">         event.preventDefault();
</span><span class="cx">         event.stopPropagation();
</span><span class="lines">@@ -816,19 +800,19 @@
</span><span class="cx">     {
</span><span class="cx">         console.assert(event.button === 0);
</span><span class="cx"> 
</span><del>-        var currentMousePosition = event.pageX - this._element.totalOffsetLeft;
-        var currentTime = this.startTime + (currentMousePosition * this.secondsPerPixel);
</del><ins>+        let currentMousePosition = event.pageX - this.element.totalOffsetLeft;
+        let currentTime = this.startTime + (currentMousePosition * this.secondsPerPixel);
</ins><span class="cx">         if (this.snapInterval)
</span><span class="cx">             currentTime = this._snapValue(currentTime);
</span><span class="cx"> 
</span><span class="cx">         if (event.altKey &amp;&amp; !event.ctrlKey &amp;&amp; !event.metaKey &amp;&amp; !event.shiftKey) {
</span><span class="cx">             // Resize the selection on both sides when the Option keys is held down.
</span><span class="cx">             if (this._dragHandleIsStartTime) {
</span><del>-                var timeDifference = currentTime - this.selectionStartTime;
</del><ins>+                let timeDifference = currentTime - this.selectionStartTime;
</ins><span class="cx">                 this.selectionStartTime = Math.max(this.startTime, Math.min(currentTime, this.selectionEndTime - this.minimumSelectionDuration));
</span><span class="cx">                 this.selectionEndTime = Math.min(Math.max(this.selectionStartTime + this.minimumSelectionDuration, this.selectionEndTime - timeDifference), this.endTime);
</span><span class="cx">             } else {
</span><del>-                var timeDifference = currentTime - this.selectionEndTime;
</del><ins>+                let timeDifference = currentTime - this.selectionEndTime;
</ins><span class="cx">                 this.selectionEndTime = Math.min(Math.max(this.selectionStartTime + this.minimumSelectionDuration, currentTime), this.endTime);
</span><span class="cx">                 this.selectionStartTime = Math.max(this.startTime, Math.min(this.selectionStartTime - timeDifference, this.selectionEndTime - this.minimumSelectionDuration));
</span><span class="cx">             }
</span><span class="lines">@@ -840,7 +824,7 @@
</span><span class="cx">                 this.selectionEndTime = Math.min(Math.max(this.selectionStartTime + this.minimumSelectionDuration, currentTime), this.endTime);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        this._updateSelection(this._element.clientWidth, this.duration);
</del><ins>+        this._updateSelection(this.element.clientWidth, this.duration);
</ins><span class="cx"> 
</span><span class="cx">         event.preventDefault();
</span><span class="cx">         event.stopPropagation();
</span><span class="lines">@@ -850,7 +834,7 @@
</span><span class="cx">     {
</span><span class="cx">         console.assert(event.button === 0);
</span><span class="cx"> 
</span><del>-        this._element.classList.remove(WebInspector.TimelineRuler.ResizingSelectionStyleClassName);
</del><ins>+        this.element.classList.remove(WebInspector.TimelineRuler.ResizingSelectionStyleClassName);
</ins><span class="cx"> 
</span><span class="cx">         document.removeEventListener(&quot;mousemove&quot;, this._selectionHandleMouseMoveEventListener);
</span><span class="cx">         document.removeEventListener(&quot;mouseup&quot;, this._selectionHandleMouseUpEventListener);
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsViewjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/View.js (192069 => 192070)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/View.js        2015-11-05 20:37:24 UTC (rev 192069)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/View.js        2015-11-05 21:17:41 UTC (rev 192070)
</span><span class="lines">@@ -41,6 +41,11 @@
</span><span class="cx">         return this._element;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    get layoutPending()
+    {
+        return !!this._scheduledLayoutUpdateIdentifier;
+    }
+
</ins><span class="cx">     get subviews()
</span><span class="cx">     {
</span><span class="cx">         return this._subviews;
</span></span></pre>
</div>
</div>

</body>
</html>