--- a/browser/extensions/formautofill/FormAutofillHeuristics.jsm
+++ b/browser/extensions/formautofill/FormAutofillHeuristics.jsm
@@ -12,16 +12,19 @@ this.EXPORTED_SYMBOLS = ["FormAutofillHe
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
/**
* Returns the autocomplete information of fields according to heuristics.
*/
this.FormAutofillHeuristics = {
VALID_FIELDS: [
+ "given-name",
+ "additional-name",
+ "family-name",
"organization",
"street-address",
"address-level2",
"address-level1",
"postal-code",
"country",
"tel",
"email",
--- a/browser/extensions/formautofill/ProfileAutoCompleteResult.jsm
+++ b/browser/extensions/formautofill/ProfileAutoCompleteResult.jsm
@@ -85,42 +85,62 @@ ProfileAutoCompleteResult.prototype = {
* @param {Array<Object>} allFieldNames The field names in the same section
* @param {object} profile The profile providing the labels to show.
* @returns {string} The secondary label
*/
_getSecondaryLabel(focusedFieldName, allFieldNames, profile) {
/* TODO: Since "name" is a special case here, so the secondary "name" label
will be refined when the handling rule for "name" is ready.
*/
- const possibleNameFields = ["given-name", "additional-name", "family-name"];
+ const possibleNameFields = [
+ "name",
+ "given-name",
+ "additional-name",
+ "family-name",
+ ];
+
focusedFieldName = possibleNameFields.includes(focusedFieldName) ?
"name" : focusedFieldName;
- if (!profile.name) {
- profile.name = FormAutofillUtils.generateFullName(profile["given-name"],
- profile["family-name"],
- profile["additional-name"]);
+
+ // Clones the profile to avoid exposing our modification.
+ let clonedProfile = Object.assign({}, profile);
+ if (!clonedProfile.name) {
+ clonedProfile.name =
+ FormAutofillUtils.generateFullName(clonedProfile["given-name"],
+ clonedProfile["family-name"],
+ clonedProfile["additional-name"]);
}
const secondaryLabelOrder = [
"street-address", // Street address
- "name", // Full name if needed
+ "name", // Full name
"address-level2", // City/Town
"organization", // Company or organization name
"address-level1", // Province/State (Standardized code if possible)
"country", // Country
"postal-code", // Postal code
"tel", // Phone number
"email", // Email address
];
for (const currentFieldName of secondaryLabelOrder) {
- if (focusedFieldName != currentFieldName &&
- allFieldNames.includes(currentFieldName) &&
- profile[currentFieldName]) {
- return profile[currentFieldName];
+ if (focusedFieldName == currentFieldName ||
+ !clonedProfile[currentFieldName]) {
+ continue;
+ }
+
+ let matching;
+ if (currentFieldName == "name") {
+ matching = allFieldNames.some(fieldName => possibleNameFields.includes(fieldName));
+ } else {
+ matching = allFieldNames.includes(currentFieldName);
+ }
+
+ if (matching) {
+ return clonedProfile[currentFieldName];
}
}
return ""; // Nothing matched.
},
_generateLabels(focusedFieldName, allFieldNames, profiles) {
// Skip results without a primary label.
--- a/browser/extensions/formautofill/ProfileStorage.jsm
+++ b/browser/extensions/formautofill/ProfileStorage.jsm
@@ -10,16 +10,19 @@
*
* {
* version: 1,
* profiles: [
* {
* guid, // 12 character...
*
* // profile
+ * given-name,
+ * additional-name,
+ * family-name,
* organization, // Company
* street-address, // (Multiline)
* address-level2, // City/Town
* address-level1, // Province (Standardized code if possible)
* postal-code,
* country, // ISO 3166
* tel,
* email,
@@ -58,16 +61,19 @@ XPCOMUtils.defineLazyServiceGetter(this,
this.log = null;
FormAutofillUtils.defineLazyLogGetter(this, this.EXPORTED_SYMBOLS[0]);
const SCHEMA_VERSION = 1;
// Name-related fields will be handled in follow-up bugs due to the complexity.
const VALID_FIELDS = [
+ "given-name",
+ "additional-name",
+ "family-name",
"organization",
"street-address",
"address-level2",
"address-level1",
"postal-code",
"country",
"tel",
"email",
--- a/browser/extensions/formautofill/test/unit/test_collectFormFields.js
+++ b/browser/extensions/formautofill/test/unit/test_collectFormFields.js
@@ -20,16 +20,18 @@ const TESTCASES = [
document: `<form><input id="given-name" autocomplete="given-name">
<input id="family-name" autocomplete="family-name">
<input id="street-addr" autocomplete="street-address">
<input id="city" autocomplete="address-level2">
<input id="country" autocomplete="country">
<input id="email" autocomplete="email">
<input id="tel" autocomplete="tel"></form>`,
fieldDetails: [
+ {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"},
+ {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "street-address"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "country"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
],
},
{
@@ -37,16 +39,18 @@ const TESTCASES = [
document: `<form><input id="given-name" autocomplete="shipping given-name">
<input id="family-name" autocomplete="shipping family-name">
<input id="street-addr" autocomplete="shipping street-address">
<input id="city" autocomplete="shipping address-level2">
<input id="country" autocomplete="shipping country">
<input id='email' autocomplete="shipping email">
<input id="tel" autocomplete="shipping tel"></form>`,
fieldDetails: [
+ {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name"},
+ {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "address-level2"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "country"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel"},
],
},
{
@@ -54,16 +58,18 @@ const TESTCASES = [
document: `<form><input id="given-name" autocomplete="shipping given-name">
<input id="family-name" autocomplete="shipping family-name">
<input id="street-addr" autocomplete="shipping street-address">
<input id="city" autocomplete="shipping address-level2">
<input id="country" autocomplete="shipping country">
<input id='email' autocomplete="shipping email">
<input id="tel" autocomplete="shipping tel"></form>`,
fieldDetails: [
+ {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name"},
+ {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "address-level2"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "country"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel"},
],
},
];
--- a/browser/extensions/formautofill/test/unit/test_markAsAutofillField.js
+++ b/browser/extensions/formautofill/test/unit/test_markAsAutofillField.js
@@ -1,25 +1,31 @@
"use strict";
Cu.import("resource://formautofill/FormAutofillContent.jsm");
const TESTCASES = [
{
- description: "Form containing 5 fields with autocomplete attribute.",
+ description: "Form containing 8 fields with autocomplete attribute.",
document: `<form>
+ <input id="given-name" autocomplete="given-name">
+ <input id="additional-name" autocomplete="additional-name">
+ <input id="family-name" autocomplete="family-name">
<input id="street-addr" autocomplete="street-address">
<input id="city" autocomplete="address-level2">
<input id="country" autocomplete="country">
<input id="email" autocomplete="email">
<input id="tel" autocomplete="tel">
<input id="without-autocomplete-1">
<input id="without-autocomplete-2">
</form>`,
expectedResult: [
+ "given-name",
+ "additional-name",
+ "family-name",
"street-addr",
"city",
"country",
"email",
"tel",
],
},
{
--- a/browser/extensions/formautofill/test/unit/test_profileAutocompleteResult.js
+++ b/browser/extensions/formautofill/test/unit/test_profileAutocompleteResult.js
@@ -1,30 +1,34 @@
"use strict";
Cu.import("resource://formautofill/ProfileAutoCompleteResult.jsm");
let matchingProfiles = [{
guid: "test-guid-1",
+ "given-name": "Timothy",
+ "family-name": "Berners-Lee",
organization: "Sesame Street",
"street-address": "123 Sesame Street.",
tel: "1-345-345-3456.",
}, {
guid: "test-guid-2",
+ "given-name": "John",
+ "family-name": "Doe",
organization: "Mozilla",
"street-address": "331 E. Evelyn Avenue",
tel: "1-650-903-0800",
}, {
guid: "test-guid-3",
organization: "",
"street-address": "321, No Name St.",
tel: "1-000-000-0000",
}];
-let allFieldNames = ["street-address", "organization", "tel"];
+let allFieldNames = ["given-name", "family-name", "street-address", "organization", "tel"];
let testCases = [{
description: "Focus on an `organization` field",
options: {},
matchingProfiles,
allFieldNames,
searchString: "",
fieldName: "organization",
@@ -101,26 +105,26 @@ let testCases = [{
searchResult: Ci.nsIAutoCompleteResult.RESULT_SUCCESS,
defaultIndex: 0,
items: [{
value: "123 Sesame Street.",
style: "autofill-profile",
comment: JSON.stringify(matchingProfiles[0]),
label: JSON.stringify({
primary: "123 Sesame Street.",
- secondary: "Sesame Street",
+ secondary: "Timothy Berners-Lee",
}),
image: "",
}, {
value: "331 E. Evelyn Avenue",
style: "autofill-profile",
comment: JSON.stringify(matchingProfiles[1]),
label: JSON.stringify({
primary: "331 E. Evelyn Avenue",
- secondary: "Mozilla",
+ secondary: "John Doe",
}),
image: "",
}, {
value: "321, No Name St.",
style: "autofill-profile",
comment: JSON.stringify(matchingProfiles[2]),
label: JSON.stringify({
primary: "321, No Name St.",
--- a/browser/extensions/formautofill/test/unit/test_profileStorage.js
+++ b/browser/extensions/formautofill/test/unit/test_profileStorage.js
@@ -5,16 +5,19 @@
"use strict";
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://formautofill/ProfileStorage.jsm");
const TEST_STORE_FILE_NAME = "test-profile.json";
const TEST_PROFILE_1 = {
+ "given-name": "Timothy",
+ "additional-name": "John",
+ "family-name": "Berners-Lee",
organization: "World Wide Web Consortium",
"street-address": "32 Vassar Street\nMIT Room 32-G524",
"address-level2": "Cambridge",
"address-level1": "MA",
"postal-code": "02139",
country: "US",
tel: "+1 617 253 5702",
email: "timbl@w3.org",