Bug 1521309 - Refresh richlistbox.xml from last pre-CE version of 2019-01-04. r=Paenglab
authorJorg K <jorgk@jorgk.com>
Sat, 19 Jan 2019 20:50:41 +0100
changeset 34247 27bc126331220a417122393e59e9515709f379ec
parent 34246 1948a0ff606a6fce643afb53e90e08a8c0cdf8b8
child 34248 c1a9b8792ed93807415d2013ad62a8f735de9c88
push id389
push userclokep@gmail.com
push dateMon, 18 Mar 2019 19:01:53 +0000
reviewersPaenglab
bugs1521309
Bug 1521309 - Refresh richlistbox.xml from last pre-CE version of 2019-01-04. r=Paenglab
common/bindings/richlistbox.xml
--- a/common/bindings/richlistbox.xml
+++ b/common/bindings/richlistbox.xml
@@ -9,28 +9,19 @@
 
 <bindings id="richlistboxBindings"
           xmlns="http://www.mozilla.org/xbl"
           xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
           xmlns:xbl="http://www.mozilla.org/xbl">
 
   <binding id="xbl-richlistbox"
            extends="chrome://global/content/bindings/general.xml#basecontrol">
-    <content>
-      <children includes="listheader"/>
-      <xul:scrollbox allowevents="true" orient="vertical" anonid="main-box"
-                     flex="1" style="overflow: auto;" xbl:inherits="dir,pack">
-        <children/>
-      </xul:scrollbox>
-    </content>
+    <content allowevents="true" orient="vertical"/>
 
     <implementation implements="nsIDOMXULMultiSelectControlElement">
-      <field name="_scrollbox">
-        document.getAnonymousElementByAttribute(this, "anonid", "main-box");
-      </field>
       <constructor>
         <![CDATA[
           this._refreshSelection();
         ]]>
       </constructor>
 
       <method name="_fireOnSelect">
         <body>
@@ -60,28 +51,23 @@
             this.dispatchEvent(event);
 
             // always call this (allows a commandupdater without controller)
             document.commandDispatcher.updateCommands("richlistbox-select");
           ]]>
         </body>
       </method>
 
-      <!-- We override base-listbox here because those methods don't take dir
-           into account on listbox (which doesn't support dir yet) -->
       <method name="getNextItem">
         <parameter name="aStartItem"/>
         <parameter name="aDelta"/>
         <body>
         <![CDATA[
-          var prop = this.dir == "reverse" && this._mayReverse ?
-                                                "previousSibling" :
-                                                "nextSibling";
           while (aStartItem) {
-            aStartItem = aStartItem[prop];
+            aStartItem = aStartItem.nextSibling;
             if (aStartItem && aStartItem.localName == "richlistitem" &&
                 (!this._userSelecting || this._canUserSelect(aStartItem))) {
               --aDelta;
               if (aDelta == 0)
                 return aStartItem;
             }
           }
           return null;
@@ -89,21 +75,18 @@
         </body>
       </method>
 
       <method name="getPreviousItem">
         <parameter name="aStartItem"/>
         <parameter name="aDelta"/>
         <body>
         <![CDATA[
-          var prop = this.dir == "reverse" && this._mayReverse ?
-                                                "nextSibling" :
-                                                "previousSibling";
           while (aStartItem) {
-            aStartItem = aStartItem[prop];
+            aStartItem = aStartItem.previousSibling;
             if (aStartItem && aStartItem.localName == "richlistitem" &&
                 (!this._userSelecting || this._canUserSelect(aStartItem))) {
               --aDelta;
               if (aDelta == 0)
                 return aStartItem;
             }
           }
           return null;
@@ -475,42 +458,48 @@
           <![CDATA[
             return this.ensureElementIsVisible(this.getItemAtIndex(aIndex));
           ]]>
         </body>
       </method>
 
       <method name="ensureElementIsVisible">
         <parameter name="aElement"/>
+        <parameter name="aAlignToTop"/>
         <body>
           <![CDATA[
-            if (!aElement)
+            if (!aElement) {
               return;
+            }
+
+            // These calculations assume that there is no padding on the
+            // "richlistbox" element, although there might be a margin.
             var targetRect = aElement.getBoundingClientRect();
-            var scrollRect = this._scrollbox.getBoundingClientRect();
+            var scrollRect = this.getBoundingClientRect();
             var offset = targetRect.top - scrollRect.top;
-            if (offset >= 0) {
+            if (!aAlignToTop && offset >= 0) {
               // scrollRect.bottom wouldn't take a horizontal scroll bar into account
-              let scrollRectBottom = scrollRect.top + this._scrollbox.clientHeight;
+              let scrollRectBottom = scrollRect.top + this.clientHeight;
               offset = targetRect.bottom - scrollRectBottom;
               if (offset <= 0)
                 return;
             }
-            this._scrollbox.scrollTop += offset;
+            this.scrollTop += offset;
           ]]>
         </body>
       </method>
 
       <method name="scrollToIndex">
         <parameter name="aIndex"/>
         <body>
           <![CDATA[
             var item = this.getItemAtIndex(aIndex);
-            if (item)
-              this._scrollbox.scrollToElement(item);
+            if (item) {
+              this.ensureElementIsVisible(item, true);
+            }
           ]]>
         </body>
       </method>
 
       <method name="getIndexOfFirstVisibleRow">
         <body>
           <![CDATA[
             var children = this.itemChildren;
@@ -545,25 +534,25 @@
             // at the extreme we're moving away from
             if (!this.currentItem)
               return aDirection == -1 ? children.length : 0;
 
             // If the current item is visible, scroll by one page so that
             // the new current item is at approximately the same position as
             // the existing current item.
             if (this._isItemVisible(this.currentItem))
-              this._scrollbox.scrollBy(0, this._scrollbox.boxObject.height * aDirection);
+              this.scrollBy(0, this.clientHeight * aDirection);
 
             // Figure out, how many items fully fit into the view port
             // (including the currently selected one), and determine
             // the index of the first one lying (partially) outside
-            var height = this._scrollbox.boxObject.height;
+            var height = this.clientHeight;
             var startBorder = this.currentItem.boxObject.y;
             if (aDirection == -1)
-              startBorder += this.currentItem.boxObject.height;
+              startBorder += this.currentItem.clientHeight;
 
             var index = this.currentIndex;
             for (var ix = index; 0 <= ix && ix < children.length; ix += aDirection) {
               var boxObject = children[ix].boxObject;
               if (boxObject.height == 0)
                 continue; // hidden children have a y of 0
               var endBorder = boxObject.y + (aDirection == -1 ? boxObject.height : 0);
               if ((endBorder - startBorder) * aDirection > height)
@@ -576,19 +565,16 @@
         </body>
       </method>
 
       <property name="itemChildren" readonly="true">
         <getter>
           <![CDATA[
             let children = Array.from(this.children)
                                 .filter(node => node.localName == "richlistitem");
-            if (this.dir == "reverse" && this._mayReverse) {
-              children.reverse();
-            }
             return children;
           ]]>
         </getter>
       </property>
 
       <method name="_refreshSelection">
         <body>
           <![CDATA[
@@ -614,24 +600,22 @@
               if (!currentItem && this._currentIndex)
                 currentItem = this.getItemAtIndex(Math.min(
                   this._currentIndex - 1, this.getRowCount()));
               if (currentItem) {
                 this.currentItem = currentItem;
                 if (this.selType != "multiple" && this.selectedCount == 0)
                   this.selectedItem = currentItem;
 
-                if (this._scrollbox.boxObject.height) {
+                if (this.clientHeight) {
                   this.ensureElementIsVisible(currentItem);
                 } else {
                   // XXX hack around a bug in ensureElementIsVisible as it will
                   // scroll beyond the last element, bug 493645.
-                  var previousElement = this.dir == "reverse" ? currentItem.nextElementSibling :
-                                                                currentItem.previousElementSibling;
-                  this.ensureElementIsVisible(previousElement);
+                  this.ensureElementIsVisible(currentItem.previousElementSibling);
                 }
               }
               this._suppressOnSelect = suppressSelect;
               // XXX actually it's just a refresh, but at least
               // the Extensions manager expects this:
               this._fireOnSelect();
               return;
             }
@@ -679,21 +663,21 @@
 
       <method name="_isItemVisible">
         <parameter name="aItem"/>
         <body>
           <![CDATA[
             if (!aItem)
               return false;
 
-            var y = this._scrollbox.scrollTop + this._scrollbox.boxObject.y;
+            var y = this.scrollTop + this.boxObject.y;
 
             // Partially visible items are also considered visible
-            return (aItem.boxObject.y + aItem.boxObject.height > y) &&
-                   (aItem.boxObject.y < y + this._scrollbox.boxObject.height);
+            return (aItem.boxObject.y + aItem.clientHeight > y) &&
+                   (aItem.boxObject.y < y + this.clientHeight);
           ]]>
         </body>
       </method>
 
       <property name="suppressOnSelect"
                 onget="return this.getAttribute('suppressonselect') == 'true';"
                 onset="this.setAttribute('suppressonselect', val);"/>
 
@@ -740,32 +724,31 @@
 
       <method name="_moveByOffsetFromUserEvent">
         <parameter name="aOffset"/>
         <parameter name="aEvent"/>
         <body>
         <![CDATA[
           if (!aEvent.defaultPrevented) {
             this._userSelecting = true;
-            this._mayReverse = true;
             this.moveByOffset(aOffset, !aEvent.ctrlKey, aEvent.shiftKey);
             this._userSelecting = false;
-            this._mayReverse = false;
             aEvent.preventDefault();
           }
         ]]>
         </body>
       </method>
 
       <method name="_canUserSelect">
         <parameter name="aItem"/>
         <body>
         <![CDATA[
           var style = document.defaultView.getComputedStyle(aItem);
-          return style.display != "none" && style.visibility == "visible";
+          return style.display != "none" && style.visibility == "visible" &&
+                 style.MozUserInput != "none";
         ]]>
         </body>
       </method>
 
       <method name="_selectTimeoutHandler">
         <parameter name="aMe"/>
         <body>
           aMe._fireOnSelect();
@@ -796,17 +779,16 @@
         </body>
       </method>
 
       <field name="_currentIndex">null</field>
       <field name="_lastKeyTime">0</field>
       <field name="_incrementalString">""</field>
       <field name="_suppressOnSelect">false</field>
       <field name="_userSelecting">false</field>
-      <field name="_mayReverse">false</field>
       <field name="_selectTimeout">null</field>
       <field name="_currentItem">null</field>
       <field name="_selectionStart">null</field>
 
       <!-- For backwards-compatibility and for convenience.
         Use ensureElementIsVisible instead -->
       <method name="ensureSelectedElementIsVisible">
         <body>
@@ -824,46 +806,38 @@
 
       <handler event="keypress" keycode="VK_DOWN" modifiers="control shift any"
                action="this._moveByOffsetFromUserEvent(1, event);"
                group="system"/>
 
       <handler event="keypress" keycode="VK_HOME" modifiers="control shift any"
                group="system">
         <![CDATA[
-          this._mayReverse = true;
           this._moveByOffsetFromUserEvent(-this.currentIndex, event);
-          this._mayReverse = false;
         ]]>
       </handler>
 
       <handler event="keypress" keycode="VK_END" modifiers="control shift any"
                group="system">
         <![CDATA[
-          this._mayReverse = true;
           this._moveByOffsetFromUserEvent(this.getRowCount() - this.currentIndex - 1, event);
-          this._mayReverse = false;
         ]]>
       </handler>
 
       <handler event="keypress" keycode="VK_PAGE_UP" modifiers="control shift any"
                group="system">
         <![CDATA[
-          this._mayReverse = true;
           this._moveByOffsetFromUserEvent(this.scrollOnePage(-1), event);
-          this._mayReverse = false;
         ]]>
       </handler>
 
       <handler event="keypress" keycode="VK_PAGE_DOWN" modifiers="control shift any"
                group="system">
         <![CDATA[
-          this._mayReverse = true;
           this._moveByOffsetFromUserEvent(this.scrollOnePage(1), event);
-          this._mayReverse = false;
         ]]>
       </handler>
 
       <handler event="keypress" key=" " modifiers="control" phase="target">
         <![CDATA[
           if (this.currentItem && this.selType == "multiple")
             this.toggleItemSelection(this.currentItem);
         ]]>
@@ -928,31 +902,31 @@
             }
           }
         ]]>
       </handler>
 
       <handler event="click">
         <![CDATA[
           // clicking into nothing should unselect
-          if (event.originalTarget == this._scrollbox) {
+          if (event.originalTarget == this) {
             this.clearSelection();
             this.currentItem = null;
           }
         ]]>
       </handler>
 
       <handler event="MozSwipeGesture">
         <![CDATA[
           // Only handle swipe gestures up and down
           switch (event.direction) {
             case event.DIRECTION_DOWN:
-              this._scrollbox.scrollTop = this._scrollbox.scrollHeight;
+              this.scrollTop = this.scrollHeight;
               break;
             case event.DIRECTION_UP:
-              this._scrollbox.scrollTop = 0;
+              this.scrollTop = 0;
               break;
           }
         ]]>
       </handler>
     </handlers>
   </binding>
 </bindings>