зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1820522 - Implement heuristics to determine whether two telephone numbers are the same, different, or mergeable r=mtigley
Differential Revision: https://phabricator.services.mozilla.com/D173802
This commit is contained in:
Родитель
159fb3427a
Коммит
2f30c1322c
|
@ -0,0 +1,76 @@
|
||||||
|
/* import-globals-from head_addressComponent.js */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// prettier-ignore
|
||||||
|
const VALID_TESTS = [
|
||||||
|
// US Valid format (XXX-XXX-XXXX) and first digit is between 2-9
|
||||||
|
["200-234-5678", true], // First digit should between 2-9
|
||||||
|
["100-234-5678", true], // First digit is not between 2-9, but currently not being checked
|
||||||
|
// when no country code is specified
|
||||||
|
["555-abc-1234", true], // Non-digit characters are normalized according to ITU E.161 standard
|
||||||
|
["55-555-5555", false], // The national number is too short (9 digits)
|
||||||
|
|
||||||
|
["2-800-555-1234", false], // "2" is not US country code so we treat
|
||||||
|
// 2-800-555-1234 as the national number, which is too long (11 digits)
|
||||||
|
|
||||||
|
// Phone numbers with country code
|
||||||
|
["1-800-555-1234", true], // Country code without plus sign
|
||||||
|
["+1 200-234-5678", true], // Country code with plus sign and with a valid national number
|
||||||
|
["+1 100-234-5678", false], // National number should be between 2-9
|
||||||
|
["+1 55-555-5555", false], // National number is too short (9 digits)
|
||||||
|
["+1 1-800-555-1234", true], // "+1" and "1" are both treated as coutnry code so national number
|
||||||
|
// is a valid number (800-555-1234)
|
||||||
|
["+1 2-800-555-1234", false], // The national number is too long (11 digits)
|
||||||
|
["+1 555-abc-1234", true], // Non-digit characters are normalized according to ITU E.161 standard
|
||||||
|
];
|
||||||
|
|
||||||
|
const COMPARE_TESTS = [
|
||||||
|
["+1 520-248-6621", "+15202486621", SAME],
|
||||||
|
["+1 520-248-6621", "1-520-248-6621", SAME],
|
||||||
|
["+1 520-248-6621", "1(520)248-6621", SAME],
|
||||||
|
["520-248-6621", "520-248-6621", SAME], // Both phone numbers don't have coutry code
|
||||||
|
["520-248-6621", "+1 520-248-6621", SAME], // Compare phone number with and without country code
|
||||||
|
|
||||||
|
["+1 520-248-6621", "248-6621", A_CONTAINS_B],
|
||||||
|
["520-248-6621", "248-6621", A_CONTAINS_B],
|
||||||
|
["0520-248-6621", "520-248-6621", A_CONTAINS_B],
|
||||||
|
["48-6621", "6621", A_CONTAINS_B], // Both phone number are invalid
|
||||||
|
|
||||||
|
["+1 520-248-6621", "+91 520-248-6622", DIFFERENT], // different national prefix and number
|
||||||
|
["+1 520-248-6621", "+91 520-248-6621", DIFFERENT], // Same number, different national prefix
|
||||||
|
["+1 520-248-6621", "+1 520-248-6622", DIFFERENT], // Same national prefix, different number
|
||||||
|
["520-248-6621", "+91 520-248-6622", DIFFERENT], // Same test as above but with default region
|
||||||
|
["520-248-6621", "+91 520-248-6621", DIFFERENT], // Same test as above but with default region
|
||||||
|
["520-248-6621", "+1 520-248-6622", DIFFERENT], // Same test as above but with default region
|
||||||
|
["520-248-6621", "520-248-6622", DIFFERENT],
|
||||||
|
|
||||||
|
// Normalize
|
||||||
|
["+1 520-248-6621", "+1 ja0-bgt-mnc1", SAME],
|
||||||
|
["+1 1-800-555-1234", "+1 800-555-1234", SAME],
|
||||||
|
|
||||||
|
// TODO: Support extension
|
||||||
|
//["+64 3 331-6005", "3 331 6005#1234", A_CONTAINS_B],
|
||||||
|
];
|
||||||
|
|
||||||
|
const TEST_FIELD_NAME = "Tel";
|
||||||
|
|
||||||
|
add_setup(async () => {
|
||||||
|
Services.prefs.setBoolPref("browser.search.region", "US");
|
||||||
|
|
||||||
|
registerCleanupFunction(function head_cleanup() {
|
||||||
|
Services.prefs.clearUserPref("browser.search.region");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
add_task(async function test_isValid() {
|
||||||
|
runIsValidTest(VALID_TESTS, TEST_FIELD_NAME, value => {
|
||||||
|
return { tel: value };
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
add_task(async function test_compare() {
|
||||||
|
runCompareTest(COMPARE_TESTS, TEST_FIELD_NAME, value => {
|
||||||
|
return { tel: value };
|
||||||
|
});
|
||||||
|
});
|
|
@ -12,6 +12,8 @@ support-files =
|
||||||
head = head_addressComponent.js
|
head = head_addressComponent.js
|
||||||
[test_addressComponent_organization.js]
|
[test_addressComponent_organization.js]
|
||||||
head = head_addressComponent.js
|
head = head_addressComponent.js
|
||||||
|
[test_addressComponent_tel.js]
|
||||||
|
head = head_addressComponent.js
|
||||||
[test_addressDataLoader.js]
|
[test_addressDataLoader.js]
|
||||||
[test_addressRecords.js]
|
[test_addressRecords.js]
|
||||||
skip-if =
|
skip-if =
|
||||||
|
|
|
@ -7,9 +7,12 @@ import { FormAutofill } from "resource://autofill/FormAutofill.sys.mjs";
|
||||||
const lazy = {};
|
const lazy = {};
|
||||||
|
|
||||||
ChromeUtils.defineESModuleGetters(lazy, {
|
ChromeUtils.defineESModuleGetters(lazy, {
|
||||||
FormAutofillUtils: "resource://gre/modules/shared/FormAutofillUtils.sys.mjs",
|
|
||||||
FormAutofillNameUtils:
|
FormAutofillNameUtils:
|
||||||
"resource://gre/modules/shared/FormAutofillNameUtils.sys.mjs",
|
"resource://gre/modules/shared/FormAutofillNameUtils.sys.mjs",
|
||||||
|
FormAutofillUtils: "resource://gre/modules/shared/FormAutofillUtils.sys.mjs",
|
||||||
|
PhoneNumber: "resource://autofill/phonenumberutils/PhoneNumber.sys.mjs",
|
||||||
|
PhoneNumberNormalizer:
|
||||||
|
"resource://autofill/phonenumberutils/PhoneNumberNormalizer.sys.mjs",
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -255,7 +258,75 @@ class Name extends AddressField {}
|
||||||
* A full telephone number, including the country code.
|
* A full telephone number, including the country code.
|
||||||
* See autocomplete="tel"
|
* See autocomplete="tel"
|
||||||
*/
|
*/
|
||||||
class Tel extends AddressField {}
|
class Tel extends AddressField {
|
||||||
|
#valid = false;
|
||||||
|
|
||||||
|
// The country code part of a telphone number, such as "1" for the United States
|
||||||
|
#country_code = null;
|
||||||
|
|
||||||
|
// The national part of a telphone number. For example, the phone number "+1 520-248-6621"
|
||||||
|
// national part is "520-248-6621".
|
||||||
|
#national_number = null;
|
||||||
|
|
||||||
|
constructor(value, region) {
|
||||||
|
super(value, region);
|
||||||
|
|
||||||
|
if (!this.userValue) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Support parse telephone extension
|
||||||
|
// We compress all tel-related fields into a single tel field when an an form
|
||||||
|
// is submitted, so we need to decompress it here.
|
||||||
|
const parsed_tel = lazy.PhoneNumber.Parse(this.userValue, region);
|
||||||
|
if (parsed_tel) {
|
||||||
|
this.#national_number = parsed_tel?.nationalNumber;
|
||||||
|
this.#country_code = parsed_tel?.countryCode;
|
||||||
|
|
||||||
|
this.#valid = true;
|
||||||
|
} else {
|
||||||
|
this.#national_number = lazy.PhoneNumberNormalizer.Normalize(
|
||||||
|
this.userValue
|
||||||
|
);
|
||||||
|
|
||||||
|
const md = lazy.PhoneNumber.FindMetaDataForRegion(region);
|
||||||
|
this.#country_code = md ? "+" + md.nationalPrefix : null;
|
||||||
|
|
||||||
|
this.#valid = lazy.PhoneNumber.IsValid(this.#national_number, md);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get country_code() {
|
||||||
|
return this.#country_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
get national_number() {
|
||||||
|
return this.#national_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
isValid() {
|
||||||
|
return this.#valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
equals(other) {
|
||||||
|
return (
|
||||||
|
this.national_number == other.national_number &&
|
||||||
|
this.country_code == other.country_code
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
contains(other) {
|
||||||
|
if (!this.country_code || this.country_code != other.country_code) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.national_number.endsWith(other.national_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
toString() {
|
||||||
|
return `${this.constructor.name}: ${this.country_code} ${this.national_number}\n`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A company or organization name.
|
* A company or organization name.
|
||||||
|
|
|
@ -416,7 +416,6 @@ export var PhoneNumber = (function(dataBase) {
|
||||||
|
|
||||||
// Lookup the meta data for the given region.
|
// Lookup the meta data for the given region.
|
||||||
let md = FindMetaDataForRegion(defaultRegion.toUpperCase());
|
let md = FindMetaDataForRegion(defaultRegion.toUpperCase());
|
||||||
|
|
||||||
if (!md) {
|
if (!md) {
|
||||||
dump("Couldn't find Meta Data for region: " + defaultRegion + "\n");
|
dump("Couldn't find Meta Data for region: " + defaultRegion + "\n");
|
||||||
return null;
|
return null;
|
||||||
|
@ -468,6 +467,8 @@ export var PhoneNumber = (function(dataBase) {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
IsPlain: IsPlainPhoneNumber,
|
IsPlain: IsPlainPhoneNumber,
|
||||||
|
IsValid: IsValidNumber,
|
||||||
Parse: ParseNumber,
|
Parse: ParseNumber,
|
||||||
|
FindMetaDataForRegion,
|
||||||
};
|
};
|
||||||
})(PHONE_NUMBER_META_DATA);
|
})(PHONE_NUMBER_META_DATA);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче