Bug 1329628 - Part 2. Append additional item to inform which fields are about to be filled at bottom of popup. draft
authorRay Lin <ralin@mozilla.com>
Tue, 23 May 2017 17:07:42 +0800
changeset 582874 62ac45726cd53a04010b273a4dfa149a8f67c177
parent 582873 52c12fb00cede0d2f99e486d772a71949e32daf7
child 582875 4b01fac942464d9b8d9072cf868425a84b5aa02b
push id60223
push userbmo:ralin@mozilla.com
push dateTue, 23 May 2017 09:34:08 +0000
bugs1329628
milestone55.0a1
Bug 1329628 - Part 2. Append additional item to inform which fields are about to be filled at bottom of popup. MozReview-Commit-ID: GfGJqx5bfJa
browser/extensions/formautofill/FormAutofillContent.jsm
browser/extensions/formautofill/ProfileAutoCompleteResult.jsm
browser/extensions/formautofill/content/formautofill.xml
--- a/browser/extensions/formautofill/FormAutofillContent.jsm
+++ b/browser/extensions/formautofill/FormAutofillContent.jsm
@@ -274,16 +274,35 @@ let ProfileAutocomplete = {
       return;
     }
 
     let profile = JSON.parse(this._lastAutoCompleteResult.getCommentAt(selectedIndex));
     let formHandler = FormAutofillContent.getFormHandler(focusedInput);
 
     formHandler.previewFormFields(profile);
   },
+
+  _updateAdditionalInfoText(selectedIndex) {
+    let lastFocusedInput = formFillController.focusedInput || this._lastAutoCompleteFocusedInput;
+    if (!lastFocusedInput || !FormAutofillContent.getFormDetails(lastFocusedInput)) {
+      return;
+    }
+
+    let mm = this._frameMMFromWindow(lastFocusedInput.ownerGlobal);
+    let extraFields;
+    if (!!~selectedIndex) {
+      let focusedInput = formFillController.focusedInput;
+      let focusedFieldName = FormAutofillContent.getInputDetails(focusedInput).fieldName;
+      let willFillFields = JSON.parse(this._lastAutoCompleteResult.getLabelAt(selectedIndex)).willFillFields || [];
+
+      extraFields = willFillFields.filter(field => field !== focusedFieldName);
+    }
+
+    mm.sendSyncMessage("FormAutofill:WillPreviewProfile", extraFields);
+  },
 };
 
 /**
  * Handles content's interactions for the process.
  *
  * NOTE: Declares it by "var" to make it accessible in unit tests.
  */
 var FormAutofillContent = {
@@ -455,13 +474,15 @@ var FormAutofillContent = {
   _previewProfile(doc) {
     let selectedIndex = ProfileAutocomplete._getSelectedIndex(doc.ownerGlobal);
 
     if (selectedIndex === -1) {
       ProfileAutocomplete._clearProfilePreview();
     } else {
       ProfileAutocomplete._previewSelectedProfile(selectedIndex);
     }
+
+    ProfileAutocomplete._updateAdditionalInfoText(selectedIndex);
   },
 };
 
 
 FormAutofillContent.init();
--- a/browser/extensions/formautofill/ProfileAutoCompleteResult.jsm
+++ b/browser/extensions/formautofill/ProfileAutoCompleteResult.jsm
@@ -32,16 +32,22 @@ this.ProfileAutoCompleteResult = functio
     this.searchResult = Ci.nsIAutoCompleteResult.RESULT_SUCCESS;
   } else {
     this.searchResult = Ci.nsIAutoCompleteResult.RESULT_NOMATCH;
   }
 
   this._popupLabels = this._generateLabels(this._focusedFieldName,
                                            this._allFieldNames,
                                            this._matchingProfiles);
+
+  // Append an additional info item  at the bottom of list
+  this._popupLabels.push({
+    primary: this._allFieldNames,
+    secondary: "",
+  });
 };
 
 ProfileAutoCompleteResult.prototype = {
 
   // The user's query string
   searchString: "",
 
   // The default item that should be entered if none is selected
@@ -138,16 +144,17 @@ ProfileAutoCompleteResult.prototype = {
     return profiles.filter(profile => {
       return !!profile[focusedFieldName];
     }).map(profile => {
       return {
         primary: profile[focusedFieldName],
         secondary: this._getSecondaryLabel(focusedFieldName,
                                            allFieldNames,
                                            profile),
+        willFillFields: allFieldNames.filter((fieldName) => !!profile[fieldName]),
       };
     });
   },
 
   /**
    * Retrieves a result
    * @param   {number} index The index of the result requested
    * @returns {string} The result at the specified index
@@ -174,16 +181,22 @@ ProfileAutoCompleteResult.prototype = {
 
   /**
    * Retrieves a style hint specific to a particular index.
    * @param   {number} index The index of the style hint requested
    * @returns {string} The style hint at the specified index
    */
   getStyleAt(index) {
     this._checkIndexBounds(index);
+
+    // The last result would be additional information item.
+    if (index === this._popupLabels.length - 1) {
+      return "autofill-additional-info";
+    }
+
     return "autofill-profile";
   },
 
   /**
    * Retrieves an image url.
    * @param   {number} index The index of the image url requested
    * @returns {string} The image url at the specified index
    */
--- a/browser/extensions/formautofill/content/formautofill.xml
+++ b/browser/extensions/formautofill/content/formautofill.xml
@@ -112,26 +112,54 @@
 
     <xbl:content xmlns="http://www.w3.org/1999/xhtml">
       <div anonid="profile-additional-info" class="profile-additional-info"></div>
     </xbl:content>
 
     <implementation implements="nsIDOMXULSelectControlItemElement">
       <constructor>
         <![CDATA[
+          this.mm = document.ownerGlobal.gBrowser.selectedBrowser.messageManager;
+          this._updateAdditionalInfoBox = ({data: extraFields}) => this._updateText(extraFields);
+
           this._infoBox = document.getAnonymousElementByAttribute(
             this, "anonid", "profile-additional-info"
           );
 
           this._adjustAcItem();
         ]]>
       </constructor>
 
+      <property name="selected" onget="return this.getAttribute('selected') == 'true';">
+        <setter><![CDATA[
+          if (val) {
+            this.setAttribute("selected", "true");
+          } else {
+            this.removeAttribute("selected");
+          }
+        ]]></setter>
+      </property>
+
+      <method name="_updateText">
+        <parameter name="extraFields"/>
+        <body>
+        <![CDATA[
+          let text= extraFields && extraFields.length ? `Also fill ${extraFields.join(", ")}` : "";
+
+          this._infoBox.textContent = text;
+        ]]>
+        </body>
+      </method>
+
       <method name="_cleanup">
-        <body></body>
+        <body>
+        <![CDATA[
+          this.mm.removeMessageListener("FormAutofill:WillPreviewProfile", this._updateAdditionalInfoBox);
+        ]]>
+        </body>
       </method>
 
       <method name="_onChanged">
         <body></body>
       </method>
 
       <method name="_onOverflow">
         <body></body>
@@ -142,14 +170,15 @@
       </method>
 
       <method name="_adjustAcItem">
         <body>
         <![CDATA[
           let outerBoxRect = this.parentNode.getBoundingClientRect();
 
           this._infoBox.style.width =  outerBoxRect.width + "px";
+          this.mm.addMessageListener("FormAutofill:WillPreviewProfile", this._updateAdditionalInfoBox);
         ]]>
         </body>
       </method>
     </implementation>
   </binding>
 </bindings>