Bug 1403563 - Allow multiple wheel events to accelerate scrollbox scrolling. r?dao draft
authorMike Conley <mconley@mozilla.com>
Wed, 08 Nov 2017 17:05:06 -0500
changeset 698449 388439c5314c8855b31704f49443b291a16a020c
parent 696646 896f1c228a7bfb4f46b7e18215b1a4b5600564b4
child 704347 40b1c7b6227a7e634baa7cd2c0b938478c11a9c6
push id89296
push usermconley@mozilla.com
push dateWed, 15 Nov 2017 20:27:47 +0000
reviewersdao
bugs1403563
milestone58.0a1
Bug 1403563 - Allow multiple wheel events to accelerate scrollbox scrolling. r?dao MozReview-Commit-ID: Lo7HxK6TGwd
toolkit/content/widgets/scrollbox.xml
--- a/toolkit/content/widgets/scrollbox.xml
+++ b/toolkit/content/widgets/scrollbox.xml
@@ -145,16 +145,24 @@
           // the height (at vertical scrollbox) of the scrolled elements.
           // However, the elements may have different width or height.  So,
           // for consistent speed, let's use avalage with of the elements.
           var elements = this._getScrollableElements();
           return elements.length && (this.scrollSize / elements.length);
         ]]></getter>
       </property>
 
+      <property name="scrollPosition" readonly="true">
+        <getter><![CDATA[
+          return this.orient == "vertical" ?
+                 this._scrollbox.scrollTop :
+                 this._scrollbox.scrollLeft;
+        ]]></getter>
+      </property>
+
       <field name="_startEndProps"><![CDATA[
         this.orient == "vertical" ? ["top", "bottom"] : ["left", "right"];
       ]]></field>
 
       <field name="_isRTLScrollbox"><![CDATA[
         this.orient != "vertical" &&
         document.defaultView.getComputedStyle(this._scrollbox).direction == "rtl";
       ]]></field>
@@ -453,16 +461,20 @@
                 this.setAttribute("scrolledtostart", "true");
               } else {
                 this.removeAttribute("scrolledtostart");
               }
             }, 0);
           });
         ]]></body>
       </method>
+
+      <field name="_isScrolling">false</field>
+      <field name="_destination">0</field>
+      <field name="_direction">0</field>
     </implementation>
 
     <handlers>
       <handler event="wheel"><![CDATA[
         let doScroll = false;
         let instant;
         let scrollAmount = 0;
         if (this.orient == "vertical") {
@@ -499,16 +511,27 @@
           }
 
           if (this._prevMouseScrolls.length > 1)
             this._prevMouseScrolls.shift();
           this._prevMouseScrolls.push(isVertical);
         }
 
         if (doScroll) {
+          let direction = scrollAmount < 0 ? -1 : 1;
+          let startPos = this.scrollPosition;
+
+          if (!this._isScrolling || this._direction != direction) {
+            this._destination = startPos + scrollAmount;
+            this._direction = direction;
+          } else {
+            // We were already in the process of scrolling in this direction
+            this._destination = this._destination + scrollAmount;
+            scrollAmount = this._destination - startPos;
+          }
           this.scrollByPixels(scrollAmount, instant);
         }
 
         event.stopPropagation();
         event.preventDefault();
       ]]></handler>
 
       <handler event="touchstart"><![CDATA[
@@ -585,18 +608,25 @@
           return;
         }
 
         this.removeAttribute("notoverflowing");
         this._updateScrollButtonsDisabledState();
       ]]></handler>
 
       <handler event="scroll"><![CDATA[
+        this._isScrolling = true;
         this._updateScrollButtonsDisabledState();
       ]]></handler>
+
+      <handler event="scrollend"><![CDATA[
+        this._isScrolling = false;
+        this._destination = 0;
+        this._direction = 0;
+      ]]></handler>
     </handlers>
   </binding>
 
   <binding id="autorepeatbutton" extends="chrome://global/content/bindings/scrollbox.xml#scrollbox-base">
     <content repeat="hover">
       <xul:image class="autorepeatbutton-icon"/>
     </content>
   </binding>