Bug 1388152 - Save displayed text of select element rather than its value in form autofill submission. r=lchang
MozReview-Commit-ID: IjZKzEdLlq5
--- a/browser/extensions/formautofill/FormAutofillHandler.jsm
+++ b/browser/extensions/formautofill/FormAutofillHandler.jsm
@@ -476,16 +476,30 @@ FormAutofillHandler.prototype = {
record: {},
untouchedFields: [],
};
details.forEach(detail => {
let element = detail.elementWeakRef.get();
// Remove the unnecessary spaces
let value = element && element.value.trim();
+
+ // Save displayed text instead of actual value of select
+ // element.
+ if (type == "address" && element instanceof Ci.nsIDOMHTMLSelectElement) {
+ // Don't save the record when the option value is empty *OR* there
+ // are multiple options being selected. The empty option is usually
+ // assumed to be default along with a meaningless text to users.
+ if (!value || element.selectedOptions.length != 1) {
+ return;
+ }
+
+ value = element.selectedOptions[0].text.trim();
+ }
+
if (!value) {
return;
}
data[type].record[detail.fieldName] = value;
if (detail.state == "AUTO_FILLED") {
data[type].untouchedFields.push(detail.fieldName);
--- a/browser/extensions/formautofill/test/unit/test_onFormSubmitted.js
+++ b/browser/extensions/formautofill/test/unit/test_onFormSubmitted.js
@@ -1,15 +1,26 @@
"use strict";
Cu.import("resource://formautofill/FormAutofillContent.jsm");
const MOCK_DOC = MockDocument.createTestDocument("http://localhost:8080/test/",
`<form id="form1">
<input id="street-addr" autocomplete="street-address">
+ <select id="address-level1" autocomplete="address-level1">
+ <option value=""></option>
+ <option value="AL">Alabama</option>
+ <option value="AK">Alaska</option>
+ <option value="AP">Armed Forces Pacific</option>
+ <option value="AE">Armed Force Europe</option>
+ <option value="AA">Armed Forces America</option>
+ <option value="AZ">Arizona</option>
+ <option value="AR">Arkansas</option>
+ <option value="CA">California</option>
+ </select>
<input id="city" autocomplete="address-level2">
<input id="country" autocomplete="country">
<input id="email" autocomplete="email">
<input id="tel" autocomplete="tel">
<input id="cc-name" autocomplete="cc-name">
<input id="cc-number" autocomplete="cc-number">
<input id="cc-exp-month" autocomplete="cc-exp-month">
<input id="cc-exp-year" autocomplete="cc-exp-year">
@@ -161,16 +172,61 @@ const TESTCASES = [
"country": "USA",
"tel": "1-650-903-0800",
},
untouchedFields: [],
},
},
},
},
+ {
+ description: "Should save displayed text of select option instead of its value",
+ formValue: {
+ "address-level1": "CA",
+ "street-addr": "331 E. Evelyn Avenue",
+ "country": "USA",
+ },
+ expectedResult: {
+ formSubmission: true,
+ records: {
+ address: {
+ guid: null,
+ record: {
+ "address-level1": "California",
+ "street-address": "331 E. Evelyn Avenue",
+ "country": "USA",
+ },
+ untouchedFields: [],
+ },
+ },
+ },
+ },
+ {
+ description: "Shouldn't save select with multiple selections",
+ formValue: {
+ "address-level1": ["AL", "AK", "AP"],
+ "street-addr": "331 E. Evelyn Avenue",
+ "country": "USA",
+ "tel": "1-650-903-0800",
+ },
+ expectedResult: {
+ formSubmission: true,
+ records: {
+ address: {
+ guid: null,
+ record: {
+ "street-address": "331 E. Evelyn Avenue",
+ "country": "USA",
+ "tel": "1-650-903-0800",
+ },
+ untouchedFields: [],
+ },
+ },
+ },
+ },
];
add_task(async function handle_earlyformsubmit_event() {
do_print("Starting testcase: Test an invalid form element");
let fakeForm = MOCK_DOC.createElement("form");
sinon.spy(FormAutofillContent, "_onFormSubmit");
do_check_eq(FormAutofillContent.notify(fakeForm), true);
@@ -181,17 +237,26 @@ add_task(async function handle_earlyform
TESTCASES.forEach(testcase => {
add_task(async function check_records_saving_is_called_correctly() {
do_print("Starting testcase: " + testcase.description);
let form = MOCK_DOC.getElementById("form1");
form.reset();
for (let key in testcase.formValue) {
let input = MOCK_DOC.getElementById(key);
- input.value = testcase.formValue[key];
+ let value = testcase.formValue[key];
+
+ if (input instanceof Ci.nsIDOMHTMLSelectElement && value) {
+ input.multiple = Array.isArray(value);
+ [...input.options].forEach(option => {
+ option.selected = value.includes(option.value);
+ });
+ } else {
+ input.value = testcase.formValue[key];
+ }
}
sinon.stub(FormAutofillContent, "_onFormSubmit");
let element = MOCK_DOC.getElementById(TARGET_ELEMENT_ID);
FormAutofillContent.identifyAutofillFields(element);
FormAutofillContent.notify(form);
do_check_eq(FormAutofillContent._onFormSubmit.called,