зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 3 changesets (bug 1417803) for failing browser/browser_device_width.js on Linux Stylo Disabled Debug platform. r=backout on a CLOSED TREE
Backed out changeset af5b96ec9db0 (bug 1417803) Backed out changeset cd5e96cab7c5 (bug 1417803) Backed out changeset fe9d556bdef4 (bug 1417803)
This commit is contained in:
Родитель
9a43553d12
Коммит
45cdfa2e9e
|
@ -95,30 +95,34 @@ AutofillProfileAutoCompleteSearch.prototype = {
|
|||
* @param {Object} listener the listener to notify when the search is complete
|
||||
*/
|
||||
startSearch(searchString, searchParam, previousResult, listener) {
|
||||
let {activeInput, activeSection, activeFieldDetail, savedFieldNames} = FormAutofillContent;
|
||||
this.log.debug("startSearch: for", searchString, "with input", formFillController.focusedInput);
|
||||
|
||||
this.forceStop = false;
|
||||
|
||||
this.log.debug("startSearch: for", searchString, "with input", activeInput);
|
||||
let savedFieldNames = FormAutofillContent.savedFieldNames;
|
||||
|
||||
let isAddressField = FormAutofillUtils.isAddressField(activeFieldDetail.fieldName);
|
||||
let isInputAutofilled = activeFieldDetail.state == FIELD_STATES.AUTO_FILLED;
|
||||
let allFieldNames = activeSection.allFieldNames;
|
||||
let filledRecordGUID = activeSection.getFilledRecordGUID();
|
||||
let focusedInput = formFillController.focusedInput;
|
||||
let info = FormAutofillContent.getInputDetails(focusedInput);
|
||||
let isAddressField = FormAutofillUtils.isAddressField(info.fieldName);
|
||||
let isInputAutofilled = info.state == FIELD_STATES.AUTO_FILLED;
|
||||
let handler = FormAutofillContent.getFormHandler(focusedInput);
|
||||
let allFieldNames = handler.getAllFieldNames(focusedInput);
|
||||
let filledRecordGUID = handler.getFilledRecordGUID(focusedInput);
|
||||
let searchPermitted = isAddressField ?
|
||||
FormAutofillUtils.isAutofillAddressesEnabled :
|
||||
FormAutofillUtils.isAutofillCreditCardsEnabled;
|
||||
let AutocompleteResult = isAddressField ? AddressResult : CreditCardResult;
|
||||
|
||||
ProfileAutocomplete.lastProfileAutoCompleteFocusedInput = activeInput;
|
||||
ProfileAutocomplete.lastProfileAutoCompleteFocusedInput = focusedInput;
|
||||
// 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(activeFieldDetail.fieldName) ||
|
||||
if (!searchPermitted || !savedFieldNames.has(info.fieldName) ||
|
||||
(!isInputAutofilled && filledRecordGUID) || (isAddressField &&
|
||||
allFieldNames.filter(field => savedFieldNames.has(field)).length < FormAutofillUtils.AUTOFILL_FIELDS_THRESHOLD)) {
|
||||
if (activeInput.autocomplete == "off") {
|
||||
if (focusedInput.autocomplete == "off") {
|
||||
// Create a dummy result as an empty search result.
|
||||
let result = new AutocompleteResult("", "", [], [], {});
|
||||
listener.onSearchResult(this, result);
|
||||
|
@ -142,7 +146,7 @@ AutofillProfileAutoCompleteSearch.prototype = {
|
|||
return;
|
||||
}
|
||||
|
||||
let infoWithoutElement = Object.assign({}, activeFieldDetail);
|
||||
let infoWithoutElement = Object.assign({}, info);
|
||||
delete infoWithoutElement.elementWeakRef;
|
||||
|
||||
let data = {
|
||||
|
@ -158,13 +162,12 @@ AutofillProfileAutoCompleteSearch.prototype = {
|
|||
// Sort addresses by timeLastUsed for showing the lastest used address at top.
|
||||
records.sort((a, b) => b.timeLastUsed - a.timeLastUsed);
|
||||
|
||||
let adaptedRecords = activeSection.getAdaptedProfiles(records);
|
||||
let adaptedRecords = handler.getAdaptedProfiles(records, focusedInput);
|
||||
let result = null;
|
||||
let handler = FormAutofillContent.activeHandler;
|
||||
let isSecure = InsecurePasswordUtils.isFormSecure(handler.form);
|
||||
|
||||
result = new AutocompleteResult(searchString,
|
||||
activeFieldDetail.fieldName,
|
||||
info.fieldName,
|
||||
allFieldNames,
|
||||
adaptedRecords,
|
||||
{isSecure, isInputAutofilled});
|
||||
|
@ -250,11 +253,11 @@ let ProfileAutocomplete = {
|
|||
observe(subject, topic, data) {
|
||||
switch (topic) {
|
||||
case "autocomplete-will-enter-text": {
|
||||
if (!FormAutofillContent.activeInput) {
|
||||
if (!formFillController.focusedInput) {
|
||||
// The observer notification is for autocomplete in a different process.
|
||||
break;
|
||||
}
|
||||
this._fillFromAutocompleteRow(FormAutofillContent.activeInput);
|
||||
this._fillFromAutocompleteRow(formFillController.focusedInput);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -279,7 +282,7 @@ let ProfileAutocomplete = {
|
|||
|
||||
_fillFromAutocompleteRow(focusedInput) {
|
||||
this.log.debug("_fillFromAutocompleteRow:", focusedInput);
|
||||
let formDetails = FormAutofillContent.activeFormDetails;
|
||||
let formDetails = FormAutofillContent.getFormDetails(focusedInput);
|
||||
if (!formDetails) {
|
||||
// The observer notification is for a different frame.
|
||||
return;
|
||||
|
@ -293,23 +296,28 @@ let ProfileAutocomplete = {
|
|||
}
|
||||
|
||||
let profile = JSON.parse(this.lastProfileAutoCompleteResult.getCommentAt(selectedIndex));
|
||||
let {fieldName} = FormAutofillContent.activeFieldDetail;
|
||||
let {fieldName} = FormAutofillContent.getInputDetails(focusedInput);
|
||||
let formHandler = FormAutofillContent.getFormHandler(focusedInput);
|
||||
|
||||
FormAutofillContent.activeHandler.autofillFormFields(profile).then(() => {
|
||||
formHandler.autofillFormFields(profile, focusedInput).then(() => {
|
||||
autocompleteController.searchString = profile[fieldName];
|
||||
});
|
||||
},
|
||||
|
||||
_clearProfilePreview() {
|
||||
if (!this.lastProfileAutoCompleteFocusedInput || !FormAutofillContent.activeSection) {
|
||||
let focusedInput = formFillController.focusedInput || this.lastProfileAutoCompleteFocusedInput;
|
||||
if (!focusedInput || !FormAutofillContent.getFormDetails(focusedInput)) {
|
||||
return;
|
||||
}
|
||||
|
||||
FormAutofillContent.activeSection.clearPreviewedFormFields();
|
||||
let formHandler = FormAutofillContent.getFormHandler(focusedInput);
|
||||
|
||||
formHandler.clearPreviewedFormFields(focusedInput);
|
||||
},
|
||||
|
||||
_previewSelectedProfile(selectedIndex) {
|
||||
if (!FormAutofillContent.activeInput || !FormAutofillContent.activeFormDetails) {
|
||||
let focusedInput = formFillController.focusedInput;
|
||||
if (!focusedInput || !FormAutofillContent.getFormDetails(focusedInput)) {
|
||||
// The observer notification is for a different process/frame.
|
||||
return;
|
||||
}
|
||||
|
@ -320,7 +328,9 @@ let ProfileAutocomplete = {
|
|||
}
|
||||
|
||||
let profile = JSON.parse(this.lastProfileAutoCompleteResult.getCommentAt(selectedIndex));
|
||||
FormAutofillContent.activeSection.previewFormFields(profile);
|
||||
let formHandler = FormAutofillContent.getFormHandler(focusedInput);
|
||||
|
||||
formHandler.previewFormFields(profile, focusedInput);
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -341,12 +351,6 @@ var FormAutofillContent = {
|
|||
*/
|
||||
savedFieldNames: null,
|
||||
|
||||
/**
|
||||
* @type {Object} The object where to store the active items, e.g. element,
|
||||
* handler, section, and field detail.
|
||||
*/
|
||||
_activeItems: {},
|
||||
|
||||
init() {
|
||||
FormAutofillUtils.defineLazyLogGetter(this, "FormAutofillContent");
|
||||
|
||||
|
@ -436,6 +440,25 @@ var FormAutofillContent = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the input's information from cache which is created after page identified.
|
||||
*
|
||||
* @param {HTMLInputElement} element Focused input which triggered profile searching
|
||||
* @returns {Object|null}
|
||||
* Return target input's information that cloned from content cache
|
||||
* (or return null if the information is not found in the cache).
|
||||
*/
|
||||
getInputDetails(element) {
|
||||
let formDetails = this.getFormDetails(element);
|
||||
for (let detail of formDetails) {
|
||||
let detailElement = detail.elementWeakRef.get();
|
||||
if (detailElement && element == detailElement) {
|
||||
return detail;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the form's handler from cache which is created after page identified.
|
||||
*
|
||||
|
@ -445,82 +468,28 @@ var FormAutofillContent = {
|
|||
* (or return null if the information is not found in the cache).
|
||||
*
|
||||
*/
|
||||
_getFormHandler(element) {
|
||||
getFormHandler(element) {
|
||||
let rootElement = FormLikeFactory.findRootForField(element);
|
||||
return this._formsDetails.get(rootElement);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the active form's information from cache which is created after page
|
||||
* identified.
|
||||
* Get the form's information from cache which is created after page identified.
|
||||
*
|
||||
* @param {HTMLInputElement} element Focused input which triggered profile searching
|
||||
* @returns {Array<Object>|null}
|
||||
* Return target form's information from content cache
|
||||
* (or return null if the information is not found in the cache).
|
||||
*
|
||||
*/
|
||||
get activeFormDetails() {
|
||||
let formHandler = this.activeHandler;
|
||||
getFormDetails(element) {
|
||||
let formHandler = this.getFormHandler(element);
|
||||
return formHandler ? formHandler.fieldDetails : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* All active items should be updated according the active element of
|
||||
* `formFillController.focusedInput`. All of them including element,
|
||||
* handler, section, and field detail, can be retrieved by their own getters.
|
||||
*
|
||||
* @param {HTMLElement|null} element The active item should be updated based
|
||||
* on this or `formFillController.focusedInput` will be taken.
|
||||
*/
|
||||
updateActiveInput(element) {
|
||||
element = element || formFillController.focusedInput;
|
||||
let handler = this._getFormHandler(element);
|
||||
if (handler) {
|
||||
handler.focusedInput = element;
|
||||
}
|
||||
this._activeItems = {
|
||||
handler,
|
||||
element,
|
||||
section: handler ? handler.activeSection : null,
|
||||
fieldDetail: null,
|
||||
};
|
||||
},
|
||||
|
||||
get activeInput() {
|
||||
return this._activeItems.element;
|
||||
},
|
||||
|
||||
get activeHandler() {
|
||||
return this._activeItems.handler;
|
||||
},
|
||||
|
||||
get activeSection() {
|
||||
return this._activeItems.section;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the active input's information from cache which is created after page
|
||||
* identified.
|
||||
*
|
||||
* @returns {Object|null}
|
||||
* Return the active input's information that cloned from content cache
|
||||
* (or return null if the information is not found in the cache).
|
||||
*/
|
||||
get activeFieldDetail() {
|
||||
if (!this._activeItems.fieldDetail) {
|
||||
let formDetails = this.activeFormDetails;
|
||||
if (!formDetails) {
|
||||
return null;
|
||||
}
|
||||
for (let detail of formDetails) {
|
||||
let detailElement = detail.elementWeakRef.get();
|
||||
if (detailElement && this.activeInput == detailElement) {
|
||||
this._activeItems.fieldDetail = detail;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this._activeItems.fieldDetail;
|
||||
getAllFieldNames(element) {
|
||||
let formHandler = this.getFormHandler(element);
|
||||
return formHandler ? formHandler.getAllFieldNames(element) : null;
|
||||
},
|
||||
|
||||
identifyAutofillFields(element) {
|
||||
|
@ -531,7 +500,7 @@ var FormAutofillContent = {
|
|||
Services.cpmm.sendAsyncMessage("FormAutofill:InitStorage");
|
||||
}
|
||||
|
||||
let formHandler = this._getFormHandler(element);
|
||||
let formHandler = this.getFormHandler(element);
|
||||
if (!formHandler) {
|
||||
let formLike = FormLikeFactory.createFromField(element);
|
||||
formHandler = new FormAutofillHandler(formLike);
|
||||
|
@ -551,12 +520,13 @@ var FormAutofillContent = {
|
|||
},
|
||||
|
||||
clearForm() {
|
||||
let focusedInput = this.activeInput || ProfileAutocomplete._lastAutoCompleteFocusedInput;
|
||||
let focusedInput = formFillController.focusedInput || ProfileAutocomplete._lastAutoCompleteFocusedInput;
|
||||
if (!focusedInput) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.activeSection.clearPopulatedForm();
|
||||
let formHandler = this.getFormHandler(focusedInput);
|
||||
formHandler.clearPopulatedForm(focusedInput);
|
||||
autocompleteController.searchString = "";
|
||||
},
|
||||
|
||||
|
@ -564,7 +534,7 @@ var FormAutofillContent = {
|
|||
let docWin = doc.ownerGlobal;
|
||||
let selectedIndex = ProfileAutocomplete._getSelectedIndex(docWin);
|
||||
let lastAutoCompleteResult = ProfileAutocomplete.lastProfileAutoCompleteResult;
|
||||
let focusedInput = this.activeInput;
|
||||
let focusedInput = formFillController.focusedInput;
|
||||
let mm = this._messageManagerFromWindow(docWin);
|
||||
|
||||
if (selectedIndex === -1 ||
|
||||
|
@ -575,9 +545,9 @@ var FormAutofillContent = {
|
|||
|
||||
ProfileAutocomplete._clearProfilePreview();
|
||||
} else {
|
||||
let focusedInputDetails = this.activeFieldDetail;
|
||||
let focusedInputDetails = this.getInputDetails(focusedInput);
|
||||
let profile = JSON.parse(lastAutoCompleteResult.getCommentAt(selectedIndex));
|
||||
let allFieldNames = FormAutofillContent.activeSection.allFieldNames;
|
||||
let allFieldNames = FormAutofillContent.getAllFieldNames(focusedInput);
|
||||
let profileFields = allFieldNames.filter(fieldName => !!profile[fieldName]);
|
||||
|
||||
let focusedCategory = FormAutofillUtils.getCategoryFromFieldName(focusedInputDetails.fieldName);
|
||||
|
@ -615,7 +585,7 @@ var FormAutofillContent = {
|
|||
|
||||
_onKeyDown(e) {
|
||||
let lastAutoCompleteResult = ProfileAutocomplete.lastProfileAutoCompleteResult;
|
||||
let focusedInput = FormAutofillContent.activeInput;
|
||||
let focusedInput = formFillController.focusedInput;
|
||||
|
||||
if (e.keyCode != Ci.nsIDOMKeyEvent.DOM_VK_RETURN || !lastAutoCompleteResult ||
|
||||
!focusedInput || focusedInput != ProfileAutocomplete.lastProfileAutoCompleteFocusedInput) {
|
||||
|
|
|
@ -99,10 +99,6 @@ class FormAutofillSection {
|
|||
return this._validDetails;
|
||||
}
|
||||
|
||||
set focusedInput(element) {
|
||||
this._focusedDetail = this.getFieldDetailByElement(element);
|
||||
}
|
||||
|
||||
getFieldDetailByElement(element) {
|
||||
return this._validDetails.find(
|
||||
detail => detail.elementWeakRef.get() == element
|
||||
|
@ -138,12 +134,12 @@ class FormAutofillSection {
|
|||
return this._cacheValue.allFieldNames;
|
||||
}
|
||||
|
||||
_getFieldDetailByName(fieldName) {
|
||||
getFieldDetailByName(fieldName) {
|
||||
return this._validDetails.find(detail => detail.fieldName == fieldName);
|
||||
}
|
||||
|
||||
_getTargetSet() {
|
||||
let fieldDetail = this._focusedDetail;
|
||||
_getTargetSet(element) {
|
||||
let fieldDetail = this.getFieldDetailByElement(element);
|
||||
if (!fieldDetail) {
|
||||
return null;
|
||||
}
|
||||
|
@ -156,13 +152,13 @@ class FormAutofillSection {
|
|||
return null;
|
||||
}
|
||||
|
||||
_getFieldDetails() {
|
||||
let targetSet = this._getTargetSet();
|
||||
getFieldDetailsByElement(element) {
|
||||
let targetSet = this._getTargetSet(element);
|
||||
return targetSet ? targetSet.fieldDetails : [];
|
||||
}
|
||||
|
||||
getFilledRecordGUID() {
|
||||
let targetSet = this._getTargetSet();
|
||||
getFilledRecordGUID(element) {
|
||||
let targetSet = this._getTargetSet(element);
|
||||
return targetSet ? targetSet.filledRecordGUID : null;
|
||||
}
|
||||
|
||||
|
@ -181,7 +177,7 @@ class FormAutofillSection {
|
|||
// "-moz-street-address-one-line" is used by the labels in
|
||||
// ProfileAutoCompleteResult.
|
||||
profile["-moz-street-address-one-line"] = this._getOneLineStreetAddress(profile["street-address"]);
|
||||
let streetAddressDetail = this._getFieldDetailByName("street-address");
|
||||
let streetAddressDetail = this.getFieldDetailByName("street-address");
|
||||
if (streetAddressDetail &&
|
||||
(streetAddressDetail.elementWeakRef.get() instanceof Ci.nsIDOMHTMLInputElement)) {
|
||||
profile["street-address"] = profile["-moz-street-address-one-line"];
|
||||
|
@ -190,7 +186,7 @@ class FormAutofillSection {
|
|||
let waitForConcat = [];
|
||||
for (let f of ["address-line3", "address-line2", "address-line1"]) {
|
||||
waitForConcat.unshift(profile[f]);
|
||||
if (this._getFieldDetailByName(f)) {
|
||||
if (this.getFieldDetailByName(f)) {
|
||||
if (waitForConcat.length > 1) {
|
||||
profile[f] = FormAutofillUtils.toOneLineAddress(waitForConcat);
|
||||
}
|
||||
|
@ -211,7 +207,7 @@ class FormAutofillSection {
|
|||
return;
|
||||
}
|
||||
|
||||
let detail = this._getFieldDetailByName("tel");
|
||||
let detail = this.getFieldDetailByName("tel");
|
||||
if (!detail) {
|
||||
return;
|
||||
}
|
||||
|
@ -260,7 +256,7 @@ class FormAutofillSection {
|
|||
}
|
||||
|
||||
for (let fieldName in profile) {
|
||||
let fieldDetail = this._getFieldDetailByName(fieldName);
|
||||
let fieldDetail = this.getFieldDetailByName(fieldName);
|
||||
if (!fieldDetail) {
|
||||
continue;
|
||||
}
|
||||
|
@ -297,7 +293,7 @@ class FormAutofillSection {
|
|||
return;
|
||||
}
|
||||
|
||||
let detail = this._getFieldDetailByName("cc-exp");
|
||||
let detail = this.getFieldDetailByName("cc-exp");
|
||||
if (!detail) {
|
||||
return;
|
||||
}
|
||||
|
@ -330,7 +326,7 @@ class FormAutofillSection {
|
|||
|
||||
_adaptFieldMaxLength(profile) {
|
||||
for (let key in profile) {
|
||||
let detail = this._getFieldDetailByName(key);
|
||||
let detail = this.getFieldDetailByName(key);
|
||||
if (!detail) {
|
||||
continue;
|
||||
}
|
||||
|
@ -370,13 +366,16 @@ class FormAutofillSection {
|
|||
*
|
||||
* @param {Object} profile
|
||||
* A profile to be filled in.
|
||||
* @param {HTMLElement} focusedInput
|
||||
* A focused input element needed to determine the address or credit
|
||||
* card field.
|
||||
*/
|
||||
async autofillFields(profile) {
|
||||
let focusedDetail = this._focusedDetail;
|
||||
async autofillFields(profile, focusedInput) {
|
||||
let focusedDetail = this.getFieldDetailByElement(focusedInput);
|
||||
if (!focusedDetail) {
|
||||
throw new Error("No fieldDetail for the focused input.");
|
||||
}
|
||||
let targetSet = this._getTargetSet();
|
||||
let targetSet = this._getTargetSet(focusedInput);
|
||||
if (FormAutofillUtils.isCreditCardField(focusedDetail.fieldName)) {
|
||||
// When Master Password is enabled by users, the decryption process
|
||||
// should prompt Master Password dialog to get the decrypted credit
|
||||
|
@ -416,11 +415,10 @@ class FormAutofillSection {
|
|||
// anyway.
|
||||
// For the others, the fields should be only filled when their values
|
||||
// are empty.
|
||||
let focusedInput = focusedDetail.elementWeakRef.get();
|
||||
if (element == focusedInput ||
|
||||
(element != focusedInput && !element.value)) {
|
||||
element.setUserInput(value);
|
||||
this._changeFieldState(fieldDetail, FIELD_STATES.AUTO_FILLED);
|
||||
this.changeFieldState(fieldDetail, FIELD_STATES.AUTO_FILLED);
|
||||
}
|
||||
} else if (ChromeUtils.getClassName(element) === "HTMLSelectElement") {
|
||||
let cache = this._cacheValue.matchingSelectOption.get(element) || {};
|
||||
|
@ -436,7 +434,7 @@ class FormAutofillSection {
|
|||
element.dispatchEvent(new element.ownerGlobal.Event("change", {bubbles: true}));
|
||||
}
|
||||
// Autofill highlight appears regardless if value is changed or not
|
||||
this._changeFieldState(fieldDetail, FIELD_STATES.AUTO_FILLED);
|
||||
this.changeFieldState(fieldDetail, FIELD_STATES.AUTO_FILLED);
|
||||
}
|
||||
if (fieldDetail.state == FIELD_STATES.AUTO_FILLED) {
|
||||
element.addEventListener("input", this, {mozSystemGroup: true});
|
||||
|
@ -449,8 +447,10 @@ class FormAutofillSection {
|
|||
*
|
||||
* @param {Object} profile
|
||||
* A profile to be previewed with
|
||||
* @param {HTMLElement} focusedInput
|
||||
* A focused input element for determining credit card or address fields.
|
||||
*/
|
||||
previewFormFields(profile) {
|
||||
previewFormFields(profile, focusedInput) {
|
||||
log.debug("preview profile: ", profile);
|
||||
|
||||
// Always show the decrypted credit card number when Master Password is
|
||||
|
@ -459,7 +459,7 @@ class FormAutofillSection {
|
|||
profile["cc-number"] = profile["cc-number-decrypted"];
|
||||
}
|
||||
|
||||
let fieldDetails = this._getFieldDetails();
|
||||
let fieldDetails = this.getFieldDetailsByElement(focusedInput);
|
||||
for (let fieldDetail of fieldDetails) {
|
||||
let element = fieldDetail.elementWeakRef.get();
|
||||
let value = profile[fieldDetail.fieldName] || "";
|
||||
|
@ -486,17 +486,20 @@ class FormAutofillSection {
|
|||
continue;
|
||||
}
|
||||
element.previewValue = value;
|
||||
this._changeFieldState(fieldDetail, value ? FIELD_STATES.PREVIEW : FIELD_STATES.NORMAL);
|
||||
this.changeFieldState(fieldDetail, value ? FIELD_STATES.PREVIEW : FIELD_STATES.NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear preview text and background highlight of all fields.
|
||||
*
|
||||
* @param {HTMLElement} focusedInput
|
||||
* A focused input element for determining credit card or address fields.
|
||||
*/
|
||||
clearPreviewedFormFields() {
|
||||
clearPreviewedFormFields(focusedInput) {
|
||||
log.debug("clear previewed fields in:", this.form);
|
||||
|
||||
let fieldDetails = this._getFieldDetails();
|
||||
let fieldDetails = this.getFieldDetailsByElement(focusedInput);
|
||||
for (let fieldDetail of fieldDetails) {
|
||||
let element = fieldDetail.elementWeakRef.get();
|
||||
if (!element) {
|
||||
|
@ -512,15 +515,18 @@ class FormAutofillSection {
|
|||
continue;
|
||||
}
|
||||
|
||||
this._changeFieldState(fieldDetail, FIELD_STATES.NORMAL);
|
||||
this.changeFieldState(fieldDetail, FIELD_STATES.NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear value and highlight style of all filled fields.
|
||||
*
|
||||
* @param {Object} focusedInput
|
||||
* A focused input element for determining credit card or address fields.
|
||||
*/
|
||||
clearPopulatedForm() {
|
||||
let fieldDetails = this._getFieldDetails();
|
||||
clearPopulatedForm(focusedInput) {
|
||||
let fieldDetails = this.getFieldDetailsByElement(focusedInput);
|
||||
for (let fieldDetail of fieldDetails) {
|
||||
let element = fieldDetail.elementWeakRef.get();
|
||||
if (!element) {
|
||||
|
@ -545,7 +551,7 @@ class FormAutofillSection {
|
|||
* @param {string} nextState
|
||||
* Used to determine the next state
|
||||
*/
|
||||
_changeFieldState(fieldDetail, nextState) {
|
||||
changeFieldState(fieldDetail, nextState) {
|
||||
let element = fieldDetail.elementWeakRef.get();
|
||||
|
||||
if (!element) {
|
||||
|
@ -578,7 +584,7 @@ class FormAutofillSection {
|
|||
for (let fieldDetail of this._validDetails) {
|
||||
const element = fieldDetail.elementWeakRef.get();
|
||||
element.removeEventListener("input", this, {mozSystemGroup: true});
|
||||
this._changeFieldState(fieldDetail, FIELD_STATES.NORMAL);
|
||||
this.changeFieldState(fieldDetail, FIELD_STATES.NORMAL);
|
||||
}
|
||||
this.address.filledRecordGUID = null;
|
||||
this.creditCard.filledRecordGUID = null;
|
||||
|
@ -709,7 +715,7 @@ class FormAutofillSection {
|
|||
|
||||
// Normalize Country
|
||||
if (address.record.country) {
|
||||
let detail = this._getFieldDetailByName("country");
|
||||
let detail = this.getFieldDetailByName("country");
|
||||
// Try identifying country field aggressively if it doesn't come from
|
||||
// @autocomplete.
|
||||
if (detail._reason != "autocomplete") {
|
||||
|
@ -765,7 +771,7 @@ class FormAutofillSection {
|
|||
const target = event.target;
|
||||
const fieldDetail = this.getFieldDetailByElement(target);
|
||||
const targetSet = this._getTargetSet(target);
|
||||
this._changeFieldState(fieldDetail, FIELD_STATES.NORMAL);
|
||||
this.changeFieldState(fieldDetail, FIELD_STATES.NORMAL);
|
||||
|
||||
if (!targetSet.fieldDetails.some(detail => detail.state == FIELD_STATES.AUTO_FILLED)) {
|
||||
targetSet.filledRecordGUID = null;
|
||||
|
@ -801,26 +807,6 @@ class FormAutofillHandler {
|
|||
this.timeStartedFillingMS = null;
|
||||
}
|
||||
|
||||
set focusedInput(element) {
|
||||
let section = this._sectionCache.get(element);
|
||||
if (!section) {
|
||||
section = this.sections.find(
|
||||
s => s.getFieldDetailByElement(element)
|
||||
);
|
||||
this._sectionCache.set(element, section);
|
||||
}
|
||||
|
||||
this._focusedSection = section;
|
||||
|
||||
if (section) {
|
||||
section.focusedInput = element;
|
||||
}
|
||||
}
|
||||
|
||||
get activeSection() {
|
||||
return this._focusedSection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the form is necessary to be updated. This function should be able to
|
||||
* detect any changes including all control elements in the form.
|
||||
|
@ -923,7 +909,49 @@ class FormAutofillHandler {
|
|||
return allValidDetails;
|
||||
}
|
||||
|
||||
_hasFilledSection() {
|
||||
getSectionByElement(element) {
|
||||
let section = this._sectionCache.get(element);
|
||||
if (!section) {
|
||||
section = this.sections.find(
|
||||
s => s.getFieldDetailByElement(element)
|
||||
);
|
||||
this._sectionCache.set(element, section);
|
||||
}
|
||||
return section;
|
||||
}
|
||||
|
||||
getAllFieldNames(focusedInput) {
|
||||
let section = this.getSectionByElement(focusedInput);
|
||||
return section.allFieldNames;
|
||||
}
|
||||
|
||||
previewFormFields(profile, focusedInput) {
|
||||
let section = this.getSectionByElement(focusedInput);
|
||||
section.previewFormFields(profile, focusedInput);
|
||||
}
|
||||
|
||||
clearPreviewedFormFields(focusedInput) {
|
||||
let section = this.getSectionByElement(focusedInput);
|
||||
section.clearPreviewedFormFields(focusedInput);
|
||||
}
|
||||
|
||||
clearPopulatedForm(focusedInput) {
|
||||
let section = this.getSectionByElement(focusedInput);
|
||||
section.clearPopulatedForm(focusedInput);
|
||||
}
|
||||
|
||||
getFilledRecordGUID(focusedInput) {
|
||||
let section = this.getSectionByElement(focusedInput);
|
||||
return section.getFilledRecordGUID(focusedInput);
|
||||
}
|
||||
|
||||
getAdaptedProfiles(originalProfiles, focusedInput) {
|
||||
let section = this.getSectionByElement(focusedInput);
|
||||
section.getAdaptedProfiles(originalProfiles);
|
||||
return originalProfiles;
|
||||
}
|
||||
|
||||
hasFilledSection() {
|
||||
return this.sections.some(section => section.isFilled());
|
||||
}
|
||||
|
||||
|
@ -933,10 +961,13 @@ class FormAutofillHandler {
|
|||
*
|
||||
* @param {Object} profile
|
||||
* A profile to be filled in.
|
||||
* @param {HTMLElement} focusedInput
|
||||
* A focused input element needed to determine the address or credit
|
||||
* card field.
|
||||
*/
|
||||
async autofillFormFields(profile) {
|
||||
let noFilledSectionsPreviously = !this._hasFilledSection();
|
||||
await this.activeSection.autofillFields(profile);
|
||||
async autofillFormFields(profile, focusedInput) {
|
||||
let noFilledSectionsPreviously = !this.hasFilledSection();
|
||||
await this.getSectionByElement(focusedInput).autofillFields(profile, focusedInput);
|
||||
|
||||
const onChangeHandler = e => {
|
||||
if (!e.isTrusted) {
|
||||
|
@ -948,7 +979,7 @@ class FormAutofillHandler {
|
|||
}
|
||||
}
|
||||
// Unregister listeners once no field is in AUTO_FILLED state.
|
||||
if (!this._hasFilledSection()) {
|
||||
if (!this.hasFilledSection()) {
|
||||
this.form.rootElement.removeEventListener("input", onChangeHandler, {mozSystemGroup: true});
|
||||
this.form.rootElement.removeEventListener("reset", onChangeHandler, {mozSystemGroup: true});
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@ var FormAutofillFrameScript = {
|
|||
// This is for testing purpose only which sends a message to indicate that the
|
||||
// form has been identified, and ready to open popup.
|
||||
sendAsyncMessage("FormAutofill:FieldsIdentified");
|
||||
FormAutofillContent.updateActiveInput();
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -55,7 +54,6 @@ var FormAutofillFrameScript = {
|
|||
if (!evt.isTrusted || !FormAutofillUtils.isAutofillEnabled) {
|
||||
return;
|
||||
}
|
||||
FormAutofillContent.updateActiveInput();
|
||||
|
||||
let element = evt.target;
|
||||
if (!FormAutofillUtils.isFieldEligibleForAutofill(element)) {
|
||||
|
|
|
@ -537,8 +537,7 @@ function do_test(testcases, testFn) {
|
|||
});
|
||||
|
||||
let focusedInput = doc.getElementById(testcase.focusedInputId);
|
||||
handler.focusedInput = focusedInput;
|
||||
let [adaptedProfile] = handler.activeSection.getAdaptedProfiles([testcase.profileData]);
|
||||
let [adaptedProfile] = handler.getAdaptedProfiles([testcase.profileData], focusedInput);
|
||||
await handler.autofillFormFields(adaptedProfile, focusedInput);
|
||||
Assert.equal(handlerInfo.filledRecordGUID, testcase.profileData.guid,
|
||||
"Check if filledRecordGUID is set correctly");
|
||||
|
|
|
@ -934,8 +934,8 @@ for (let testcase of TESTCASES) {
|
|||
let handler = new FormAutofillHandler(formLike);
|
||||
|
||||
handler.collectFormFields();
|
||||
handler.focusedInput = form.elements[0];
|
||||
let adaptedRecords = handler.activeSection.getAdaptedProfiles(testcase.profileData);
|
||||
let focusedInput = form.elements[0];
|
||||
let adaptedRecords = handler.getAdaptedProfiles(testcase.profileData, focusedInput);
|
||||
Assert.deepEqual(adaptedRecords, testcase.expectedResult);
|
||||
|
||||
if (testcase.expectedOptionElements) {
|
||||
|
@ -946,7 +946,8 @@ for (let testcase of TESTCASES) {
|
|||
Assert.notEqual(expectedOption, null);
|
||||
|
||||
let value = testcase.profileData[i][field];
|
||||
let cache = handler.activeSection._cacheValue.matchingSelectOption.get(select);
|
||||
let section = handler.getSectionByElement(select);
|
||||
let cache = section._cacheValue.matchingSelectOption.get(select);
|
||||
let targetOption = cache[value] && cache[value].get();
|
||||
Assert.notEqual(targetOption, null);
|
||||
|
||||
|
|
|
@ -88,13 +88,12 @@ TESTCASES.forEach(testcase => {
|
|||
for (let i in testcase.targetInput) {
|
||||
let input = doc.getElementById(testcase.targetInput[i]);
|
||||
FormAutofillContent.identifyAutofillFields(input);
|
||||
FormAutofillContent.updateActiveInput(input);
|
||||
|
||||
// Put the input element reference to `element` to make sure the result of
|
||||
// `activeFieldDetail` contains the same input element.
|
||||
// `getInputDetails` contains the same input element.
|
||||
testcase.expectedResult[i].input.elementWeakRef = Cu.getWeakReference(input);
|
||||
|
||||
inputDetailAssertion(FormAutofillContent.activeFieldDetail,
|
||||
inputDetailAssertion(FormAutofillContent.getInputDetails(input),
|
||||
testcase.expectedResult[i].input);
|
||||
|
||||
let formDetails = testcase.expectedResult[i].form;
|
||||
|
@ -105,7 +104,7 @@ TESTCASES.forEach(testcase => {
|
|||
formDetail.elementWeakRef = Cu.getWeakReference(doc.querySelector(queryString));
|
||||
}
|
||||
|
||||
FormAutofillContent.activeFormDetails.forEach((detail, index) => {
|
||||
FormAutofillContent.getFormDetails(input).forEach((detail, index) => {
|
||||
inputDetailAssertion(detail, formDetails[index]);
|
||||
});
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче