Bug 1387130 - Use original tabstrip scrolling behaviour when using scrollbuttons. r?dao draft
authorMike Conley <mconley@mozilla.com>
Wed, 06 Sep 2017 13:28:48 -0400
changeset 660271 0ff45571772898f74d5852243df20fb88f88775f
parent 659233 973e8b890a62aee4b3170558ac3b608928162ef6
child 730183 690fa2213a0cae0902efc7732fe7a4ece17bbd36
push id78343
push usermconley@mozilla.com
push dateWed, 06 Sep 2017 19:47:08 +0000
reviewersdao
bugs1387130, 1356705
milestone57.0a1
Bug 1387130 - Use original tabstrip scrolling behaviour when using scrollbuttons. r?dao In bug 1356705, we switched scrollbox to use CSS smooth scroll when the scrollbox is configured to scroll smoothly. This caused the tab strip to scroll with a "pulse" when using the arrow scrollbuttons. This is because we scroll by a single tab each time, as opposed to scrolling by pixels. This reverts part of bug 1356705 so that we use instant scrolling instead of smooth scrolling in the scrollbuttons case, which returns the original behaviour of the strip without the pulse. MozReview-Commit-ID: D8QQ8kQ7AjM
toolkit/content/widgets/scrollbox.xml
--- a/toolkit/content/widgets/scrollbox.xml
+++ b/toolkit/content/widgets/scrollbox.xml
@@ -655,24 +655,52 @@
           if (!document)
             aTimer.cancel();
 
           this.scrollByIndex(this._scrollIndex);
         ]]>
         </body>
       </method>
 
+      <field name="_arrowScrollAnim"><![CDATA[({
+        scrollbox: this,
+        requestHandle: 0, /* 0 indicates there is no pending request */
+        start: function arrowSmoothScroll_start() {
+          this.lastFrameTime = window.performance.now();
+          if (!this.requestHandle)
+            this.requestHandle = window.requestAnimationFrame(this.sample.bind(this));
+        },
+        stop: function arrowSmoothScroll_stop() {
+          window.cancelAnimationFrame(this.requestHandle);
+          this.requestHandle = 0;
+        },
+        sample: function arrowSmoothScroll_handleEvent(timeStamp) {
+          const scrollIndex = this.scrollbox._scrollIndex;
+          const timePassed = timeStamp - this.lastFrameTime;
+          this.lastFrameTime = timeStamp;
+
+          const scrollDelta = 0.5 * timePassed * scrollIndex;
+          this.scrollbox.scrollByPixels(scrollDelta, true);
+          this.requestHandle = window.requestAnimationFrame(this.sample.bind(this));
+        }
+      })]]></field>
+
       <method name="_startScroll">
         <parameter name="index"/>
         <body><![CDATA[
           if (this._isRTLScrollbox)
             index *= -1;
           this._scrollIndex = index;
           this._mousedown = true;
 
+          if (this.smoothScroll) {
+            this._arrowScrollAnim.start();
+            return;
+          }
+
           if (!this._scrollTimer)
             this._scrollTimer =
               Components.classes["@mozilla.org/timer;1"]
                         .createInstance(Components.interfaces.nsITimer);
           else
             this._scrollTimer.cancel();
 
           this._scrollTimer.initWithCallback(this, this._scrollDelay,
@@ -682,17 +710,23 @@
         </body>
       </method>
 
       <method name="_stopScroll">
         <body><![CDATA[
           if (this._scrollTimer)
             this._scrollTimer.cancel();
           this._mousedown = false;
+          if (!this._scrollIndex || !this.smoothScroll)
+            return;
+
+          this.scrollByIndex(this._scrollIndex);
           this._scrollIndex = 0;
+
+          this._arrowScrollAnim.stop();
         ]]></body>
       </method>
 
       <method name="_pauseScroll">
         <body><![CDATA[
           if (this._mousedown) {
             this._stopScroll();
             this._mousedown = true;