Bug 594002 - Make the tab bar scrollbox deal with tab scrolling properly when it has padding set on it. r=Enn, a=betaN
authorMarkus Stange <mstange@themasta.com>
Wed, 24 Nov 2010 10:50:20 +0100
changeset 58136 a6b991eee6835067f20e7828f7c75793f808e3f6
parent 58135 4fb1f137b0f6640141ea5cdb7ca3ce07f5fce091
child 58137 c32ed22725099c6b24835780164a4afb73f8f522
push id17174
push usermstange@themasta.com
push dateWed, 24 Nov 2010 09:57:48 +0000
treeherdermozilla-central@fad69d390b23 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersEnn, betaN
bugs594002
milestone2.0b8pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 594002 - Make the tab bar scrollbox deal with tab scrolling properly when it has padding set on it. r=Enn, a=betaN
browser/base/content/tabbrowser.xml
browser/base/content/test/browser_overflowScroll.js
toolkit/content/widgets/scrollbox.xml
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -2777,22 +2777,30 @@
 
           if (pinnedOnly)
             this.tabbrowser.tabContainer.setAttribute("pinnedonly", "true");
           else
             this.tabbrowser.tabContainer.removeAttribute("pinnedonly");
 
           var scrollButtonWidth = (this.getAttribute("overflow") != "true" || pinnedOnly) ? 0 :
                                   this.mTabstrip._scrollButtonDown.scrollWidth;
+          var paddingStart = this.mTabstrip.scrollboxPaddingStart;
+
           for (var i = this.tabbrowser._numPinnedTabs - 1; i >= 0; i--) {
             let tab = this.childNodes[i];
             width += pinnedOnly ? 0 : tab.scrollWidth;
-            tab.style.MozMarginStart = - (width + scrollButtonWidth) + "px";
+            if (this.getAttribute("overflow") != "true")
+              tab.style.MozMarginStart = - (width + scrollButtonWidth) + "px";
+            else
+              tab.style.MozMarginStart = - (width + scrollButtonWidth + paddingStart) + "px";
           }
-          this.style.MozMarginStart = width + "px";
+          if (width == 0 || this.getAttribute("overflow") != "true")
+            this.style.MozMarginStart = width + "px";
+          else
+            this.style.MozMarginStart = width + paddingStart + "px";
           this.mTabstrip.ensureElementIsVisible(this.selectedItem, false);
         ]]></body>
       </method>
 
       <method name="handleEvent">
         <parameter name="aEvent"/>
         <body><![CDATA[
           switch (aEvent.type) {
--- a/browser/base/content/test/browser_overflowScroll.js
+++ b/browser/base/content/test/browser_overflowScroll.js
@@ -41,39 +41,43 @@ function runOverflowTests(aEvent) {
 
   tabstrip.removeEventListener("overflow", runOverflowTests, false);
 
   var upButton = tabstrip._scrollButtonUp;
   var downButton = tabstrip._scrollButtonDown;
   var element;
 
   gBrowser.selectedTab = firstScrollable();
-  isLeft(firstScrollable(), "Selecting the first tab scrolls it into view");
+  ok(left(scrollbox) <= left(firstScrollable()), "Selecting the first tab scrolls it into view " +
+     "(" + left(scrollbox) + " <= " + left(firstScrollable()) + ")");
 
   element = nextRightElement();
   EventUtils.synthesizeMouse(downButton, 1, 1, {});
   isRight(element, "Scrolled one tab to the right with a single click");
 
   gBrowser.selectedTab = tabs[tabs.length - 1];
-  isRight(gBrowser.selectedTab, "Selecting the last tab scrolls it into view");
+  ok(right(gBrowser.selectedTab) <= right(scrollbox), "Selecting the last tab scrolls it into view " +
+     "(" + right(gBrowser.selectedTab) + " <= " + right(scrollbox) + ")");
 
   element = nextLeftElement();
   EventUtils.synthesizeMouse(upButton, 1, 1, {});
   isLeft(element, "Scrolled one tab to the left with a single click");
 
   element = elementFromPoint(left(scrollbox) - width(scrollbox));
   EventUtils.synthesizeMouse(upButton, 1, 1, {clickCount: 2});
   isLeft(element, "Scrolled one page of tabs with a double click");
 
   EventUtils.synthesizeMouse(upButton, 1, 1, {clickCount: 3});
-  isLeft(firstScrollable(), "Scrolled to the start with a triple click");
+  var firstScrollableLeft = left(firstScrollable());
+  ok(left(scrollbox) <= firstScrollableLeft, "Scrolled to the start with a triple click " +
+     "(" + left(scrollbox) + " <= " + firstScrollableLeft + ")");
 
   for (var i = 2; i; i--)
     EventUtils.synthesizeMouseScroll(scrollbox, 1, 1, {axis: "horizontal", delta: -1});
-  isLeft(firstScrollable(), "Remained at the start with the mouse wheel");
+  is(left(firstScrollable()), firstScrollableLeft, "Remained at the start with the mouse wheel");
 
   element = nextRightElement();
   EventUtils.synthesizeMouseScroll(scrollbox, 1, 1, {axis: "horizontal", delta: 1});
   isRight(element, "Scrolled one tab to the right with the mouse wheel");
 
   while (tabs.length > 1)
     gBrowser.removeTab(tabs[0]);
 
--- a/toolkit/content/widgets/scrollbox.xml
+++ b/toolkit/content/widgets/scrollbox.xml
@@ -21,17 +21,20 @@
 
   <binding id="arrowscrollbox" extends="chrome://global/content/bindings/scrollbox.xml#scrollbox-base">
     <content>
       <xul:autorepeatbutton class="autorepeatbutton-up"
                             anonid="scrollbutton-up"
                             collapsed="true"
                             xbl:inherits="orient"
                             oncommand="_autorepeatbuttonScroll(event);"/>
-      <xul:scrollbox xbl:inherits="orient,align,pack,dir" flex="1" anonid="scrollbox">
+      <xul:scrollbox class="arrowscrollbox-scrollbox"
+                     anonid="scrollbox"
+                     flex="1"
+                     xbl:inherits="orient,align,pack,dir">
         <children/>
       </xul:scrollbox>
       <xul:autorepeatbutton class="autorepeatbutton-down"
                             anonid="scrollbutton-down"
                             collapsed="true"
                             xbl:inherits="orient"
                             oncommand="_autorepeatbuttonScroll(event);"/>
     </content>
@@ -130,17 +133,36 @@
 
       <property name="scrollSize" readonly="true">
         <getter><![CDATA[
           return this.orient == "vertical" ?
                  this._scrollbox.scrollHeight :
                  this._scrollbox.scrollWidth;
         ]]></getter>
       </property>
-
+      <property name="scrollPaddingRect" readonly="true">
+        <getter><![CDATA[
+          // This assumes that this._scrollbox doesn't have any border.
+          var outerRect = this.scrollClientRect;
+          var innerRect = {};
+          innerRect.left = outerRect.left - this._scrollbox.scrollLeft;
+          innerRect.top = outerRect.top - this._scrollbox.scrollTop;
+          innerRect.right = innerRect.left + this._scrollbox.scrollWidth;
+          innerRect.bottom = innerRect.top + this._scrollbox.scrollHeight;
+          return innerRect;
+        ]]></getter>
+      </property>
+      <property name="scrollboxPaddingStart" readonly="true">
+        <getter><![CDATA[
+          var ltr = (window.getComputedStyle(this, null).direction == "ltr");
+          var paddingStartName = ltr ? "padding-left" : "padding-right";
+          var scrollboxStyle = window.getComputedStyle(this._scrollbox, null);
+          return parseFloat(scrollboxStyle.getPropertyValue(paddingStartName));
+        ]]></getter>
+      </property>
       <property name="scrollPosition">
         <getter><![CDATA[
           return this.orient == "vertical" ?
                  this._scrollbox.scrollTop :
                  this._scrollbox.scrollLeft;
         ]]></getter>
         <setter><![CDATA[
           if (this.orient == "vertical")
@@ -181,16 +203,33 @@
 
           var vertical = this.orient == "vertical";
           var rect = this.scrollClientRect;
           var containerStart = vertical ? rect.top : rect.left;
           var containerEnd = vertical ? rect.bottom : rect.right;
           rect = element.getBoundingClientRect();
           var elementStart = vertical ? rect.top : rect.left;
           var elementEnd = vertical ? rect.bottom : rect.right;
+
+          var scrollPaddingRect = this.scrollPaddingRect;
+          let style = window.getComputedStyle(this._scrollbox, null);
+          var scrollContentRect = {
+            left: scrollPaddingRect.left + parseFloat(style.paddingLeft),
+            top: scrollPaddingRect.top + parseFloat(style.paddingTop),
+            right: scrollPaddingRect.right - parseFloat(style.paddingRight),
+            bottom: scrollPaddingRect.bottom - parseFloat(style.paddingBottom)
+          };
+
+          if (elementStart <= (vertical ? scrollContentRect.top : scrollContentRect.left)) {
+            elementStart = vertical ? scrollPaddingRect.top : scrollPaddingRect.left;
+          }
+          if (elementEnd >= (vertical ? scrollContentRect.bottom : scrollContentRect.right)) {
+            elementEnd = vertical ? scrollPaddingRect.bottom : scrollPaddingRect.right;
+          }
+
           var amountToScroll;
 
           if (elementStart < containerStart) {
             amountToScroll = elementStart - containerStart;
           } else if (containerEnd < elementEnd) {
             amountToScroll = elementEnd - containerEnd;
           } else if (this._isScrolling) {
             // decelerate if a currently-visible element is selected during the scroll
@@ -538,17 +577,20 @@
       <xul:toolbarbutton class="scrollbutton-up" collapsed="true"
                          xbl:inherits="orient"
                          anonid="scrollbutton-up"
                          onclick="_distanceScroll(event);"
                          onmousedown="if (event.button == 0) _startScroll(-1);"
                          onmouseup="if (event.button == 0) _stopScroll();"
                          onmouseover="_continueScroll(-1);"
                          onmouseout="_pauseScroll();"/>
-      <xul:scrollbox xbl:inherits="orient,align,pack,dir" flex="1" anonid="scrollbox">
+      <xul:scrollbox class="arrowscrollbox-scrollbox"
+                     anonid="scrollbox"
+                     flex="1"
+                     xbl:inherits="orient,align,pack,dir">
         <children/>
       </xul:scrollbox>
       <xul:toolbarbutton class="scrollbutton-down" collapsed="true"
                          xbl:inherits="orient"
                          anonid="scrollbutton-down"
                          onclick="_distanceScroll(event);"
                          onmousedown="if (event.button == 0) _startScroll(1);"
                          onmouseup="if (event.button == 0) _stopScroll();"