Bug 1457719 - Part 3 - Replace "autorepeatbutton" with "toolbarbutton" in the base "arrowscrollbox" binding. r=dao draft
authorPaolo Amadini <paolo.mozmail@amadzone.org>
Fri, 01 Jun 2018 11:15:36 +0100
changeset 802739 16600f0916ac4188ceaf8dff61fb61021cc8da5a
parent 802738 672f94e2b638e7112c9b6bbe60b1c6dd9d6950b3
child 802740 ae1bafe7144f6f428e2ef4e7047d5c64e0a19e8c
push id111939
push userpaolo.mozmail@amadzone.org
push dateFri, 01 Jun 2018 10:30:29 +0000
reviewersdao
bugs1457719
milestone62.0a1
Bug 1457719 - Part 3 - Replace "autorepeatbutton" with "toolbarbutton" in the base "arrowscrollbox" binding. r=dao This aligns the markup of the base "arrowscrollbox" binding with the "clicktoscroll" derived binding, while still keeping different event handlers. MozReview-Commit-ID: 9eYt1kyjgP9
browser/themes/shared/customizableui/panelUI.inc.css
toolkit/content/widgets/scrollbox.xml
toolkit/themes/linux/global/scrollbox.css
toolkit/themes/osx/global/global.css
toolkit/themes/osx/global/scrollbox.css
toolkit/themes/windows/global/scrollbox.css
--- a/browser/themes/shared/customizableui/panelUI.inc.css
+++ b/browser/themes/shared/customizableui/panelUI.inc.css
@@ -189,24 +189,16 @@ panelview {
 .cui-widget-panelview menuitem.subviewbutton.panel-subview-footer {
   margin: 4px 0 0;
 }
 
 .cui-widget-panelview .subviewbutton.panel-subview-footer > .menu-text {
   -moz-box-flex: 1;
 }
 
-#appMenu-popup > arrowscrollbox > autorepeatbutton {
-  display: none;
-}
-
-#appMenu-popup > arrowscrollbox > scrollbox {
-  overflow: visible;
-}
-
 #appMenu-popup > .panel-arrowcontainer > .panel-arrowcontent,
 panel[photon] > .panel-arrowcontainer > .panel-arrowcontent {
   overflow: hidden;
 }
 
 .cui-widget-panel > .panel-arrowcontainer > .panel-arrowcontent > .popup-internal-box {
   padding: 0;
 }
@@ -1104,18 +1096,18 @@ menuitem.panel-subview-footer@menuStateA
 #BMB_bookmarksPopup .subviewbutton:not([disabled="true"]) {
   color: inherit;
 }
 
 #BMB_bookmarksPopup .subviewbutton > .menu-iconic-left {
   margin-inline-end: 3px;
 }
 
-#BMB_bookmarksPopup .panel-arrowcontainer > .panel-arrowcontent > .popup-internal-box > .autorepeatbutton-up,
-#BMB_bookmarksPopup .panel-arrowcontainer > .panel-arrowcontent > .popup-internal-box > .autorepeatbutton-down {
+#BMB_bookmarksPopup .panel-arrowcontainer > .panel-arrowcontent > .popup-internal-box > .scrollbutton-up,
+#BMB_bookmarksPopup .panel-arrowcontainer > .panel-arrowcontent > .popup-internal-box > .scrollbutton-down {
   -moz-appearance: none;
   margin-top: 0;
   margin-bottom: 0;
 }
 
 /* Remove padding on xul:arrowscrollbox to avoid extra padding on footer */
 #BMB_bookmarksPopup arrowscrollbox {
   padding-bottom: 0px;
--- a/toolkit/content/widgets/scrollbox.xml
+++ b/toolkit/content/widgets/scrollbox.xml
@@ -27,47 +27,57 @@
   </binding>
 
   <binding id="arrowscrollbox" extends="chrome://global/content/bindings/general.xml#basecontrol">
     <resources>
       <stylesheet src="chrome://global/skin/scrollbox.css"/>
     </resources>
 
     <content>
-      <xul:autorepeatbutton class="autorepeatbutton-up"
-                            anonid="scrollbutton-up"
-                            xbl:inherits="orient,collapsed=notoverflowing,disabled=scrolledtostart"
-                            oncommand="_autorepeatbuttonScroll(event);"/>
+      <xul:toolbarbutton class="scrollbutton-up"
+                         anonid="scrollbutton-up"
+                         xbl:inherits="orient,collapsed=notoverflowing,disabled=scrolledtostart"
+                         onmouseover="_startScroll(-1);"
+                         onmouseout="_stopScroll();"/>
       <xul:spacer class="arrowscrollbox-overflow-start-indicator"
                   xbl:inherits="collapsed=scrolledtostart"/>
       <xul:scrollbox class="arrowscrollbox-scrollbox"
                      anonid="scrollbox"
                      flex="1"
                      xbl:inherits="orient,align,pack,dir,smoothscroll">
         <children/>
       </xul:scrollbox>
       <xul:spacer class="arrowscrollbox-overflow-end-indicator"
                   xbl:inherits="collapsed=scrolledtoend"/>
-      <xul:autorepeatbutton class="autorepeatbutton-down"
-                            anonid="scrollbutton-down"
-                            xbl:inherits="orient,collapsed=notoverflowing,disabled=scrolledtoend"
-                            oncommand="_autorepeatbuttonScroll(event);"/>
+      <xul:toolbarbutton class="scrollbutton-down"
+                         anonid="scrollbutton-down"
+                         xbl:inherits="orient,collapsed=notoverflowing,disabled=scrolledtoend"
+                         onmouseover="_startScroll(1);"
+                         onmouseout="_stopScroll();"/>
     </content>
 
     <implementation>
       <constructor><![CDATA[
         if (!this.hasAttribute("smoothscroll")) {
           this.smoothScroll = this._prefBranch
                                   .getBoolPref("toolkit.scrollbox.smoothScroll", true);
         }
 
         this.setAttribute("notoverflowing", "true");
         this._updateScrollButtonsDisabledState();
       ]]></constructor>
 
+      <destructor><![CDATA[
+        // Release timer to avoid reference cycles.
+        if (this._scrollTimer) {
+          this._scrollTimer.cancel();
+          this._scrollTimer = null;
+        }
+      ]]></destructor>
+
       <field name="_scrollbox">
         document.getAnonymousElementByAttribute(this, "anonid", "scrollbox");
       </field>
       <field name="_scrollButtonUp">
         document.getAnonymousElementByAttribute(this, "anonid", "scrollbutton-up");
       </field>
       <field name="_scrollButtonDown">
         document.getAnonymousElementByAttribute(this, "anonid", "scrollbutton-down");
@@ -315,26 +325,45 @@
             mid = Math.max(mid - 1, 0);
           else if (aPhysicalScrollDir > 0 && rect[end] < aX)
             mid = Math.min(mid + 1, elements.length - 1);
 
           return elements[mid];
         ]]></body>
       </method>
 
-      <method name="_autorepeatbuttonScroll">
-        <parameter name="event"/>
+      <method name="_startScroll">
+        <parameter name="index"/>
         <body><![CDATA[
-          var dir = event.originalTarget == this._scrollButtonUp ? -1 : 1;
-          if (this._isRTLScrollbox)
-            dir *= -1;
+          if (this._isRTLScrollbox) {
+            index *= -1;
+          }
+
+          if (!this._scrollTimer) {
+            this._scrollTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+          } else {
+            this._scrollTimer.cancel();
+          }
+
+          let callback = () => this.scrollByPixels(this.scrollIncrement * index);
 
-          this.scrollByPixels(this.scrollIncrement * dir);
+          // Use the same REPEAT_DELAY as "nsRepeatService.h".
+          let scrollDelay = /Mac/.test(navigator.platform) ? 25 : 50;
 
-          event.stopPropagation();
+          this._scrollTimer.initWithCallback(callback, scrollDelay,
+                                             Ci.nsITimer.TYPE_REPEATING_SLACK);
+          callback();
+        ]]>
+        </body>
+      </method>
+
+      <method name="_stopScroll">
+        <body><![CDATA[
+          if (this._scrollTimer)
+            this._scrollTimer.cancel();
         ]]></body>
       </method>
 
       <method name="scrollByPixels">
         <parameter name="aPixels"/>
         <parameter name="aInstant"/>
         <body><![CDATA[
           let scrollOptions = { behavior: aInstant ? "instant" : "auto" };
--- a/toolkit/themes/linux/global/scrollbox.css
+++ b/toolkit/themes/linux/global/scrollbox.css
@@ -1,33 +1,32 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 
-.autorepeatbutton-up > .autorepeatbutton-icon,
 .scrollbutton-up > .toolbarbutton-icon {
   -moz-appearance: button-arrow-up;
 }
 
-.autorepeatbutton-down > .autorepeatbutton-icon,
 .scrollbutton-down > .toolbarbutton-icon {
   -moz-appearance: button-arrow-down;
 }
 
-.autorepeatbutton-up[orient="horizontal"] > .autorepeatbutton-icon,
 .scrollbutton-up[orient="horizontal"] > .toolbarbutton-icon {
   -moz-appearance: button-arrow-previous;
 }
 
-.autorepeatbutton-down[orient="horizontal"] > .autorepeatbutton-icon,
 .scrollbutton-down[orient="horizontal"] > .toolbarbutton-icon {
   -moz-appearance: button-arrow-next;
 }
 
 :-moz-any(.scrollbutton-up, .scrollbutton-down) > .toolbarbutton-text {
   display: none;
 }
 
-autorepeatbutton {
+arrowscrollbox:not([clicktoscroll="true"]) > .scrollbutton-up,
+arrowscrollbox:not([clicktoscroll="true"]) > .scrollbutton-down {
+  -moz-appearance: none;
   border: 1px solid ThreeDShadow;
+  padding: 0;
 }
--- a/toolkit/themes/osx/global/global.css
+++ b/toolkit/themes/osx/global/global.css
@@ -275,49 +275,51 @@ popupnotificationcontent {
 }
 
 .autoscroller[scrolldir="EW"] {
   background-image: url("chrome://global/skin/icons/autoscroll-horizontal.svg");
 }
 
 /* autorepeatbuttons in menus */
 
-.popup-internal-box > autorepeatbutton {
+.popup-internal-box > .scrollbutton-up,
+.popup-internal-box > .scrollbutton-down {
   height: 15px;
   position: relative;
   list-style-image: none;
   /* Here we're using a little magic.
    * The arrow button is supposed to overlay the scrollbox, blocking
    * everything under it from reaching the screen. However, the menu background
    * is slightly transparent, so how can we block something completely without
    * messing up the transparency? It's easy: The native theming of the
    * "menuitem" appearance uses CGContextClearRect before drawing, which
    * clears everything under it.
    * Without help from native theming this effect wouldn't be achievable.
    */
   -moz-appearance: menuitem;
 }
 
-.popup-internal-box > .autorepeatbutton-up {
+.popup-internal-box > .scrollbutton-up {
   padding-top: 1px; /* 4px padding-top from the .popup-internal-box. */
   margin-bottom: -15px;
 }
 
-.popup-internal-box > .autorepeatbutton-up > .autorepeatbutton-icon {
+.popup-internal-box > .scrollbutton-up > .toolbarbutton-icon {
   -moz-appearance: button-arrow-up;
 }
 
-.popup-internal-box > .autorepeatbutton-down {
+.popup-internal-box > .scrollbutton-down {
   padding-top: 5px;
   margin-top: -15px;
 }
 
-.popup-internal-box > .autorepeatbutton-down > .autorepeatbutton-icon {
+.popup-internal-box > .scrollbutton-down > .toolbarbutton-icon {
   -moz-appearance: button-arrow-down;
 }
 
-.popup-internal-box > autorepeatbutton[disabled="true"] {
+.popup-internal-box > .scrollbutton-up[disabled="true"],
+.popup-internal-box > .scrollbutton-down[disabled="true"] {
   visibility: collapse;
 }
 
 /* :::::: Close button icons ::::: */
 
 %include ../../shared/close-icon.inc.css
--- a/toolkit/themes/osx/global/scrollbox.css
+++ b/toolkit/themes/osx/global/scrollbox.css
@@ -1,62 +1,54 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
  
 /* Horizontal enabled */
-.autorepeatbutton-up[orient="horizontal"],
 .scrollbutton-up[orient="horizontal"] {
   list-style-image: url("chrome://global/skin/arrow/arrow-lft-sharp.gif");
   -moz-image-region: auto; /* cut off inheritance */
 }
- 
-.autorepeatbutton-down[orient="horizontal"],
+
 .scrollbutton-down[orient="horizontal"] {
   list-style-image: url("chrome://global/skin/arrow/arrow-rit-sharp.gif");
   -moz-image-region: auto; /* cut off inheritance */
 }
 
 /* Horizontal disabled */
-.autorepeatbutton-up[orient="horizontal"][disabled="true"],
 .scrollbutton-up[orient="horizontal"][disabled="true"] {
   list-style-image: url("chrome://global/skin/arrow/arrow-lft-dis.gif");
   -moz-image-region: auto; /* cut off inheritance */
 }
- 
-.autorepeatbutton-down[orient="horizontal"][disabled="true"],
+
 .scrollbutton-down[orient="horizontal"][disabled="true"] {
   list-style-image: url("chrome://global/skin/arrow/arrow-rit-dis.gif");
   -moz-image-region: auto; /* cut off inheritance */
 }
 
 /* Vertical enabled */
-.autorepeatbutton-up:not([orient="horizontal"]),
-.scrollbutton-up {
+.scrollbutton-up:not([orient="horizontal"]) {
   list-style-image: url("chrome://global/skin/arrow/arrow-up-sharp.gif");
   -moz-image-region: auto; /* cut off inheritance */
 }
 
-.autorepeatbutton-down:not([orient="horizontal"]),
-.scrollbutton-down {
+.scrollbutton-down:not([orient="horizontal"]) {
   list-style-image: url("chrome://global/skin/arrow/arrow-dn-sharp.gif");
   -moz-image-region: auto; /* cut off inheritance */
 }
 
 /* Vertical disabled */
-.autorepeatbutton-up[disabled="true"]:not([orient="horizontal"]),
-.scrollbutton-up[disabled="true"] {
+.scrollbutton-up[disabled="true"]:not([orient="horizontal"]) {
   list-style-image: url("chrome://global/skin/arrow/arrow-up-dis.gif");
   -moz-image-region: auto; /* cut off inheritance */
 }
 
-.autorepeatbutton-down[disabled="true"]:not([orient="horizontal"]),
-.scrollbutton-down[disabled="true"] {
+.scrollbutton-down[disabled="true"]:not([orient="horizontal"]) {
   list-style-image: url("chrome://global/skin/arrow/arrow-dn-dis.gif");
   -moz-image-region: auto; /* cut off inheritance */
 }
 
 .scrollbutton-up > .toolbarbutton-text,
 .scrollbutton-down > .toolbarbutton-text {
   display: none;
 }
--- a/toolkit/themes/windows/global/scrollbox.css
+++ b/toolkit/themes/windows/global/scrollbox.css
@@ -4,97 +4,86 @@
 
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 
 /*
  * Scroll arrows
  */
 
 /* Horizontal enabled */
-.autorepeatbutton-up[orient="horizontal"],
-.autorepeatbutton-down:-moz-locale-dir(rtl)[orient="horizontal"],
 .scrollbutton-up[orient="horizontal"],
 .scrollbutton-down:-moz-locale-dir(rtl)[orient="horizontal"] {
   list-style-image: url("chrome://global/skin/arrow/arrow-lft.gif");
   -moz-image-region: auto; /* cut off inheritance */
 }
 
-.autorepeatbutton-down[orient="horizontal"],
-.autorepeatbutton-up:-moz-locale-dir(rtl)[orient="horizontal"],
 .scrollbutton-down[orient="horizontal"],
 .scrollbutton-up:-moz-locale-dir(rtl)[orient="horizontal"] {
   list-style-image: url("chrome://global/skin/arrow/arrow-rit.gif");
   -moz-image-region: auto; /* cut off inheritance */
 }
 
  /* Horizontal disabled */
-.autorepeatbutton-up[orient="horizontal"][disabled="true"],
-.autorepeatbutton-down:-moz-locale-dir(rtl)[orient="horizontal"][disabled="true"],
 .scrollbutton-up[orient="horizontal"][disabled="true"],
 .scrollbutton-down:-moz-locale-dir(rtl)[orient="horizontal"][disabled="true"] {
   list-style-image: url("chrome://global/skin/arrow/arrow-lft-dis.gif");
   -moz-image-region: auto; /* cut off inheritance */
 }
 
-.autorepeatbutton-down[orient="horizontal"][disabled="true"],
-.autorepeatbutton-up:-moz-locale-dir(rtl)[orient="horizontal"][disabled="true"],
 .scrollbutton-down[orient="horizontal"][disabled="true"],
 .scrollbutton-up:-moz-locale-dir(rtl)[orient="horizontal"][disabled="true"] {
   list-style-image: url("chrome://global/skin/arrow/arrow-rit-dis.gif");
   -moz-image-region: auto; /* cut off inheritance */
 }
 
 /* Vertical enabled */
-.autorepeatbutton-up,
 .scrollbutton-up {
   list-style-image: url("chrome://global/skin/arrow/arrow-up.gif");
   -moz-image-region: auto; /* cut off inheritance */
 }
 
-.autorepeatbutton-down,
 .scrollbutton-down {
   list-style-image: url("chrome://global/skin/arrow/arrow-dn.gif");
   -moz-image-region: auto; /* cut off inheritance */
 }
 
 /* Vertical disabled */
-.autorepeatbutton-up[disabled="true"],
 .scrollbutton-up[disabled="true"] {
   list-style-image: url("chrome://global/skin/arrow/arrow-up-dis.gif");
   -moz-image-region: auto; /* cut off inheritance */
 }
 
-.autorepeatbutton-down[disabled="true"],
 .scrollbutton-down[disabled="true"] {
   list-style-image: url("chrome://global/skin/arrow/arrow-dn-dis.gif");
   -moz-image-region: auto; /* cut off inheritance */
 }
 
 .scrollbutton-up > .toolbarbutton-text,
 .scrollbutton-down > .toolbarbutton-text {
   display: none;
 }
 
-autorepeatbutton,
 .scrollbutton-up,
 .scrollbutton-down {
   -moz-box-align: center;
   -moz-box-pack: center;
   margin-top: 1px;
   margin-bottom: 2px;
   margin-inline-start: 1px;
   margin-inline-end: 2px;
 }
 
-autorepeatbutton {
+arrowscrollbox:not([clicktoscroll="true"]) > .scrollbutton-up,
+arrowscrollbox:not([clicktoscroll="true"]) > .scrollbutton-down {
+  -moz-appearance: none;
   border: 1px solid transparent;
   padding: 1px;
 }
 
-autorepeatbutton:not([disabled="true"]):hover,
-autorepeatbutton:not([disabled="true"]):hover:active {
+arrowscrollbox:not([clicktoscroll="true"]) > .scrollbutton-up:not([disabled="true"]):hover,
+arrowscrollbox:not([clicktoscroll="true"]) > .scrollbutton-down:not([disabled="true"]):hover {
   margin: 1px;
   border: 1px inset ThreeDFace;
   padding-top: 2px;
   padding-bottom: 1px;
   padding-inline-start: 2px;
   padding-inline-end: 1px;
 }