Bug 1192505 - location bar suggestions disappear if mouse moves. r=adw, a=sylvestre
authorMarco Bonardo <mbonardo@mozilla.com>
Thu, 29 Oct 2015 11:11:09 +0100
changeset 305360 c670c565d7286a5e0ae74fa4b2086d86d5f9889e
parent 305359 00fe0e2bbdbbaccea3e87549d76464d28cd677f1
child 305361 f79375fd1d44427c27141f444d7b60b13afe7835
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersadw, sylvestre
bugs1192505
milestone44.0a2
Bug 1192505 - location bar suggestions disappear if mouse moves. r=adw, a=sylvestre
browser/base/content/urlbarBindings.xml
toolkit/content/widgets/autocomplete.xml
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -1539,25 +1539,16 @@ file, You can obtain one at http://mozil
             }
           ]]>
         </body>
       </method>
 
     </implementation>
     <handlers>
 
-      <handler event="select"><![CDATA[
-        // When the user selects one of matches, stop the search to avoid
-        // changing the underlying result unexpectedly.
-        if (!this._ignoreNextSelect && this.selectedIndex >= 0) {
-          let controller = this.view.QueryInterface(Components.interfaces.nsIAutoCompleteController);
-          controller.stopSearch();
-        }
-      ]]></handler>
-
       <handler event="mousedown"><![CDATA[
         // Required to make the xul:label.text-link elements in the search
         // suggestions notification work correctly when clicked on Linux.
         // This is copied from the mousedown handler in
         // browser-search-autocomplete-result-popup, which apparently had a
         // similar problem.
         event.preventDefault();
       ]]></handler>
--- a/toolkit/content/widgets/autocomplete.xml
+++ b/toolkit/content/widgets/autocomplete.xml
@@ -204,16 +204,18 @@
         <parameter name="aEndIndex"/>
         <body><![CDATA[
           this.inputField.setSelectionRange(aStartIndex, aEndIndex);
         ]]></body>
       </method>
 
       <method name="onSearchBegin">
         <body><![CDATA[
+          if (this.popup && typeof this.popup.onSearchBegin == "function")
+            this.popup.onSearchBegin();
           if (this._searchBeginHandler)
             this._searchBeginHandler();
         ]]></body>
       </method>
 
       <method name="onSearchComplete">
         <body><![CDATA[
           if (this.mController.matchCount == 0)
@@ -1039,16 +1041,22 @@ extends="chrome://global/content/binding
           this.richlistbox.ensureElementIsVisible(
             this.richlistbox.selectedItem || this.richlistbox.firstChild);
 
           return val;
         ]]>
         </setter>
       </property>
 
+      <method name="onSearchBegin">
+        <body><![CDATA[
+          this.richlistbox.mouseSelectedIndex = -1;
+        ]]></body>
+      </method>
+
       <method name="openAutocompletePopup">
         <parameter name="aInput"/>
         <parameter name="aElement"/>
         <body>
           <![CDATA[
           // until we have "baseBinding", (see bug #373652) this allows
           // us to override openAutocompletePopup(), but still call
           // the method on the base class
@@ -1221,19 +1229,23 @@ extends="chrome://global/content/binding
             let url = Components.classes["@mozilla.org/intl/texttosuburi;1"].
               getService(Components.interfaces.nsITextToSubURI).
               unEscapeURIForUI("UTF-8", controller.getValueAt(this._currentIndex));
 
             if (this._currentIndex < existingItemsCount) {
               // re-use the existing item
               item = this.richlistbox.childNodes[this._currentIndex];
 
-              // Completely re-use the existing richlistitem if it's the same
+              // Completely re-use the existing richlistitem if it's the same.
+              // Also re-use it if we are about to replace the currently mouse
+              // selected item, to avoid surprising the user.
               if (item.getAttribute("text") == trimmedSearchString &&
-                  item.getAttribute("url") == url) {
+                   (item.getAttribute("url") == url ||
+                    this.richlistbox.mouseSelectedIndex === this._currentIndex)
+                  ) {
                 item.collapsed = false;
                 this._currentIndex++;
                 continue;
               }
             }
             else {
               // need to create a new item
               item = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "richlistitem");
@@ -1987,47 +1999,49 @@ extends="chrome://global/content/binding
         <children/>
       </xul:treerows>
     </content>
   </binding>
 
   <binding id="autocomplete-richlistbox" extends="chrome://global/content/bindings/richlistbox.xml#richlistbox">
     <implementation>
       <field name="mLastMoveTime">Date.now()</field>
+      <field name="mouseSelectedIndex">-1</field>
     </implementation>
     <handlers>
       <handler event="mouseup">
         <![CDATA[
         // don't call onPopupClick for the scrollbar buttons, thumb, slider, etc.
-        var item = event.originalTarget;
-
-        while (item && item.localName != "richlistitem")
+        let item = event.originalTarget;
+        while (item && item.localName != "richlistitem") {
           item = item.parentNode;
+        }
 
         if (!item)
           return;
 
         this.parentNode.onPopupClick(event);
       ]]>
       </handler>
 
       <handler event="mousemove">
         <![CDATA[
         if (Date.now() - this.mLastMoveTime > 30) {
-         var item = event.target;
-
-         while (item && item.localName != "richlistitem")
+         let item = event.target;
+         while (item && item.localName != "richlistitem") {
            item = item.parentNode;
+         }
 
          if (!item)
            return;
 
-         var rc = this.getIndexOfItem(item);
-         if (rc != this.selectedIndex)
-            this.selectedIndex = rc;
+         let index = this.getIndexOfItem(item);
+         if (index != this.selectedIndex) {
+            this.mouseSelectedIndex = this.selectedIndex = index;
+         }
 
          this.mLastMoveTime = Date.now();
         }
       ]]>
       </handler>
     </handlers>
   </binding>