Bug 1085745 - Add a way to select the autocomplete popup in CSS based on which input it is opened for. r=dao, a=lsblakk
authorBrian Grinstead <bgrinstead@mozilla.com>
Tue, 21 Oct 2014 20:44:38 -0700
changeset 233500 32ad158dd41a734e80acfc8693ddc6059dcb25c2
parent 233499 f42870da259bb3f54b16c86fe8becdafe8787d47
child 233501 a6414ad2ef81750886f1ddcafa3e36d4597507ec
push id4187
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:29:12 +0000
treeherdermozilla-beta@f23cc6a30c11 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdao, lsblakk
bugs1085745
milestone35.0a2
Bug 1085745 - Add a way to select the autocomplete popup in CSS based on which input it is opened for. r=dao, a=lsblakk
toolkit/content/tests/chrome/test_autocomplete2.xul
toolkit/content/widgets/autocomplete.xml
--- a/toolkit/content/tests/chrome/test_autocomplete2.xul
+++ b/toolkit/content/tests/chrome/test_autocomplete2.xul
@@ -104,16 +104,19 @@ function startTest() {
 
   autocomplete.highlightNonMatches = "false";
 
   is(autocomplete.getAttribute("highlightnonmatches"), "false",
      "highlight non matches attribute set to false correctly");
   is(autocomplete.highlightNonMatches, false,
      "highlight non matches getter returned false correctly");
 
+  ok(!autocomplete.popup.hasAttribute("autocompleteinput"),
+     "autocompleteinput on popup not set by default");
+
   check();
 }
 
 function check() {
   var autocomplete = $("autocomplete");
 
   // Toggle this value, so we can re-use the one function.
   returnResult = !returnResult;
@@ -141,16 +144,19 @@ function checkResult() {
     isnot(style.getPropertyCSSValue("color").cssText, "rgb(255, 0, 0)",
           "not nomatch and highlightNonMatches - should not be red");
 
     autocomplete.highlightNonMatches = "false";
 
     isnot(style.getPropertyCSSValue("color").cssText, "rgb(255, 0, 0)",
           "not nomatch and not highlightNonMatches - should not be red");
 
+    is (autocomplete.popup.getAttribute("autocompleteinput"), "autocomplete",
+      "The popup's autocompleteinput attribute is set to the ID of the textbox");
+
     setTimeout(check, 0);
   }
   else {
     // No result was returned, so there should be nomatch attribute
     is(autocomplete.getAttribute("nomatch"), "true",
        "nomatch attribute not correctly set when expected");
 
     // Ensure that the style is set correctly whichever way highlightNonMatches
@@ -160,16 +166,19 @@ function checkResult() {
     is(style.getPropertyCSSValue("color").cssText, "rgb(255, 0, 0)",
        "nomatch and highlightNonMatches - should be red");
 
     autocomplete.highlightNonMatches = "false";
 
     isnot(style.getPropertyCSSValue("color").cssText, "rgb(255, 0, 0)",
           "nomatch and not highlightNonMatches - should not be red");
 
+    ok(!autocomplete.popup.hasAttribute("autocompleteinput"),
+       "autocompleteinput on popup not set when closed");
+
     setTimeout(function() {
       // Unregister the factory so that we don't get in the way of other tests
       componentManager.unregisterFactory(autoCompleteSimpleID, autoCompleteSimple);
       SimpleTest.finish();
     }, 0);
   }
 }
 
--- a/toolkit/content/widgets/autocomplete.xml
+++ b/toolkit/content/widgets/autocomplete.xml
@@ -894,26 +894,42 @@ extends="chrome://global/content/binding
         // If normalMaxRows wasn't already set by the input, then set it here
         // so that we restore the correct number when the popup is hidden.
 
         // Null-check this.mInput; see bug 1017914
         if (this._normalMaxRows < 0 && this.mInput) {
           this._normalMaxRows = this.mInput.maxRows;
         }
 
+        // Set an attribute for styling the popup based on the input.
+        let inputID = "";
+        if (this.mInput && this.mInput.ownerDocument &&
+            this.mInput.ownerDocument.documentURIObject.schemeIs("chrome")) {
+          inputID = this.mInput.id;
+          // Take care of elements with no id that are inside xbl bindings
+          if (!inputID) {
+            let bindingParent = this.mInput.ownerDocument.getBindingParent(this.mInput);
+            if (bindingParent) {
+              inputID = bindingParent.id;
+            }
+          }
+        }
+        this.setAttribute("autocompleteinput", inputID);
+
         this.mPopupOpen = true;
       ]]></handler>
 
       <handler event="popuphiding"><![CDATA[
         var isListActive = true;
         if (this.selectedIndex == -1)
           isListActive = false;
         var controller = this.view.QueryInterface(Components.interfaces.nsIAutoCompleteController);
         controller.stopSearch();
 
+        this.removeAttribute("autocompleteinput");
         this.mPopupOpen = false;
 
         // Reset the maxRows property to the cached "normal" value, and reset
         // _normalMaxRows so that we can detect whether it was set by the input
         // when the popupshowing handler runs.
 
         // Null-check this.mInput; see bug 1017914
         if (this.mInput)