Bug 1022925 - Part 2: Move alternative name to extension file. r=lchang,scottwu

MozReview-Commit-ID: 4rFagXU5iit

--HG--
extra : rebase_source : af0f34250fd0f92c84aa3d9b648e72d5e08ca828
This commit is contained in:
steveck-chung 2017-11-10 18:36:22 +08:00
Родитель 84109f9c52
Коммит 45ecb2c0e5
6 изменённых файлов: 163 добавлений и 22 удалений

Просмотреть файл

@ -4,17 +4,16 @@
"use strict";
this.EXPORTED_SYMBOLS = ["FormAutofillUtils"];
this.EXPORTED_SYMBOLS = ["FormAutofillUtils", "AddressDataLoader"];
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
const ADDRESS_REFERENCES = "resource://formautofill/addressmetadata/addressReferences.js";
const ADDRESS_METADATA_PATH = "resource://formautofill/addressmetadata/";
const ADDRESS_REFERENCES = "addressReferences.js";
const ADDRESS_REFERENCES_EXT = "addressReferencesExt.js";
// TODO: We only support US in MVP. We are going to support more countries in
// bug 1370193.
const ALTERNATIVE_COUNTRY_NAMES = {
"US": ["US", "United States of America", "United States", "America", "U.S.", "USA", "U.S.A.", "U.S.A"],
};
// TODO: This list should become a pref in Bug 1413494
const SUPPORTED_COUNTRY_LIST = ["US"];
const ADDRESSES_COLLECTION_NAME = "addresses";
const CREDITCARDS_COLLECTION_NAME = "creditCards";
@ -43,6 +42,77 @@ const MAX_FIELD_VALUE_LENGTH = 200;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
let AddressDataLoader = {
// Status of address data loading. We'll load all the countries with basic level 1
// information while requesting conutry information, and set country to true.
// Level 1 Set is for recording which country's level 1/level 2 data is loaded,
// since we only load this when getCountryAddressData called with level 1 parameter.
_dataLoaded: {
country: false,
level1: new Set(),
},
/**
* Load address data and extension script into a sandbox from different paths.
* @param {string} path
* The path for address data and extension script. It could be root of the address
* metadata folder(addressmetadata/) or under specific country(addressmetadata/TW/).
* @returns {object}
* A sandbox that contains address data object with properties from extension.
*/
_loadScripts(path) {
let sandbox = {};
let extSandbox = {};
try {
sandbox = FormAutofillUtils.loadDataFromScript(path + ADDRESS_REFERENCES);
extSandbox = FormAutofillUtils.loadDataFromScript(path + ADDRESS_REFERENCES_EXT);
} catch (e) {
// Will return only address references if extension loading failed or empty sandbox if
// address references loading failed.
return sandbox;
}
if (extSandbox.addressDataExt) {
for (let key in extSandbox.addressDataExt) {
Object.assign(sandbox.addressData[key], extSandbox.addressDataExt[key]);
}
}
return sandbox;
},
/**
* We'll cache addressData in the loader once the data loaded from scripts.
* It'll become the example below after loading addressReferences with extension:
* addressData: {
"data/US": {"lang": "en", ...// Data defined in libaddressinput metadata
* "alternative_names": ... // Data defined in extension }
* "data/CA": {} // Other supported country metadata
* "data/TW": {} // Other supported country metadata
* "data/TW/台北市": {} // Other supported country level 1 metadata
* }
* @param {string} country
* @param {string} level1
* @returns {object}
*/
getData(country, level1 = null) {
// Load the addressData if needed
if (!this._dataLoaded.country) {
this._addressData = this._loadScripts(ADDRESS_METADATA_PATH).addressData;
this._dataLoaded.country = true;
}
if (!level1) {
return this._addressData[`data/${country}`];
}
// If level1 is set, load addressReferences under country folder with specific
// country/level 1 for level 2 information.
if (!this._dataLoaded.level1.has(country)) {
Object.assign(this._addressData,
this._loadScripts(`${ADDRESS_METADATA_PATH}${country}/`).addressData);
this._dataLoaded.level1.add(country);
}
return this._addressData[`data/${country}/${level1}`];
},
};
this.FormAutofillUtils = {
get AUTOFILL_FIELDS_THRESHOLD() { return 3; },
get isAutofillEnabled() { return this.isAutofillAddressesEnabled || this.isAutofillCreditCardsEnabled; },
@ -94,7 +164,7 @@ this.FormAutofillUtils = {
"cc-exp-year": "creditCard",
"cc-exp": "creditCard",
},
_addressDataLoaded: false,
_collators: {},
_reAlternativeCountryNames: {},
@ -221,18 +291,15 @@ this.FormAutofillUtils = {
return sandbox;
},
/**
* Get country address data. Fallback to US if not found.
* @param {string} country
* @returns {object}
*/
getCountryAddressData(country) {
// Load the addressData if needed
if (!this._addressDataLoaded) {
Object.assign(this, this.loadDataFromScript(ADDRESS_REFERENCES));
this._addressDataLoaded = true;
// Get country address data and fallback to US if not found.
// See AddressDataLoader.getData for more details of addressData structure.
getCountryAddressData(country, level1 = null) {
let metadata = AddressDataLoader.getData(country, level1);
if (!metadata) {
metadata = level1 ? null : AddressDataLoader.getData("US");
}
return this.addressData[`data/${country}`] || this.addressData["data/US"];
return metadata;
},
/**
@ -311,12 +378,13 @@ this.FormAutofillUtils = {
* @returns {string} The matching country code.
*/
identifyCountryCode(countryName, countrySpecified) {
let countries = countrySpecified ? [countrySpecified] : Object.keys(ALTERNATIVE_COUNTRY_NAMES);
let countries = countrySpecified ? [countrySpecified] : SUPPORTED_COUNTRY_LIST;
for (let country of countries) {
let collators = this.getCollators(country);
let alternativeCountryNames = ALTERNATIVE_COUNTRY_NAMES[country];
let metadata = this.getCountryAddressData(country);
let alternativeCountryNames = metadata.alternative_names || [metadata.name];
let reAlternativeCountryNames = this._reAlternativeCountryNames[country];
if (!reAlternativeCountryNames) {
reAlternativeCountryNames = this._reAlternativeCountryNames[country] = [];
@ -445,7 +513,7 @@ this.FormAutofillUtils = {
break;
}
case "country": {
if (ALTERNATIVE_COUNTRY_NAMES[value]) {
if (this.getCountryAddressData(value).alternative_names) {
for (let option of selectEl.options) {
if (this.identifyCountryCode(option.text, value) || this.identifyCountryCode(option.value, value)) {
return option;

Просмотреть файл

@ -10,6 +10,11 @@
// The data below is initially copied from
// https://chromium-i18n.appspot.com/ssl-aggregate-address
// WARNING: DO NOT change any value or add additional properties in addressData.
// We only accept the metadata of the supported countries that is copied from libaddressinput directly.
// Please edit addressReferencesExt.js instead if you want to add new property as complement
// or overwrite the existing properties.
var addressData = {
"data/US": {"lang": "en", "upper": "CS", "sub_zipexs": "35000,36999~99500,99999~96799~85000,86999~71600,72999~34000,34099~09000,09999~96200,96699~90000,96199~80000,81999~06000,06999~19700,19999~20000,56999~32000,34999~30000,39901~96910,96932~96700,96899~83200,83999~60000,62999~46000,47999~50000,52999~66000,67999~40000,42799~70000,71599~03900,04999~96960,96979~20600,21999~01000,05544~48000,49999~96941,96944~55000,56799~38600,39799~63000,65999~59000,59999~68000,69999~88900,89999~03000,03899~07000,08999~87000,88499~10000,00544~27000,28999~58000,58999~96950,96952~43000,45999~73000,74999~97000,97999~96940~15000,19699~00600,00999~02800,02999~29000,29999~57000,57999~37000,38599~75000,73344~84000,84999~05000,05999~00800,00899~20100,24699~98000,99499~24700,26999~53000,54999~82000,83414", "zipex": "95014,22162-1010", "name": "UNITED STATES", "zip": "(\\d{5})(?:[ \\-](\\d{4}))?", "zip_name_type": "zip", "fmt": "%N%n%O%n%A%n%C, %S %Z", "state_name_type": "state", "id": "data/US", "languages": "en", "sub_keys": "AL~AK~AS~AZ~AR~AA~AE~AP~CA~CO~CT~DE~DC~FL~GA~GU~HI~ID~IL~IN~IA~KS~KY~LA~ME~MH~MD~MA~MI~FM~MN~MS~MO~MT~NE~NV~NH~NJ~NM~NY~NC~ND~MP~OH~OK~OR~PW~PA~PR~RI~SC~SD~TN~TX~UT~VT~VI~VA~WA~WV~WI~WY", "key": "US", "posturl": "https://tools.usps.com/go/ZipLookupAction!input.action", "require": "ACSZ", "sub_names": "Alabama~Alaska~American Samoa~Arizona~Arkansas~Armed Forces (AA)~Armed Forces (AE)~Armed Forces (AP)~California~Colorado~Connecticut~Delaware~District of Columbia~Florida~Georgia~Guam~Hawaii~Idaho~Illinois~Indiana~Iowa~Kansas~Kentucky~Louisiana~Maine~Marshall Islands~Maryland~Massachusetts~Michigan~Micronesia~Minnesota~Mississippi~Missouri~Montana~Nebraska~Nevada~New Hampshire~New Jersey~New Mexico~New York~North Carolina~North Dakota~Northern Mariana Islands~Ohio~Oklahoma~Oregon~Palau~Pennsylvania~Puerto Rico~Rhode Island~South Carolina~South Dakota~Tennessee~Texas~Utah~Vermont~Virgin Islands~Virginia~Washington~West Virginia~Wisconsin~Wyoming", "sub_zips": "3[56]~99[5-9]~96799~8[56]~71[6-9]|72~340~09~96[2-6]~9[0-5]|96[01]~8[01]~06~19[7-9]~20[02-5]|569~3[23]|34[1-9]~3[01]|398|39901~969([1-2]\\d|3[12])~967[0-8]|9679[0-8]|968~83[2-9]~6[0-2]~4[67]~5[0-2]~6[67]~4[01]|42[0-7]~70|71[0-5]~039|04~969[67]~20[6-9]|21~01|02[0-7]|05501|05544~4[89]~9694[1-4]~55|56[0-7]~38[6-9]|39[0-7]~6[3-5]~59~6[89]~889|89~03[0-8]~0[78]~87|88[0-4]~1[0-4]|06390|00501|00544~2[78]~58~9695[0-2]~4[3-5]~7[34]~97~969(39|40)~1[5-8]|19[0-6]~00[679]~02[89]~29~57~37|38[0-5]~7[5-9]|885|73301|73344~84~05~008~201|2[23]|24[0-6]~98|99[0-4]~24[7-9]|2[56]~5[34]~82|83[01]|83414"},
};

Просмотреть файл

@ -0,0 +1,17 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* exported addressDataExt */
/* eslint max-len: 0 */
"use strict";
// "addressDataExt" uses the same key as "addressData" in "addressReferences.js" and contains
// contains the information we need but absent in "libaddressinput" such as alternative names.
// TODO: We only support the alternative name of US in MVP. We are going to support more countries in
// bug 1370193.
var addressDataExt = {
"data/US": {"alternative_names": ["US", "United States of America", "United States", "America", "U.S.", "USA", "U.S.A.", "U.S.A"]},
};

Просмотреть файл

@ -0,0 +1,49 @@
"use strict";
Cu.import("resource://formautofill/FormAutofillUtils.jsm");
add_task(async function test_initalState() {
// addressData should not exist
Assert.equal(AddressDataLoader._addressData, undefined);
// Verify _dataLoaded state
Assert.equal(AddressDataLoader._dataLoaded.country, false);
Assert.equal(AddressDataLoader._dataLoaded.level1.size, 0);
});
add_task(async function test_loadDataState() {
sinon.spy(AddressDataLoader, "_loadScripts");
let metadata = FormAutofillUtils.getCountryAddressData("US");
Assert.ok(AddressDataLoader._addressData, "addressData exists");
// Verify _dataLoaded state
Assert.equal(AddressDataLoader._dataLoaded.country, true);
Assert.equal(AddressDataLoader._dataLoaded.level1.size, 0);
// _loadScripts should be called
sinon.assert.called(AddressDataLoader._loadScripts);
// Verify metadata
Assert.equal(metadata.id, "data/US");
Assert.ok(metadata.alternative_names,
"US alternative names should be loaded from extension");
AddressDataLoader._loadScripts.reset();
// Load data without country
let newMetadata = FormAutofillUtils.getCountryAddressData();
// _loadScripts should not be called
sinon.assert.notCalled(AddressDataLoader._loadScripts);
Assert.deepEqual(metadata, newMetadata, "metadata should be US if country is not specified");
AddressDataLoader._loadScripts.reset();
// Load level 1 data that does not exist
let undefinedMetadata = FormAutofillUtils.getCountryAddressData("US", "CA");
// _loadScripts should be called
sinon.assert.called(AddressDataLoader._loadScripts);
Assert.equal(undefinedMetadata, undefined, "metadata should be undefined");
Assert.ok(AddressDataLoader._dataLoaded.level1.has("US"),
"level 1 state array should be set even there's no valid metadata");
AddressDataLoader._loadScripts.reset();
// Load level 1 data again
undefinedMetadata = FormAutofillUtils.getCountryAddressData("US", "AS");
Assert.equal(undefinedMetadata, undefined, "metadata should be undefined");
// _loadScripts should not be called
sinon.assert.notCalled(AddressDataLoader._loadScripts);
});

Просмотреть файл

@ -19,6 +19,7 @@ support-files =
[heuristics/third_party/test_Staples.js]
[heuristics/third_party/test_Walmart.js]
[test_activeStatus.js]
[test_addressDataLoader.js]
[test_addressRecords.js]
[test_autofillFormFields.js]
[test_collectFormFields.js]

Просмотреть файл

@ -72,6 +72,7 @@
"forms.jsm": ["FormData"],
"FormAutofillHeuristics.jsm": ["FormAutofillHeuristics", "LabelUtils"],
"FormAutofillSync.jsm": ["AddressesEngine", "CreditCardsEngine"],
"FormAutofillUtils.jsm": ["FormAutofillUtils", "AddressDataLoader"],
"FrameScriptManager.jsm": ["getNewLoaderID"],
"fxa_utils.js": ["initializeIdentityWithTokenServerResponse"],
"fxaccounts.jsm": ["Authentication"],