Bug 1404773 - Part 3. (WIP) Implement clear populated form function for form autofill clear button.
MozReview-Commit-ID: 8No9FXWJv0p
--- a/browser/extensions/formautofill/FormAutofillContent.jsm
+++ b/browser/extensions/formautofill/FormAutofillContent.jsm
@@ -106,27 +106,23 @@ AutofillProfileAutoCompleteSearch.protot
let isInputAutofilled = info.state == FIELD_STATES.AUTO_FILLED;
let handler = FormAutofillContent.getFormHandler(focusedInput);
let allFieldNames = handler.allFieldNames;
let filledRecordGUID = isAddressField ? handler.address.filledRecordGUID : handler.creditCard.filledRecordGUID;
let searchPermitted = isAddressField ?
FormAutofillUtils.isAutofillAddressesEnabled :
FormAutofillUtils.isAutofillCreditCardsEnabled;
- // TODO: This flag is used to temporarily hide clear form popup before the feature
- // is done, and it should be removed in Bug 1404773.
- const clearFormButtonDisabled = true;
-
// Fallback to form-history if ...
// - specified autofill feature is pref off.
// - no profile can fill the currently-focused input.
// - the current form has already been populated.
// - (address only) less than 3 inputs are covered by all saved fields in the storage.
if (!searchPermitted || !savedFieldNames.has(info.fieldName) ||
- (!isInputAutofilled | clearFormButtonDisabled && filledRecordGUID) || (isAddressField &&
+ (!isInputAutofilled && filledRecordGUID) || (isAddressField &&
allFieldNames.filter(field => savedFieldNames.has(field)).length < FormAutofillUtils.AUTOFILL_FIELDS_THRESHOLD)) {
if (focusedInput.autocomplete == "off") {
// Create a dummy AddressResult as an empty search result.
let result = new AddressResult("", "", [], [], {});
listener.onSearchResult(this, result);
return;
}
let formHistory = Cc["@mozilla.org/autocomplete/search;1?name=form-history"]
@@ -145,17 +141,17 @@ AutofillProfileAutoCompleteSearch.protot
let data = {
collectionName: isAddressField ? ADDRESSES_COLLECTION_NAME : CREDITCARDS_COLLECTION_NAME,
info: infoWithoutElement,
searchString,
};
// Show clear form popup if click on filled fields.
- if (isInputAutofilled && !clearFormButtonDisabled) {
+ if (isInputAutofilled) {
let result = null;
result = new ClearFormResult(searchString, info.fieldName, [], [], {});
listener.onSearchResult(this, result);
ProfileAutocomplete.setProfileAutoCompleteResult(result);
return;
}
this._getRecords(data).then((records) => {
@@ -531,16 +527,28 @@ var FormAutofillContent = {
this._formsDetails.set(formHandler.form.rootElement, formHandler);
this.log.debug("Adding form handler to _formsDetails:", formHandler);
validDetails.forEach(detail =>
this._markAsAutofillField(detail.elementWeakRef.get())
);
},
+ clearForm() {
+ let focusedInput = formFillController.focusedInput || ProfileAutocomplete._lastAutoCompleteFocusedInput;
+ if (!focusedInput) {
+ return;
+ }
+ let formHandler = this.getFormHandler(focusedInput);
+ if (!formHandler) {
+ return;
+ }
+ formHandler.clearPopulatedForm(focusedInput);
+ },
+
previewProfile(doc) {
let docWin = doc.ownerGlobal;
let selectedIndex = ProfileAutocomplete._getSelectedIndex(docWin);
let lastAutoCompleteResult = ProfileAutocomplete.getProfileAutoCompleteResult();
let focusedInput = formFillController.focusedInput;
let mm = this._messageManagerFromWindow(docWin);
if (selectedIndex === -1 ||
@@ -595,13 +603,16 @@ var FormAutofillContent = {
let selectedIndex = ProfileAutocomplete._getSelectedIndex(e.target.ownerGlobal);
let selectedRowStyle = lastAutoCompleteResult.getStyleAt(selectedIndex);
if (selectedRowStyle == "autofill-footer") {
focusedInput.addEventListener("DOMAutoComplete", () => {
Services.cpmm.sendAsyncMessage("FormAutofill:OpenPreferences");
}, {once: true});
}
+ if (selectedRowStyle == "autofill-clear-button") {
+ FormAutofillContent.clearForm();
+ }
},
};
FormAutofillContent.init();
--- a/browser/extensions/formautofill/FormAutofillHandler.jsm
+++ b/browser/extensions/formautofill/FormAutofillHandler.jsm
@@ -531,16 +531,33 @@ FormAutofillHandler.prototype = {
if (fieldDetail.state == FIELD_STATES.AUTO_FILLED) {
continue;
}
this.changeFieldState(fieldDetail, FIELD_STATES.NORMAL);
}
},
+ clearPopulatedForm(focusedInput) {
+ let fieldDetails = this.getFieldDetailsByElement(focusedInput);
+ for (let fieldDetail of fieldDetails) {
+ let element = fieldDetail.elementWeakRef.get();
+ if (!element) {
+ log.warn(fieldDetail.fieldName, "is unreachable");
+ continue;
+ }
+
+ if (fieldDetail.state == FIELD_STATES.AUTO_FILLED) {
+ element.setUserInput("");
+ }
+
+ this.changeFieldState(fieldDetail, FIELD_STATES.NORMAL);
+ }
+ },
+
/**
* Change the state of a field to correspond with different presentations.
*
* @param {Object} fieldDetail
* A fieldDetail of which its element is about to update the state.
* @param {string} nextState
* Used to determine the next state
*/
--- a/browser/extensions/formautofill/ProfileAutoCompleteResult.jsm
+++ b/browser/extensions/formautofill/ProfileAutoCompleteResult.jsm
@@ -397,22 +397,22 @@ class ClearFormResult extends ProfileAut
constructor(...args) {
super(...args);
this.searchResult = Ci.nsIAutoCompleteResult.RESULT_SUCCESS;
}
_generateLabels() {
return [
- {primary: "Clear Form", secondary: ""}, // clear form button
+ "", // clear form button
{primary: "", secondary: ""}, // more options button
];
}
getStyleAt(index) {
this._checkIndexBounds(index);
if (index == this.matchCount - 1) {
return "autofill-footer";
}
- return "autofill-profile";
+ return "autofill-clear-button";
}
}
--- a/browser/extensions/formautofill/content/FormAutofillFrameScript.js
+++ b/browser/extensions/formautofill/content/FormAutofillFrameScript.js
@@ -37,16 +37,17 @@ var FormAutofillFrameScript = {
this._hasPendingTask = false;
this._nextHandleElement = null;
});
},
init() {
addEventListener("focusin", this);
addMessageListener("FormAutofill:PreviewProfile", this);
+ addMessageListener("FormAutofill:ClearForm", this);
addMessageListener("FormAutoComplete:PopupClosed", this);
addMessageListener("FormAutoComplete:PopupOpened", this);
},
handleEvent(evt) {
if (!evt.isTrusted || !FormAutofillUtils.isAutofillEnabled) {
return;
}
@@ -80,23 +81,28 @@ var FormAutofillFrameScript = {
const doc = content.document;
const {chromeEventHandler} = doc.ownerGlobal.getInterface(Ci.nsIDocShell);
switch (message.name) {
case "FormAutofill:PreviewProfile": {
FormAutofillContent.previewProfile(doc);
break;
}
+ case "FormAutofill:ClearForm": {
+ FormAutofillContent.clearForm();
+ break;
+ }
case "FormAutoComplete:PopupClosed": {
FormAutofillContent.previewProfile(doc);
chromeEventHandler.removeEventListener("keydown", FormAutofillContent._onKeyDown,
{capturing: true});
break;
}
case "FormAutoComplete:PopupOpened": {
chromeEventHandler.addEventListener("keydown", FormAutofillContent._onKeyDown,
{capturing: true});
+ break;
}
}
},
};
FormAutofillFrameScript.init();