Bug 1340468 - Notify formautofill add-on of which item is being selected. r=MattN
MozReview-Commit-ID: 3YfW35Zon1Q
--- a/browser/extensions/formautofill/FormAutofillContent.jsm
+++ b/browser/extensions/formautofill/FormAutofillContent.jsm
@@ -232,16 +232,50 @@ let ProfileAutocomplete = {
return;
}
let profile = JSON.parse(this._lastAutoCompleteResult.getCommentAt(selectedIndex));
let formHandler = FormAutofillContent.getFormHandler(focusedInput);
formHandler.autofillFormFields(profile, focusedInput);
},
+
+ _previewFromAutocompleteRow(doc) {
+ let mm = this._frameMMFromWindow(doc.ownerGlobal);
+ let selectedIndexResult = mm.sendSyncMessage("FormAutoComplete:GetSelectedIndex", {});
+ if (selectedIndexResult.length != 1 || !Number.isInteger(selectedIndexResult[0])) {
+ throw new Error("Invalid autocomplete selectedIndex");
+ }
+
+ let selectedIndex = selectedIndexResult[0];
+ if (selectedIndex == -1) {
+ // Clear exisiting preview feilds
+ [...doc.getElementsByTagName("form")]
+ .map(form => FormAutofillContent._formsDetails.get(form))
+ .filter(fh => !!fh)
+ .forEach(fh => fh.clearPreviewedFormFields());
+ return;
+ }
+
+ let focusedInput = formFillController.focusedInput;
+ if (!focusedInput || !FormAutofillContent.getFormDetails(focusedInput)) {
+ // The observer notification is for a different process/frame.
+ return;
+ }
+
+ if (!this._lastAutoCompleteResult ||
+ this._lastAutoCompleteResult.getStyleAt(selectedIndex) != "autofill-profile") {
+ return;
+ }
+
+ let profile = JSON.parse(this._lastAutoCompleteResult.getCommentAt(selectedIndex));
+ let formHandler = FormAutofillContent.getFormHandler(focusedInput);
+
+ formHandler.previewFormFields(profile);
+ },
};
/**
* Handles content's interactions for the process.
*
* NOTE: Declares it by "var" to make it accessible in unit tests.
*/
var FormAutofillContent = {
@@ -352,12 +386,16 @@ var FormAutofillContent = {
this.log.debug("Adding form handler to _formsDetails:", formHandler);
formHandler.fieldDetails.forEach(detail => this._markAsAutofillField(detail.element));
});
},
_markAsAutofillField(field) {
formFillController.markAsAutofillField(field);
},
+
+ _previewProfile(doc) {
+ ProfileAutocomplete._previewFromAutocompleteRow(doc);
+ },
};
FormAutofillContent.init();
--- a/browser/extensions/formautofill/FormAutofillHandler.jsm
+++ b/browser/extensions/formautofill/FormAutofillHandler.jsm
@@ -124,9 +124,46 @@ FormAutofillHandler.prototype = {
}
let value = profile[fieldDetail.fieldName];
if (value) {
fieldDetail.element.setUserInput(value);
}
}
},
+
+ /**
+ * Populates result to the preview layers with given profile.
+ *
+ * @param {Object} profile
+ * A profile to be previewed with
+ */
+ previewFormFields(profile) {
+ log.debug("preview profile in autofillFormFields:", profile);
+ for (let fieldDetail of this.fieldDetails) {
+ let value = profile[fieldDetail.fieldName] || "";
+
+ // Skip the fields that already has text entered
+ if (fieldDetail.element.value) {
+ continue;
+ }
+
+ // fieldDetail.element.highlight = !!value;
+ // fieldDetail.element.setUserInputPreview = value;
+
+ // TODO: Remove these once DOM preview API is ready
+ fieldDetail.element.style.backgroundColor = value ? "rgba(36,138,235,.1)" : "transparent";
+ fieldDetail.element.placeholder = value;
+ }
+ },
+
+ clearPreviewedFormFields() {
+ log.debug("clear previewed fields in:", this.form);
+ for (let fieldDetail of this.fieldDetails) {
+ // fieldDetail.element.setUserInputPreview("");
+ // fieldDetail.element.highlight = false;
+
+ // TODO: Remove these once DOM preview API is ready
+ fieldDetail.element.style.backgroundColor = "transparent";
+ fieldDetail.element.placeholder = "";
+ }
+ },
};
--- a/browser/extensions/formautofill/content/FormAutofillFrameScript.js
+++ b/browser/extensions/formautofill/content/FormAutofillFrameScript.js
@@ -17,16 +17,19 @@ Cu.import("resource://formautofill/FormA
/**
* Handles content's interactions for the frame.
*
* NOTE: Declares it by "var" to make it accessible in unit tests.
*/
var FormAutofillFrameScript = {
init() {
addEventListener("DOMContentLoaded", this);
+ addMessageListener("FormAutofill:PreviewProfile", this);
+ addMessageListener("FormAutoComplete:PopupClosed", this);
+ addMessageListener("FormAutoComplete:SetSelectedIndex", this);
},
handleEvent(evt) {
if (!evt.isTrusted) {
return;
}
if (!Services.prefs.getBoolPref("browser.formautofill.enabled")) {
@@ -39,11 +42,25 @@ var FormAutofillFrameScript = {
if (!(doc instanceof Ci.nsIDOMHTMLDocument)) {
return;
}
FormAutofillContent.identifyAutofillFields(doc);
break;
}
}
},
+
+ receiveMessage(aMessage) {
+ if (!Services.prefs.getBoolPref("browser.formautofill.enabled")) {
+ return;
+ }
+
+ switch (aMessage.name) {
+ case "FormAutofill:PreviewProfile":
+ case "FormAutoComplete:PopupClosed":
+ case "FormAutoComplete:SetSelectedIndex":
+ FormAutofillContent._previewProfile(content.document);
+ break;
+ }
+ },
};
FormAutofillFrameScript.init();
--- a/browser/extensions/formautofill/content/formautofill.xml
+++ b/browser/extensions/formautofill/content/formautofill.xml
@@ -33,29 +33,48 @@
this, "anonid", "profile-item-box"
);
this._label = document.getAnonymousElementByAttribute(
this, "anonid", "profile-label"
);
this._comment = document.getAnonymousElementByAttribute(
this, "anonid", "profile-comment"
);
+ this.mm = document.ownerGlobal.gBrowser.selectedBrowser.messageManager;
this._adjustAcItem();
]]>
</constructor>
+ <property name="selected" onget="return this.getAttribute('selected') == 'true';">
+ <setter><![CDATA[
+ if (val) {
+ this.setAttribute("selected", "true");
+ } else {
+ this.removeAttribute("selected");
+ }
+
+ this.mm.sendAsyncMessage("FormAutofill:PreviewProfile");
+
+ return val;
+ ]]></setter>
+ </property>
+
<method name="_cleanup">
<body>
<![CDATA[
this._itemBox.removeAttribute("size");
]]>
</body>
</method>
+ <method name="_onChanged">
+ <body></body>
+ </method>
+
<method name="_onOverflow">
<body></body>
</method>
<method name="_onUnderflow">
<body></body>
</method>