Bug 1539726 - remove tabmail-arrowscrollbox binding and handle its logic within tabmail-tabs. r=mkmelin
authorAlessandro Castellani <alessandro@thunderbird.net>
Fri, 31 May 2019 23:56:51 +0200
changeset 35738 8e9201ae828118bbc3bceb4f7413fd67b38fe1ec
parent 35737 dd45283763df5ccdc4c69a63fe0860aece16a8c8
child 35739 28e2abca59382f70c626b826d5304468676cd3cb
push id392
push userclokep@gmail.com
push dateMon, 02 Sep 2019 20:17:19 +0000
reviewersmkmelin
bugs1539726
Bug 1539726 - remove tabmail-arrowscrollbox binding and handle its logic within tabmail-tabs. r=mkmelin
mail/base/content/tabmail.css
mail/base/content/tabmail.xml
mail/themes/linux/mail/tabmail.css
mail/themes/osx/mail/tabmail.css
mail/themes/shared/mail/tabmail.css
mail/themes/windows/mail/compacttheme.css
mail/themes/windows/mail/tabmail.css
--- a/mail/base/content/tabmail.css
+++ b/mail/base/content/tabmail.css
@@ -1,20 +1,16 @@
 /* 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/. */
 
 #tabmail-tabs {
   -moz-binding: url("chrome://messenger/content/tabmail.xml#tabmail-tabs");
 }
 
-.tabmail-arrowscrollbox {
-  -moz-binding: url("chrome://messenger/content/tabmail.xml#tabmail-arrowscrollbox");
-}
-
 .tabs-alltabs-popup {
   -moz-binding: url("chrome://messenger/content/tabmail.xml#tabmail-alltabs-popup");
 }
 
 .tab-label-container {
   overflow: hidden;
 }
 
--- a/mail/base/content/tabmail.xml
+++ b/mail/base/content/tabmail.xml
@@ -1784,136 +1784,55 @@
                                     .chromeEventHandler;
           this._callTabListeners("onRefreshAttempted", [browser, ...arguments]);
         ]]></body>
       </method>
 
     </implementation>
   </binding>
 
-  <binding id="tabmail-arrowscrollbox" extends="chrome://global/content/bindings/scrollbox.xml#arrowscrollbox">
-    <content>
-      <xul:toolbarbutton class="scrollbutton-up"
-                         xbl:inherits="orient,collapsed=notoverflowing,disabled=scrolledtostart"
-                         anonid="scrollbutton-up"
-                         onmousedown="_startScroll(-1);"
-                         onmouseup="_stopScroll();"
-                         onmouseout="_stopScroll();"/>
-      <xul:spacer class="arrowscrollbox-overflow-start-indicator"
-                  xbl:inherits="collapsed=scrolledtostart"/>
-      <xul:scrollbox xbl:inherits="orient,align,pack,dir"
-                     flex="1"
-                     anonid="scrollbox">
-        <children/>
-      </xul:scrollbox>
-      <xul:spacer class="arrowscrollbox-overflow-end-indicator"
-                  xbl:inherits="collapsed=scrolledtoend"/>
-      <xul:stack align="center"
-                 pack="end"
-                 class="scrollbutton-down-stack">
-        <xul:hbox flex="1"
-                  class="scrollbutton-down-box"
-                  collapsed="true"
-                  anonid="down-box"/>
-        <xul:hbox flex="1"
-                  class="scrollbutton-down-box-animate"
-                  collapsed="true"
-                  anonid="down-box-animate"/>
-        <xul:toolbarbutton class="scrollbutton-down"
-                           xbl:inherits="orient,collapsed=notoverflowing,disabled=scrolledtoend"
-                           anonid="scrollbutton-down"
-                           onmousedown="_startScroll(1);"
-                           onmouseup="_stopScroll();"
-                           onmouseout="_stopScroll();"/>
-      </xul:stack>
-    </content>
-    <implementation>
-      <field name="_scrollButtonDownBox">
-        document.getAnonymousElementByAttribute(this, "anonid", "down-box");
-      </field>
-      <field name="_scrollButtonDownBoxAnimate">
-        document.getAnonymousElementByAttribute(this, "anonid", "down-box-animate");
-      </field>
-    </implementation>
-    <handlers>
-      <handler event="underflow"><![CDATA[
-        // filter underflow events which were dispatched on nested scrollboxes
-        if (event.target != this)
-          return;
-
-        // Ignore vertical events.
-        if (event.detail == 0) {
-          return;
-        }
-
-        this.setAttribute("notoverflowing", "true");
-        let alltabsButton = document.getElementById("alltabs-button");
-        alltabsButton.setAttribute("hidden", "true");
-      ]]></handler>
-
-      <handler event="overflow"><![CDATA[
-        // filter underflow events which were dispatched on nested scrollboxes
-        if (event.target != this)
-          return;
-
-        // Ignore vertical events.
-        if (event.detail == 0) {
-          return;
-        }
-
-        this.removeAttribute("notoverflowing");
-        let alltabsButton = document.getElementById("alltabs-button");
-        alltabsButton.removeAttribute("hidden");
-      ]]></handler>
-
-      <handler event="UpdatedScrollButtonsDisabledState"><![CDATA[
-        // filter underflow events which were dispatched on nested scrollboxes
-        if (event.target != this)
-          return;
-
-        // fix for bug #352353
-        // unlike the scrollup button on the tab strip (which is a
-        // simple toolbarbutton) the scrolldown button is
-        // a more complicated stack of boxes and a toolbarbutton
-        // so that we can animate when a tab is opened offscreen.
-        // in order to style the box with the actual background image
-        // we need to manually set the disable state to match the
-        // disable state of the toolbarbutton.
-        this._scrollButtonDownBox
-            .setAttribute("disabled", this._scrollButtonDown.disabled);
-      ]]></handler>
-
-    </handlers>
-  </binding>
   <binding id="tabmail-tabs"
            extends="chrome://global/content/bindings/tabbox.xml#tabs">
     <content context="toolbar-context-menu">
       <xul:vbox flex="1">
         <xul:hbox>
           <xul:hbox class="tab-drop-indicator-box">
             <xul:image class="tab-drop-indicator"
                        anonid="tab-drop-indicator"
                        collapsed="true"/>
           </xul:hbox>
           <xul:arrowscrollbox class="tabmail-arrowscrollbox"
                               anonid="arrowscrollbox"
                               orient="horizontal"
                               flex="1"
-                              style="min-width: 1px;">
+                              style="min-width: 1px;"
+                              clicktoscroll="true">
             <children includes="tab"/>
           </xul:arrowscrollbox>
           <children/>
           <xul:hbox class="tabs-closebutton-box"
                     anonid="tabstrip-closebutton"
                     align="center"
                     pack="end">
             <xul:image class="close-icon tabs-closebutton"/>
           </xul:hbox>
         </xul:hbox>
       </xul:vbox>
+      <xul:stack align="center"
+                 pack="end"
+                 class="scrollbutton-down-stack">
+        <xul:hbox flex="1"
+                  class="scrollbutton-down-box"
+                  collapsed="true"
+                  anonid="down-box"/>
+        <xul:hbox flex="1"
+                  class="scrollbutton-down-box-animate"
+                  collapsed="true"
+                  anonid="down-box-animate"/>
+      </xul:stack>
     </content>
 
     <implementation implements="nsITimerCallback">
       <constructor>
         <![CDATA[
           const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
           this.mTabMinWidth = Services.prefs.getIntPref("mail.tabs.tabMinWidth");
@@ -1923,16 +1842,17 @@
           this.mAutoHide = Services.prefs.getBoolPref("mail.tabs.autoHide");
 
           if (this.mAutoHide)
             this.mCollapseToolbar.collapsed = true;
 
           this.firstChild.minWidth = this.mTabMinWidth;
           this.firstChild.maxWidth = this.mTabMaxWidth;
           this._updateCloseButtons();
+          this._initializeArrowScrollbox();
 
           Services.prefs.addObserver("mail.tabs.", this._prefObserver);
 
           window.addEventListener("resize", this);
 
           // Listen to overflow/underflow events on the tabstrip,
           // we cannot put these as xbl handlers on the entire binding because
           // they would also get called for the all-tabs popup scrollbox.
@@ -1973,16 +1893,24 @@
       <field name="arrowScrollbox">
         document.getAnonymousElementByAttribute(this, "anonid", "arrowscrollbox");
       </field>
 
       <field name="arrowScrollboxClosebutton">
         document.getAnonymousElementByAttribute(this, "anonid", "tabstrip-closebutton");
       </field>
 
+      <field name="_scrollButtonDownBox">
+        document.getAnonymousElementByAttribute(this, "anonid", "down-box");
+      </field>
+
+      <field name="_scrollButtonDownBoxAnimate">
+        document.getAnonymousElementByAttribute(this, "anonid", "down-box-animate");
+      </field>
+
       <field name="mToolbar">
         document.getElementById(this.getAttribute("tabtoolbar"));
       </field>
 
       <field name="mCollapseToolbar">
         document.getElementById(this.getAttribute("collapsetoolbar"));
       </field>
 
@@ -2056,16 +1984,68 @@
             this.dispatchEvent(event);
           }
 
           return val;
         ]]>
         </setter>
       </property>
 
+      <method name="_initializeArrowScrollbox">
+        <body><![CDATA[
+          let arrowScrollbox = this.arrowScrollbox;
+          arrowScrollbox.addEventListener("underflow", event => {
+            // filter underflow events which were dispatched on nested scrollboxes
+            if (event.target != arrowScrollbox)
+              return;
+
+            // Ignore vertical events.
+            if (event.detail == 0) {
+              return;
+            }
+
+            arrowScrollbox.setAttribute("notoverflowing", "true");
+            let alltabsButton = document.getElementById("alltabs-button");
+            alltabsButton.setAttribute("hidden", "true");
+          }, true);
+
+          arrowScrollbox.addEventListener("overflow", event => {
+            // filter underflow events which were dispatched on nested scrollboxes
+            if (event.target != arrowScrollbox)
+              return;
+
+            // Ignore vertical events.
+            if (event.detail == 0) {
+              return;
+            }
+
+            arrowScrollbox.removeAttribute("notoverflowing");
+            let alltabsButton = document.getElementById("alltabs-button");
+            alltabsButton.removeAttribute("hidden");
+          });
+
+          arrowScrollbox.addEventListener("UpdatedScrollButtonsDisabledState", event => {
+            // filter underflow events which were dispatched on nested scrollboxes
+            if (event.target != arrowScrollbox)
+              return;
+
+            // fix for bug #352353
+            // unlike the scrollup button on the tab strip (which is a
+            // simple toolbarbutton) the scrolldown button is
+            // a more complicated stack of boxes and a toolbarbutton
+            // so that we can animate when a tab is opened offscreen.
+            // in order to style the box with the actual background image
+            // we need to manually set the disable state to match the
+            // disable state of the toolbarbutton.
+            arrowScrollbox._scrollButtonDownBox
+                .setAttribute("disabled", arrowScrollbox._scrollButtonDown.disabled);
+          });
+        ]]></body>
+      </method>
+
       <method name="_updateCloseButtons">
         <body><![CDATA[
           // modes for tabstrip
           // 0 - activetab  = close button on active tab only
           // 1 - alltabs    = close buttons on all tabs
           // 2 - noclose    = no close buttons at all
           // 3 - closeatend = close button at the end of the tabstrip
           switch (this.mCloseButtons) {
--- a/mail/themes/linux/mail/tabmail.css
+++ b/mail/themes/linux/mail/tabmail.css
@@ -65,34 +65,34 @@ tabpanels {
   margin-top: 1px;
 }
 
 /**
  * Tab Scrollbox Arrow Buttons
  */
 
 .tabmail-arrowscrollbox > .scrollbutton-up,
-.tabmail-arrowscrollbox > stack > .scrollbutton-down {
+.tabmail-arrowscrollbox > .scrollbutton-down {
   -moz-appearance: none;
   padding: 3px !important;
   border-style: none !important;
 }
 
 .tabmail-arrowscrollbox > .scrollbutton-up > .toolbarbutton-icon,
-.tabmail-arrowscrollbox > stack > .scrollbutton-down > .toolbarbutton-icon {
+.tabmail-arrowscrollbox > .scrollbutton-down > .toolbarbutton-icon {
   -moz-appearance: none;
 }
 
 .tabmail-arrowscrollbox > .scrollbutton-up:not([disabled]):hover,
-.tabmail-arrowscrollbox > stack > .scrollbutton-down:not([disabled]):hover {
+.tabmail-arrowscrollbox > .scrollbutton-down:not([disabled]):hover {
   background: var(--toolbarbutton-active-background);
 }
 
 .tabmail-arrowscrollbox > .scrollbutton-up[disabled],
-.tabmail-arrowscrollbox > stack > .scrollbutton-down[disabled] {
+.tabmail-arrowscrollbox > .scrollbutton-down[disabled] {
   --toolbarbutton-icon-fill-opacity: .4;
 }
 
 .tabs-alltabs-box-animate {
   background-color: Highlight;
   opacity: 0;
 }
 
--- a/mail/themes/osx/mail/tabmail.css
+++ b/mail/themes/osx/mail/tabmail.css
@@ -124,55 +124,61 @@ tabmail > tabbox > tabpanels {
   background-image: none !important;
 }
 
 /**
  * Tab Scrollbox Arrow Buttons
  */
 
 .tabmail-arrowscrollbox > .scrollbutton-up,
-.tabmail-arrowscrollbox > stack > .scrollbutton-down {
+.tabmail-arrowscrollbox > .scrollbutton-down {
   padding: 0 4px !important;
   margin: 0 0 1px !important;
 }
 
 .tabmail-arrowscrollbox >
   .scrollbutton-up:not([disabled="true"]):hover,
-.tabmail-arrowscrollbox > stack >
+.tabmail-arrowscrollbox >
   .scrollbutton-down:not([disabled="true"]):hover {
   background-image: linear-gradient(transparent, rgba(0,0,0,0.15));
 }
 
 .tabmail-arrowscrollbox >
   .scrollbutton-up:not([disabled="true"]):hover:active,
-.tabmail-arrowscrollbox > stack >
+.tabmail-arrowscrollbox >
   .scrollbutton-down:not([disabled="true"]):hover:active {
   background-image: linear-gradient(transparent, rgba(0,0,0,0.3));
 }
 
 #tabs-toolbar[brighttext] .tabmail-arrowscrollbox >
   .scrollbutton-up:not([disabled="true"]):hover,
-#tabs-toolbar[brighttext] .tabmail-arrowscrollbox > stack >
+#tabs-toolbar[brighttext] .tabmail-arrowscrollbox >
   .scrollbutton-down:not([disabled="true"]):hover {
   background-image: linear-gradient(rgba(255,255,255,0.25), rgba(255,255,255,0.25));
 }
 
 #tabs-toolbar[brighttext] .tabmail-arrowscrollbox >
   .scrollbutton-up:not([disabled="true"]):hover:active,
-#tabs-toolbar[brighttext] .tabmail-arrowscrollbox > stack >
+#tabs-toolbar[brighttext] .tabmail-arrowscrollbox >
   .scrollbutton-down:not([disabled="true"]):hover:active {
   background-image: linear-gradient(rgba(255,255,255,0.35), rgba(255,255,255,0.35));
 }
 
 .tabmail-arrowscrollbox > .scrollbutton-up[disabled="true"],
-.tabmail-arrowscrollbox > stack > .scrollbutton-down[disabled="true"] {
+.tabmail-arrowscrollbox > .scrollbutton-down[disabled="true"] {
   --toolbarbutton-icon-fill-opacity: .5;
   background-image: none;
 }
 
+/* Tab Overflow */
+.tabmail-arrowscrollbox > .arrowscrollbox-overflow-start-indicator:not([collapsed]),
+.tabmail-arrowscrollbox > .arrowscrollbox-overflow-end-indicator:not([collapsed]) {
+  margin-bottom: 0;
+}
+
 /**
  * All Tabs Buttons
  */
 
 .tabs-alltabs-box {
   margin: 0;
 }
 
--- a/mail/themes/shared/mail/tabmail.css
+++ b/mail/themes/shared/mail/tabmail.css
@@ -247,35 +247,36 @@
   display: -moz-box;
 }
 
 /**
  * Tab Scrollbox Arrow Buttons
  */
 
 .tabmail-arrowscrollbox > .scrollbutton-up,
-.tabmail-arrowscrollbox > stack > .scrollbutton-down {
+.tabmail-arrowscrollbox > .scrollbutton-down {
   color: inherit;
   list-style-image: url("chrome://messenger/skin/icons/arrow-left.svg") !important;
   -moz-context-properties: fill, fill-opacity;
   fill: var(--lwt-toolbarbutton-icon-fill, currentColor);
   fill-opacity: var(--toolbarbutton-icon-fill-opacity);
 }
 
 .tabmail-arrowscrollbox > .scrollbutton-up:-moz-locale-dir(rtl),
-.tabmail-arrowscrollbox > stack > .scrollbutton-down:-moz-locale-dir(ltr) {
+.tabmail-arrowscrollbox > .scrollbutton-down:-moz-locale-dir(ltr) {
   transform: scaleX(-1);
 }
 
 /* Tab Overflow */
 .tabmail-arrowscrollbox > .arrowscrollbox-overflow-start-indicator:not([collapsed]),
 .tabmail-arrowscrollbox > .arrowscrollbox-overflow-end-indicator:not([collapsed]) {
   width: 18px;
   background-image: url("chrome://messenger/skin/icons/overflow-indicator.png");
   background-size: 17px 100%;
+  background-repeat: no-repeat;
   border-left: 1px solid;
   border-image: linear-gradient(rgba(255,255,255,.2),
                                 rgba(255,255,255,.2) calc(100% - 1px),
                                 transparent calc(100% - 1px));
   border-image-slice: 1;
   margin-bottom: 1px;
   pointer-events: none;
   position: relative;
--- a/mail/themes/windows/mail/compacttheme.css
+++ b/mail/themes/windows/mail/compacttheme.css
@@ -149,17 +149,17 @@
     }
 
     #messengerWindow[tabsintitlebar] #mail-menubar > menu {
       color: inherit;
     }
 
     #tabs-toolbar .toolbarbutton-1,
     .tabmail-arrowscrollbox > .scrollbutton-up,
-    .tabmail-arrowscrollbox > stack > .scrollbutton-down {
+    .tabmail-arrowscrollbox > .scrollbutton-down {
       fill: CaptionText;
     }
   }
 }
 
 /* Restored windows get an artificial border on windows, because the lwtheme background
  * overlaps the regular window border. That isn't the case for us, so we avoid painting
  * over the native border with our custom borders: */
--- a/mail/themes/windows/mail/tabmail.css
+++ b/mail/themes/windows/mail/tabmail.css
@@ -58,41 +58,41 @@ tabpanels {
   outline: none !important;
 }
 
 /**
  * Tab Scrollbox Arrow Buttons
  */
 
 .tabmail-arrowscrollbox > .scrollbutton-up,
-.tabmail-arrowscrollbox > stack > .scrollbutton-down {
+.tabmail-arrowscrollbox > .scrollbutton-down {
   -moz-appearance: none;
   border-style: none !important;
   padding: 0 3px !important;
   margin: 0 !important;
   margin-inline-end: 1px !important;
 }
 
 .tabmail-arrowscrollbox > .scrollbutton-up[disabled],
-.tabmail-arrowscrollbox > stack > .scrollbutton-down[disabled] {
+.tabmail-arrowscrollbox > .scrollbutton-down[disabled] {
   --toolbarbutton-icon-fill-opacity: .4;
 }
 
 .tabmail-arrowscrollbox > .scrollbutton-up:-moz-locale-dir(rtl),
-.tabmail-arrowscrollbox > stack > .scrollbutton-down:-moz-locale-dir(ltr) {
+.tabmail-arrowscrollbox > .scrollbutton-down:-moz-locale-dir(ltr) {
   margin-inline-start: 1px !important;
   margin-inline-end: 0 !important;
 }
 
 /**
  * All Tabs Button
  */
 
 .tabmail-arrowscrollbox > .scrollbutton-up:not([disabled]):hover,
-.tabmail-arrowscrollbox > stack > .scrollbutton-down:not([disabled]):hover {
+.tabmail-arrowscrollbox > .scrollbutton-down:not([disabled]):hover {
   background: var(--toolbarbutton-active-background);
 }
 
 @media (-moz-windows-glass) {
   /* Set to full fill-opacity to improve visibility of toolbar buttons on aero glass. */
   :root[tabsintitlebar] #tabs-toolbar {
     --toolbarbutton-icon-fill-opacity: 1;
   }
@@ -105,31 +105,31 @@ tabpanels {
     border-color: transparent;
     margin-top: 0;
     margin-bottom: -1px;
   }
 
   #alltabs-button:not(:-moz-lwtheme):not([disabled]):hover,
   .tabmail-arrowscrollbox >
     .scrollbutton-up:not(:-moz-lwtheme):not([disabled]):hover,
-  .tabmail-arrowscrollbox > stack >
+  .tabmail-arrowscrollbox >
     .scrollbutton-down:not(:-moz-lwtheme):not([disabled]):hover {
     background-color: transparent;
     background-image: linear-gradient(rgba(255, 255, 255, 0),
                       rgba(255, 255, 255, .5)),
                       linear-gradient(transparent, rgba(0, 0, 0, .25) 30%),
                       linear-gradient(transparent, rgba(0, 0, 0, .25) 30%);
     background-position: 1px -1px, 0 -1px, 100% -1px;
     background-size: calc(100% - 2px) 100%, 1px 100%, 1px 100%;
     background-repeat: no-repeat;
   }
 
   #tabs-toolbar[brighttext] .tabmail-arrowscrollbox >
     .scrollbutton-up:not(:-moz-lwtheme):not([disabled]):hover,
-  #tabs-toolbar[brighttext] .tabmail-arrowscrollbox > stack >
+  #tabs-toolbar[brighttext] .tabmail-arrowscrollbox >
     .scrollbutton-down:not(:-moz-lwtheme):not([disabled]):hover {
     background-image: linear-gradient(rgba(255, 255, 255, 0),
                       rgba(255, 255, 255, .5)),
                       linear-gradient(transparent, rgba(255, 255, 355, .25) 30%),
                       linear-gradient(transparent, rgba(255, 255, 255, .25) 30%);
   }
 }