Bug 1411509 - Add the country address format parser. r=lchang,steveck

MozReview-Commit-ID: 9ViNsQYeO0d

--HG--
extra : rebase_source : f26166b0e67fedfb7dd40e5f9c184eb662985de8
This commit is contained in:
Scott Wu 2017-10-27 15:17:58 +08:00
parent 21d957d700
commit 2e849a739c
3 changed files with 96 additions and 0 deletions

View File

@ -238,6 +238,54 @@ this.FormAutofillUtils = {
return this._collators[country];
},
/**
* Parse a country address format string and outputs an array of fields.
* Spaces, commas, and other literals are ignored in this implementation.
* For example, format string "%A%n%C, %S" should return:
* [
* {fieldId: "street-address", newLine: true},
* {fieldId: "address-level2"},
* {fieldId: "address-level1"},
* ]
*
* @param {string} fmt Country address format string
* @returns {array<object>} List of fields
*/
parseAddressFormat(fmt) {
if (!fmt) {
throw new Error("fmt string is missing.");
}
// Based on the list of fields abbreviations in
// https://github.com/googlei18n/libaddressinput/wiki/AddressValidationMetadata
const fieldsLookup = {
N: "name",
O: "organization",
A: "street-address",
S: "address-level1",
C: "address-level2",
Z: "postal-code",
n: "newLine",
};
return fmt.match(/%[^%]/g).reduce((parsed, part) => {
// Take the first letter of each segment and try to identify it
let fieldId = fieldsLookup[part[1]];
// Early return if cannot identify part.
if (!fieldId) {
return parsed;
}
// If a new line is detected, add an attribute to the previous field.
if (fieldId == "newLine") {
let size = parsed.length;
if (size) {
parsed[size - 1].newLine = true;
}
return parsed;
}
return parsed.concat({fieldId});
}, []);
},
/**
* Use alternative country name list to identify a country code from a
* specified country name.

View File

@ -0,0 +1,47 @@
"use strict";
Cu.import("resource://formautofill/FormAutofillUtils.jsm");
add_task(async function test_parseAddressFormat() {
const TEST_CASES = [
{
fmt: "%N%n%O%n%A%n%C, %S %Z", // US
parsed: [
{fieldId: "name", newLine: true},
{fieldId: "organization", newLine: true},
{fieldId: "street-address", newLine: true},
{fieldId: "address-level2"},
{fieldId: "address-level1"},
{fieldId: "postal-code"},
],
},
{
fmt: "%N%n%O%n%A%n%C %S %Z", // CA
parsed: [
{fieldId: "name", newLine: true},
{fieldId: "organization", newLine: true},
{fieldId: "street-address", newLine: true},
{fieldId: "address-level2"},
{fieldId: "address-level1"},
{fieldId: "postal-code"},
],
},
{
fmt: "%N%n%O%n%A%n%Z %C", // DE
parsed: [
{fieldId: "name", newLine: true},
{fieldId: "organization", newLine: true},
{fieldId: "street-address", newLine: true},
{fieldId: "postal-code"},
{fieldId: "address-level2"},
],
},
];
Assert.throws(() => FormAutofillUtils.parseAddressFormat(),
/fmt string is missing./,
"Should throw if fmt is empty");
for (let tc of TEST_CASES) {
Assert.deepEqual(FormAutofillUtils.parseAddressFormat(tc.fmt), tc.parsed);
}
});

View File

@ -38,6 +38,7 @@ support-files =
[test_migrateRecords.js]
[test_nameUtils.js]
[test_onFormSubmitted.js]
[test_parseAddressFormat.js]
[test_profileAutocompleteResult.js]
[test_phoneNumber.js]
[test_reconcile.js]