Bug 1516876 - Remove the "autocomplete-richlistbox" binding. r=bgrins
authorPaolo Amadini <paolo.mozmail@amadzone.org>
Sun, 30 Dec 2018 15:59:57 +0000
changeset 509344 3ab044c93118276fac2854d0a6c8762b32b36bd2
parent 509343 9781b1970089c2186ab5b3ffa79532f2e0bc0a0f
child 509345 59468cc2550d9441832a6d6954dd46cccc089435
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbgrins
bugs1516876
milestone66.0a1
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 1516876 - Remove the "autocomplete-richlistbox" binding. r=bgrins Differential Revision: https://phabricator.services.mozilla.com/D15501
toolkit/components/satchel/test/browser/browser_popup_mouseover.js
toolkit/content/widgets/autocomplete.xml
toolkit/content/xul.css
--- a/toolkit/components/satchel/test/browser/browser_popup_mouseover.js
+++ b/toolkit/components/satchel/test/browser/browser_popup_mouseover.js
@@ -28,26 +28,26 @@ add_task(async function test() {
 
     // show popup
     await BrowserTestUtils.synthesizeKey("VK_DOWN", {}, browser);
     await BrowserTestUtils.waitForCondition(() => {
       return autoCompletePopup.popupOpen;
     });
     const listItemElems = itemsBox.querySelectorAll(".autocomplete-richlistitem");
     is(listItemElems.length, mockHistory.length, "ensure result length");
-    is(itemsBox.mousedOverIndex, -1, "mousedOverIndex should be -1");
+    is(autoCompletePopup.mousedOverIndex, -1, "mousedOverIndex should be -1");
 
     // navigate to the first item
     await BrowserTestUtils.synthesizeKey("VK_DOWN", {}, browser);
     is(autoCompletePopup.selectedIndex, 0, "selectedIndex should be 0");
 
     // mouseover the second item
     EventUtils.synthesizeMouseAtCenter(listItemElems[1], {type: "mouseover"});
     await BrowserTestUtils.waitForCondition(() => {
-      return itemsBox.mousedOverIndex = 1;
+      return autoCompletePopup.mousedOverIndex = 1;
     });
     ok(true, "mousedOverIndex changed");
     is(autoCompletePopup.selectedIndex, 0, "selectedIndex should not be changed by mouseover");
 
     // close popup
     await ContentTask.spawn(browser, {}, async function() {
       const input = content.document.querySelector("input");
 
--- a/toolkit/content/widgets/autocomplete.xml
+++ b/toolkit/content/widgets/autocomplete.xml
@@ -659,16 +659,73 @@
       </xul:hbox>
     </content>
 
     <implementation implements="nsIAutoCompletePopup">
       <field name="mInput">null</field>
       <field name="mPopupOpen">false</field>
       <field name="_currentIndex">0</field>
 
+      <constructor><![CDATA[
+        if (!this.listEvents) {
+          this.listEvents = {
+            handleEvent: event => {
+              if (!this.parentNode) {
+                return;
+              }
+
+              switch (event.type) {
+                case "mouseup":
+                  // Don't call onPopupClick for the scrollbar buttons, thumb,
+                  // slider, etc. If we hit the richlistbox and not a
+                  // richlistitem, we ignore the event.
+                  if (event.target.closest("richlistbox,richlistitem")
+                                  .localName == "richlistitem") {
+                    this.onPopupClick(event);
+                  }
+                  break;
+                case "mousemove":
+                  if (Date.now() - this.mLastMoveTime <= 30) {
+                    return;
+                  }
+
+                  let item = event.target.closest("richlistbox,richlistitem");
+
+                  // If we hit the richlistbox and not a richlistitem, we ignore
+                  // the event.
+                  if (item.localName == "richlistbox") {
+                    return;
+                  }
+
+                  let index = this.richlistbox.getIndexOfItem(item);
+
+                  this.mousedOverIndex = index;
+
+                  if (item.selectedByMouseOver) {
+                    this.richlistbox.selectedIndex = index;
+                  }
+
+                  this.mLastMoveTime = Date.now();
+                  break;
+              }
+            },
+          };
+          this.richlistbox.addEventListener("mouseup", this.listEvents);
+          this.richlistbox.addEventListener("mousemove", this.listEvents);
+        }
+      ]]></constructor>
+
+      <destructor><![CDATA[
+        if (this.listEvents) {
+          this.richlistbox.removeEventListener("mouseup", this.listEvents);
+          this.richlistbox.removeEventListener("mousemove", this.listEvents);
+          delete this.listEvents;
+        }
+      ]]></destructor>
+
       <!-- =================== nsIAutoCompletePopup =================== -->
 
       <property name="input" readonly="true"
                 onget="return this.mInput"/>
 
       <property name="overrideValue" readonly="true"
                 onget="return null;"/>
 
@@ -761,20 +818,22 @@
               this.richlistbox.selectedItem || this.richlistbox.firstElementChild);
           }
           return val;
         ]]>
         </setter>
       </property>
 
       <field name="_previousSelectedIndex">-1</field>
+      <field name="mLastMoveTime">Date.now()</field>
+      <field name="mousedOverIndex">-1</field>
 
       <method name="onSearchBegin">
         <body><![CDATA[
-          this.richlistbox.mousedOverIndex = -1;
+          this.mousedOverIndex = -1;
 
           if (typeof this._onSearchBegin == "function") {
             this._onSearchBegin();
           }
         ]]></body>
       </method>
 
       <method name="openAutocompletePopup">
@@ -1006,17 +1065,17 @@
             // due to new results, but only when: the item is the same, *OR*
             // we are about to replace the currently moused-over item, to
             // avoid surprising the user.
             let iface = Ci.nsIAutoCompletePopup;
             if (reusable &&
                 originalText == trimmedSearchString &&
                 invalidateReason == iface.INVALIDATE_REASON_NEW_RESULT &&
                 (originalValue == value ||
-                 this.richlistbox.mousedOverIndex === this._currentIndex)) {
+                 this.mousedOverIndex === this._currentIndex)) {
 
               // try to re-use the existing item
               let reused = item._reuseAcItem();
               if (reused) {
                 this._currentIndex++;
                 continue;
               }
             } else {
@@ -2231,54 +2290,9 @@
         }
         if (!this.selected) {
           control.selectItem(this);
         }
         control.currentItem = this;
       ]]></handler>
     </handlers>
   </binding>
-
-  <binding id="autocomplete-richlistbox" extends="chrome://global/content/bindings/richlistbox.xml#richlistbox">
-    <implementation>
-      <field name="mLastMoveTime">Date.now()</field>
-      <field name="mousedOverIndex">-1</field>
-    </implementation>
-    <handlers>
-      <handler event="mouseup">
-        <![CDATA[
-        // Don't call onPopupClick for the scrollbar buttons, thumb, slider, etc.
-        // If we hit the richlistbox and not a richlistitem, we ignore the event.
-        if (event.originalTarget.closest("richlistbox,richlistitem").localName == "richlistbox") {
-          return;
-        }
-
-        this.parentNode.onPopupClick(event);
-      ]]>
-      </handler>
-
-      <handler event="mousemove">
-        <![CDATA[
-        if (Date.now() - this.mLastMoveTime <= 30) {
-          return;
-        }
-
-        let item = event.target.closest("richlistbox,richlistitem");
-
-        // If we hit the richlistbox and not a richlistitem, we ignore the event.
-        if (item.localName == "richlistbox") {
-          return;
-        }
-
-        let index = this.getIndexOfItem(item);
-
-        this.mousedOverIndex = index;
-
-        if (item.selectedByMouseOver) {
-          this.selectedIndex = index;
-        }
-
-        this.mLastMoveTime = Date.now();
-      ]]>
-      </handler>
-    </handlers>
-  </binding>
 </bindings>
--- a/toolkit/content/xul.css
+++ b/toolkit/content/xul.css
@@ -588,17 +588,16 @@ textbox[type="autocomplete"] {
   -moz-binding: url("chrome://global/content/bindings/autocomplete.xml#autocomplete");
 }
 
 panel[type="autocomplete-richlistbox"] {
   -moz-binding: url("chrome://global/content/bindings/autocomplete.xml#autocomplete-rich-result-popup");
 }
 
 .autocomplete-richlistbox {
-  -moz-binding: url("chrome://global/content/bindings/autocomplete.xml#autocomplete-richlistbox");
   -moz-user-focus: ignore;
   overflow-x: hidden !important;
 }
 
 .autocomplete-richlistitem {
   -moz-binding: url("chrome://global/content/bindings/autocomplete.xml#autocomplete-richlistitem");
   -moz-box-orient: vertical;
   overflow: -moz-hidden-unscrollable;