Bug 580257 - _getScrollableElements needs to exclude non-scrollable elements. r=enn
authorDão Gottwald <dao@mozilla.com>
Fri, 23 Jul 2010 00:31:58 +0200
changeset 48122 06a37463c15e07e10e9bfa758a52a218acaed9c6
parent 48121 54c9709c9ee9169aa665ed5d9ada52b95107f1c8
child 48123 cf5f013caa80a71e927c418538fabc1f8fdd63c6
push id14581
push userdgottwald@mozilla.com
push dateFri, 23 Jul 2010 07:29:15 +0000
treeherdermozilla-central@06a37463c15e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersenn
bugs580257
milestone2.0b3pre
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 580257 - _getScrollableElements needs to exclude non-scrollable elements. r=enn
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
@@ -2308,17 +2308,18 @@
   </binding>
 
   <binding id="tabbrowser-arrowscrollbox" extends="chrome://global/content/bindings/scrollbox.xml#arrowscrollbox-clicktoscroll">
     <implementation>
       <!-- Override scrollbox.xml method, since our scrollbox's children are
            inherited from the binding parent -->
       <method name="_getScrollableElements">
         <body><![CDATA[
-          return document.getBindingParent(this).childNodes;
+          return Array.filter(document.getBindingParent(this).childNodes,
+                              this._canScrollToElement, this);
         ]]></body>
       </method>
       <method name="_canScrollToElement">
         <parameter name="tab"/>
         <body>
           return !tab.pinned;
         </body>
       </method>
--- a/browser/base/content/test/browser_overflowScroll.js
+++ b/browser/base/content/test/browser_overflowScroll.js
@@ -1,80 +1,82 @@
-var tabContainer = gBrowser.tabContainer;
-var tabstrip = tabContainer.mTabstrip;
+var tabstrip = gBrowser.tabContainer.mTabstrip;
 var scrollbox = tabstrip._scrollbox;
 var originalSmoothScroll = tabstrip.smoothScroll;
+var tabs = gBrowser.tabs;
 
 function rect(ele)           ele.getBoundingClientRect();
 function width(ele)          rect(ele).width;
 function left(ele)           rect(ele).left;
 function right(ele)          rect(ele).right;
 function isLeft(ele, msg)    is(left(ele), left(scrollbox), msg);
 function isRight(ele, msg)   is(right(ele), right(scrollbox), msg);
 function elementFromPoint(x) tabstrip._elementFromPoint(x);
 function nextLeftElement()   elementFromPoint(left(scrollbox) - 1);
 function nextRightElement()  elementFromPoint(right(scrollbox) + 1);
+function firstScrollable()   tabs[gBrowser._numPinnedTabs];
 
 function test() {
   waitForExplicitFinish();
 
   // If the previous (or more) test finished with cleaning up the tabs,
   // there may be some pending animations. That can cause a failure of
   // this tests, so, we should test this in another stack.
   setTimeout(doTest, 0);
 }
 
 function doTest() {
   tabstrip.smoothScroll = false;
 
   var tabMinWidth = parseInt(getComputedStyle(gBrowser.selectedTab, null).minWidth);
   var tabCountForOverflow = Math.ceil(width(tabstrip) / tabMinWidth * 3);
-  while (tabContainer.childNodes.length < tabCountForOverflow)
+  while (tabs.length < tabCountForOverflow)
     gBrowser.addTab("about:blank", {skipAnimation: true});
+  gBrowser.pinTab(tabs[0]);
 
   tabstrip.addEventListener("overflow", runOverflowTests, false);
 }
 
 function runOverflowTests(aEvent) {
   if (aEvent.detail != 1)
     return;
 
   tabstrip.removeEventListener("overflow", runOverflowTests, false);
 
   var upButton = tabstrip._scrollButtonUp;
   var downButton = tabstrip._scrollButtonDown;
   var element;
 
-  gBrowser.selectedTab = tabContainer.firstChild;
-  isLeft(tabContainer.firstChild, "Selecting the first tab scrolls it into view");
+  gBrowser.selectedTab = firstScrollable();
+  isLeft(firstScrollable(), "Selecting the first tab scrolls it into view");
 
   element = nextRightElement();
   EventUtils.synthesizeMouse(downButton, 1, 1, {});
   isRight(element, "Scrolled one tab to the right with a single click");
 
-  gBrowser.selectedTab = tabContainer.lastChild;
-  isRight(tabContainer.lastChild, "Selecting the last tab scrolls it into view");
+  gBrowser.selectedTab = tabs[tabs.length - 1];
+  isRight(gBrowser.selectedTab, "Selecting the last tab scrolls it into view");
 
   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(tabContainer.firstChild, "Scrolled to the start with a triple click");
+  isLeft(firstScrollable(), "Scrolled to the start with a triple click");
 
   for (var i = 2; i; i--)
     EventUtils.synthesizeMouseScroll(scrollbox, 1, 1, {axis: "horizontal", delta: -1});
-  isLeft(tabContainer.firstChild, "Remained at the start with the mouse wheel");
+  isLeft(firstScrollable(), "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 (tabContainer.childNodes.length > 1)
-    gBrowser.removeTab(tabContainer.lastChild);
+  while (tabs.length > 1)
+    gBrowser.removeTab(tabs[0]);
 
   tabstrip.smoothScroll = originalSmoothScroll;
   finish();
 }
--- a/toolkit/content/widgets/scrollbox.xml
+++ b/toolkit/content/widgets/scrollbox.xml
@@ -311,33 +311,32 @@
             return;
 
           this.ensureElementIsVisible(targetElement, aSmoothScroll);
         ]]></body>
       </method>
 
       <method name="_getScrollableElements">
         <body><![CDATA[
-          return this.hasChildNodes() ?
-                   this.childNodes : document.getBindingParent(this).childNodes;
+          var nodes = this.hasChildNodes() ?
+                        this.childNodes : document.getBindingParent(this).childNodes;
+          return Array.filter(nodes, this._canScrollToElement, this);
         ]]></body>
       </method>
 
       <method name="_elementFromPoint">
         <parameter name="aX"/>
         <parameter name="aPhysicalScrollDir"/>
         <body><![CDATA[
           var elements = this._getScrollableElements();
           if (!elements.length)
             return null;
 
-          if (this._isRTLScrollbox) {
-            elements = Array.slice(elements);
+          if (this._isRTLScrollbox)
             elements.reverse();
-          }
 
           var [start, end] = this._startEndProps;
           var low = 0;
           var high = elements.length - 1;
 
           if (aX < elements[low].getBoundingClientRect()[start] ||
               aX > elements[high].getBoundingClientRect()[end])
             return null;