Bug 1152517 - Recipient autocomplete wrongly considers last mouse-hovered contact from results dropdown "selected" and then uses that unintended, random recipient upon blur (via Tab, Enter, or when moving to subject or body). r=mak
authorMagnus Melin <mkmelin+mozilla@iki.fi>
Wed, 15 Jul 2015 16:22:54 +0300
changeset 253089 c36bb974792d9572d775c746e3950355772314a4
parent 253088 d42f9b90ecad009ba7b05791c5f3ad13de4cacf4
child 253090 0462f22ccc7086dfe0194929694055b61ebff3c8
push id29061
push userryanvm@gmail.com
push dateThu, 16 Jul 2015 18:53:45 +0000
treeherdermozilla-central@a0f4a688433d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmak
bugs1152517
milestone42.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 1152517 - Recipient autocomplete wrongly considers last mouse-hovered contact from results dropdown "selected" and then uses that unintended, random recipient upon blur (via Tab, Enter, or when moving to subject or body). r=mak
toolkit/content/widgets/autocomplete.xml
--- a/toolkit/content/widgets/autocomplete.xml
+++ b/toolkit/content/widgets/autocomplete.xml
@@ -603,18 +603,37 @@
       <handler event="compositionend" phase="capturing"
                action="if (this.mController.input == this) this.mController.handleEndComposition();"/>
 
       <handler event="focus" phase="capturing"
                action="this.attachController();"/>
 
       <handler event="blur" phase="capturing"><![CDATA[
         if (!this._dontBlur) {
-          if (this.forceComplete && this.mController.matchCount >= 1)
+          if (this.forceComplete && this.mController.matchCount >= 1) {
+            // mousemove sets selected index. Don't blindly use that selected
+            // index in this blur handler since if the popup is open you can
+            // easily "select" another match just by moving the mouse over it.
+            let filledVal = this.value.replace(/.+ >> /, "").toLowerCase();
+            let selectedVal = null;
+            if (this.popup.selectedIndex >= 0) {
+              selectedVal = this.mController.getFinalCompleteValueAt(
+                this.popup.selectedIndex);
+            }
+            if (selectedVal && filledVal != selectedVal.toLowerCase()) {
+              for (let i = 0; i < this.mController.matchCount; i++) {
+                let matchVal = this.mController.getFinalCompleteValueAt(i);
+                if (matchVal.toLowerCase() == filledVal) {
+                  this.popup.selectedIndex = i;
+                  break;
+                }
+              }
+            }
             this.mController.handleEnter(false);
+          }
           this.detachController();
         }
       ]]></handler>
     </handlers>
   </binding>
 
   <binding id="autocomplete-result-popup" extends="chrome://global/content/bindings/autocomplete.xml#autocomplete-base-popup">
     <resources>