зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1339721 - Use FormAutofillHandler.autofillFormFields to fill in fields.; r=MattN
MozReview-Commit-ID: KgphpgQ4FNp --HG-- extra : rebase_source : 7d8dc62c683ccc439385db78ecdde62a999e8978
This commit is contained in:
Родитель
d80bc035b4
Коммит
214ce08657
|
@ -233,20 +233,9 @@ let ProfileAutocomplete = {
|
|||
}
|
||||
|
||||
let profile = JSON.parse(this._lastAutoCompleteResult.getCommentAt(selectedIndex));
|
||||
let formHandler = FormAutofillContent.getFormHandler(focusedInput);
|
||||
|
||||
// TODO: FormAutofillHandler.autofillFormFields will be used for filling
|
||||
// fields logic eventually.
|
||||
for (let inputInfo of formDetails) {
|
||||
// Skip filling the value of focused input which is filled in
|
||||
// FormFillController.
|
||||
if (inputInfo.element === focusedInput) {
|
||||
continue;
|
||||
}
|
||||
let value = profile[inputInfo.fieldName];
|
||||
if (value) {
|
||||
inputInfo.element.setUserInput(value);
|
||||
}
|
||||
}
|
||||
formHandler.autofillFormFields(profile, focusedInput);
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -295,19 +284,32 @@ var FormAutofillContent = {
|
|||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the form's handler 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 handler from content cache
|
||||
* (or return null if the information is not found in the cache).
|
||||
*
|
||||
*/
|
||||
getFormHandler(element) {
|
||||
let rootElement = FormLikeFactory.findRootForField(element);
|
||||
return this._formsDetails.get(rootElement);
|
||||
},
|
||||
|
||||
/**
|
||||
* 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 that cloned from content cache
|
||||
* Return target form's information from content cache
|
||||
* (or return null if the information is not found in the cache).
|
||||
*
|
||||
*/
|
||||
getFormDetails(element) {
|
||||
let rootElement = FormLikeFactory.findRootForField(element);
|
||||
let formDetails = this._formsDetails.get(rootElement);
|
||||
return formDetails ? formDetails.fieldDetails : null;
|
||||
let formHandler = this.getFormHandler(element);
|
||||
return formHandler ? formHandler.fieldDetails : null;
|
||||
},
|
||||
|
||||
getAllFieldNames(element) {
|
||||
|
|
|
@ -103,45 +103,30 @@ FormAutofillHandler.prototype = {
|
|||
|
||||
/**
|
||||
* Processes form fields that can be autofilled, and populates them with the
|
||||
* data provided by backend.
|
||||
* profile provided by backend.
|
||||
*
|
||||
* @param {Array<Object>} autofillResult
|
||||
* Data returned by the user interface.
|
||||
* [{
|
||||
* section: Value originally provided to the user interface.
|
||||
* addressType: Value originally provided to the user interface.
|
||||
* contactType: Value originally provided to the user interface.
|
||||
* fieldName: Value originally provided to the user interface.
|
||||
* value: String with which the field should be updated.
|
||||
* index: Index to match the input in fieldDetails
|
||||
* }],
|
||||
* }
|
||||
* @param {Object} profile
|
||||
* A profile to be filled in.
|
||||
* @param {Object} focusedInput
|
||||
* A focused input element which is skipped for filling.
|
||||
*/
|
||||
autofillFormFields(autofillResult) {
|
||||
log.debug("autofillFormFields:", autofillResult);
|
||||
for (let field of autofillResult) {
|
||||
// TODO: Skip filling the value of focused input which is filled in
|
||||
// FormFillController.
|
||||
autofillFormFields(profile, focusedInput) {
|
||||
log.debug("profile in autofillFormFields:", profile);
|
||||
for (let fieldDetail of this.fieldDetails) {
|
||||
// Avoid filling field value in the following cases:
|
||||
// 1. the focused input which is filled in FormFillController.
|
||||
// 2. a non-empty input field
|
||||
// 3. the invalid value set
|
||||
|
||||
// Get the field details, if it was processed by the user interface.
|
||||
let fieldDetail = this.fieldDetails[field.index];
|
||||
|
||||
// Avoid the invalid value set
|
||||
if (!fieldDetail || !field.value) {
|
||||
if (fieldDetail.element === focusedInput ||
|
||||
fieldDetail.element.value) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let info = FormAutofillHeuristics.getInfo(fieldDetail.element);
|
||||
if (!info ||
|
||||
field.section != info.section ||
|
||||
field.addressType != info.addressType ||
|
||||
field.contactType != info.contactType ||
|
||||
field.fieldName != info.fieldName) {
|
||||
Cu.reportError("Autocomplete tokens mismatched");
|
||||
continue;
|
||||
let value = profile[fieldDetail.fieldName];
|
||||
if (value) {
|
||||
fieldDetail.element.setUserInput(value);
|
||||
}
|
||||
|
||||
fieldDetail.element.setUserInput(field.value);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -13,7 +13,7 @@ const TESTCASES = [
|
|||
<input id="street-addr"><input id="city"><input id="country">
|
||||
<input id='email'><input id="tel"></form>`,
|
||||
fieldDetails: [],
|
||||
profileData: [],
|
||||
profileData: {},
|
||||
expectedResult: {
|
||||
"street-addr": "",
|
||||
"city": "",
|
||||
|
@ -40,15 +40,13 @@ const TESTCASES = [
|
|||
{"section": "", "addressType": "", "contactType": "", "fieldName": "email", "element": {}},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel", "element": {}},
|
||||
],
|
||||
profileData: [
|
||||
{"section": "", "addressType": "", "fieldName": "given-name", "contactType": "", "index": 0, "value": "foo"},
|
||||
{"section": "", "addressType": "", "fieldName": "family-name", "contactType": "", "index": 1, "value": "bar"},
|
||||
{"section": "", "addressType": "", "fieldName": "street-address", "contactType": "", "index": 2, "value": "2 Harrison St"},
|
||||
{"section": "", "addressType": "", "fieldName": "address-level2", "contactType": "", "index": 3, "value": "San Francisco"},
|
||||
{"section": "", "addressType": "", "fieldName": "country", "contactType": "", "index": 4, "value": "US"},
|
||||
{"section": "", "addressType": "", "fieldName": "email", "contactType": "", "index": 5, "value": "foo@mozilla.com"},
|
||||
{"section": "", "addressType": "", "fieldName": "tel", "contactType": "", "index": 6, "value": "1234567"},
|
||||
],
|
||||
profileData: {
|
||||
"street-address": "2 Harrison St",
|
||||
"address-level2": "San Francisco",
|
||||
"country": "US",
|
||||
"email": "foo@mozilla.com",
|
||||
"tel": "1234567",
|
||||
},
|
||||
expectedResult: {
|
||||
"street-addr": "2 Harrison St",
|
||||
"city": "San Francisco",
|
||||
|
@ -75,15 +73,13 @@ const TESTCASES = [
|
|||
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email", "element": {}},
|
||||
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel", "element": {}},
|
||||
],
|
||||
profileData: [
|
||||
{"section": "", "addressType": "shipping", "fieldName": "given-name", "contactType": "", "index": 0, "value": "foo"},
|
||||
{"section": "", "addressType": "shipping", "fieldName": "family-name", "contactType": "", "index": 1, "value": "bar"},
|
||||
{"section": "", "addressType": "shipping", "fieldName": "street-address", "contactType": "", "index": 2, "value": "2 Harrison St"},
|
||||
{"section": "", "addressType": "shipping", "fieldName": "address-level2", "contactType": "", "index": 3, "value": "San Francisco"},
|
||||
{"section": "", "addressType": "shipping", "fieldName": "country", "contactType": "", "index": 4, "value": "US"},
|
||||
{"section": "", "addressType": "shipping", "fieldName": "email", "contactType": "", "index": 5, "value": "foo@mozilla.com"},
|
||||
{"section": "", "addressType": "shipping", "fieldName": "tel", "contactType": "", "index": 6, "value": "1234567"},
|
||||
],
|
||||
profileData: {
|
||||
"street-address": "2 Harrison St",
|
||||
"address-level2": "San Francisco",
|
||||
"country": "US",
|
||||
"email": "foo@mozilla.com",
|
||||
"tel": "1234567",
|
||||
},
|
||||
expectedResult: {
|
||||
"street-addr": "2 Harrison St",
|
||||
"city": "San Francisco",
|
||||
|
@ -110,15 +106,13 @@ const TESTCASES = [
|
|||
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email", "element": {}},
|
||||
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel", "element": {}},
|
||||
],
|
||||
profileData: [
|
||||
{"section": "", "addressType": "shipping", "fieldName": "given-name", "contactType": "", "index": 0, "value": "foo"},
|
||||
{"section": "", "addressType": "shipping", "fieldName": "family-name", "contactType": "", "index": 1, "value": "bar"},
|
||||
{"section": "", "addressType": "shipping", "fieldName": "street-address", "contactType": "", "index": 2, "value": "2 Harrison St"},
|
||||
{"section": "", "addressType": "shipping", "fieldName": "address-level2", "contactType": "", "index": 3, "value": "San Francisco"},
|
||||
{"section": "", "addressType": "shipping", "fieldName": "country", "contactType": "", "index": 4, "value": "US"},
|
||||
{"section": "", "addressType": "shipping", "fieldName": "email", "contactType": "", "index": 5},
|
||||
{"section": "", "addressType": "shipping", "fieldName": "tel", "contactType": "", "index": 6},
|
||||
],
|
||||
profileData: {
|
||||
"street-address": "2 Harrison St",
|
||||
"address-level2": "San Francisco",
|
||||
"country": "US",
|
||||
"email": "",
|
||||
"tel": "",
|
||||
},
|
||||
expectedResult: {
|
||||
"street-addr": "2 Harrison St",
|
||||
"city": "San Francisco",
|
||||
|
@ -145,15 +139,13 @@ const TESTCASES = [
|
|||
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email", "element": {}},
|
||||
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel", "element": {}},
|
||||
],
|
||||
profileData: [
|
||||
{"section": "", "addressType": "shipping", "fieldName": "given-name", "contactType": "", "index": 0, "value": "foo"},
|
||||
{"section": "", "addressType": "shipping", "fieldName": "family-name", "contactType": "", "index": 1, "value": "bar"},
|
||||
{"section": "", "addressType": "shipping", "fieldName": "street-address", "contactType": "", "index": 2, "value": "2 Harrison St"},
|
||||
{"section": "", "addressType": "shipping", "fieldName": "address-level2", "contactType": "", "index": 3, "value": "San Francisco"},
|
||||
{"section": "", "addressType": "shipping", "fieldName": "country", "contactType": "", "index": 4, "value": "US"},
|
||||
{"section": "", "addressType": "shipping", "fieldName": "email", "contactType": "", "index": 5, "value": "foo@mozilla.com"},
|
||||
{"section": "", "addressType": "shipping", "fieldName": "tel", "contactType": "", "index": 6, "value": "1234567"},
|
||||
],
|
||||
profileData: {
|
||||
"street-address": "",
|
||||
"address-level2": "",
|
||||
"country": "",
|
||||
"email": "foo@mozilla.com",
|
||||
"tel": "1234567",
|
||||
},
|
||||
expectedResult: {
|
||||
"street-addr": "",
|
||||
"city": "",
|
||||
|
@ -174,17 +166,29 @@ for (let tc of TESTCASES) {
|
|||
testcase.document);
|
||||
let form = doc.querySelector("form");
|
||||
let handler = new FormAutofillHandler(form);
|
||||
let onChangePromises = [];
|
||||
|
||||
handler.fieldDetails = testcase.fieldDetails;
|
||||
handler.fieldDetails.forEach((field, index) => {
|
||||
field.element = doc.querySelectorAll("input")[index];
|
||||
let element = doc.querySelectorAll("input")[index];
|
||||
field.element = element;
|
||||
if (!testcase.profileData[field.fieldName]) {
|
||||
// Avoid waiting for `change` event of a input with a blank value to
|
||||
// be filled.
|
||||
return;
|
||||
}
|
||||
onChangePromises.push(new Promise(resolve => {
|
||||
element.addEventListener("change", () => {
|
||||
let id = element.id;
|
||||
Assert.equal(element.value, testcase.expectedResult[id],
|
||||
"Check the " + id + " fields were filled with correct data");
|
||||
resolve();
|
||||
}, {once: true});
|
||||
}));
|
||||
});
|
||||
|
||||
handler.autofillFormFields(testcase.profileData);
|
||||
for (let id in testcase.expectedResult) {
|
||||
Assert.equal(doc.getElementById(id).value, testcase.expectedResult[id],
|
||||
"Check the " + id + " fields were filled with correct data");
|
||||
}
|
||||
yield Promise.all(onChangePromises);
|
||||
});
|
||||
})();
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче