mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
Bug 883923 - Provide a Fuzzy Matcher API for phone numbers. r=fabrice
This commit is contained in:
parent
532b81527e
commit
2258001442
@ -348,6 +348,8 @@
|
||||
@BINPATH@/components/BrowserElementParent.js
|
||||
@BINPATH@/components/ContactManager.js
|
||||
@BINPATH@/components/ContactManager.manifest
|
||||
@BINPATH@/components/PhoneNumberService.js
|
||||
@BINPATH@/components/PhoneNumberService.manifest
|
||||
@BINPATH@/components/PermissionSettings.js
|
||||
@BINPATH@/components/PermissionSettings.manifest
|
||||
@BINPATH@/components/PermissionPromptService.js
|
||||
|
@ -520,6 +520,8 @@
|
||||
@BINPATH@/components/PermissionSettings.manifest
|
||||
@BINPATH@/components/ContactManager.js
|
||||
@BINPATH@/components/ContactManager.manifest
|
||||
@BINPATH@/components/PhoneNumberService.js
|
||||
@BINPATH@/components/PhoneNumberService.manifest
|
||||
@BINPATH@/components/AlarmsManager.js
|
||||
@BINPATH@/components/AlarmsManager.manifest
|
||||
@BINPATH@/components/Push.js
|
||||
|
@ -145,6 +145,11 @@ this.PermissionsTable = { geolocation: {
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
phonenumberservice: {
|
||||
app: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
fmradio: {
|
||||
app: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
|
@ -1602,6 +1602,14 @@ Navigator::HasPowerSupport(JSContext* /* unused */, JSObject* aGlobal)
|
||||
return win && PowerManager::CheckPermission(win);
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool
|
||||
Navigator::HasPhoneNumberSupport(JSContext* /* unused */, JSObject* aGlobal)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win = GetWindowFromGlobal(aGlobal);
|
||||
return CheckPermission(win, "phonenumberservice");
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool
|
||||
Navigator::HasIdleSupport(JSContext* /* unused */, JSObject* aGlobal)
|
||||
|
@ -256,6 +256,7 @@ public:
|
||||
// WebIDL helper methods
|
||||
static bool HasBatterySupport(JSContext* /* unused*/, JSObject* /*unused */);
|
||||
static bool HasPowerSupport(JSContext* /* unused */, JSObject* aGlobal);
|
||||
static bool HasPhoneNumberSupport(JSContext* /* unused */, JSObject* aGlobal);
|
||||
static bool HasIdleSupport(JSContext* /* unused */, JSObject* aGlobal);
|
||||
static bool HasWakeLockSupport(JSContext* /* unused*/, JSObject* /*unused */);
|
||||
static bool HasDesktopNotificationSupport(JSContext* /* unused*/,
|
||||
|
@ -9,19 +9,18 @@
|
||||
this.EXPORTED_SYMBOLS = ["PhoneNumber"];
|
||||
|
||||
Components.utils.import("resource://gre/modules/PhoneNumberMetaData.jsm");
|
||||
Components.utils.import("resource://gre/modules/PhoneNumberNormalizer.jsm");
|
||||
|
||||
this.PhoneNumber = (function (dataBase) {
|
||||
// Use strict in our context only - users might not want it
|
||||
'use strict';
|
||||
|
||||
const MAX_PHONE_NUMBER_LENGTH = 50;
|
||||
const UNICODE_DIGITS = /[\uFF10-\uFF19\u0660-\u0669\u06F0-\u06F9]/g;
|
||||
const NON_ALPHA_CHARS = /[^a-zA-Z]/g;
|
||||
const NON_DIALABLE_CHARS = /[^,#+\*\d]/g;
|
||||
const NON_DIALABLE_CHARS_ONCE = new RegExp(NON_DIALABLE_CHARS.source);
|
||||
const BACKSLASH = /\\/g;
|
||||
const SPLIT_FIRST_GROUP = /^(\d+)(.*)$/;
|
||||
const VALID_ALPHA_PATTERN = /[a-zA-Z]/g;
|
||||
const LEADING_PLUS_CHARS_PATTERN = /^[+\uFF0B]+/g;
|
||||
|
||||
// Format of the string encoded meta data. If the name contains "^" or "$"
|
||||
@ -225,40 +224,6 @@ this.PhoneNumber = (function (dataBase) {
|
||||
}
|
||||
};
|
||||
|
||||
// Map letters to numbers according to the ITU E.161 standard
|
||||
var E161 = {
|
||||
'a': 2, 'b': 2, 'c': 2,
|
||||
'd': 3, 'e': 3, 'f': 3,
|
||||
'g': 4, 'h': 4, 'i': 4,
|
||||
'j': 5, 'k': 5, 'l': 5,
|
||||
'm': 6, 'n': 6, 'o': 6,
|
||||
'p': 7, 'q': 7, 'r': 7, 's': 7,
|
||||
't': 8, 'u': 8, 'v': 8,
|
||||
'w': 9, 'x': 9, 'y': 9, 'z': 9
|
||||
};
|
||||
|
||||
// Normalize a number by converting unicode numbers and symbols to their
|
||||
// ASCII equivalents and removing all non-dialable characters.
|
||||
function NormalizeNumber(number, numbersOnly) {
|
||||
if (typeof number !== 'string') {
|
||||
return '';
|
||||
}
|
||||
|
||||
number = number.replace(UNICODE_DIGITS,
|
||||
function (ch) {
|
||||
return String.fromCharCode(48 + (ch.charCodeAt(0) & 0xf));
|
||||
});
|
||||
if (!numbersOnly) {
|
||||
number = number.replace(VALID_ALPHA_PATTERN,
|
||||
function (ch) {
|
||||
return String(E161[ch.toLowerCase()] || 0);
|
||||
});
|
||||
}
|
||||
number = number.replace(LEADING_PLUS_CHARS_PATTERN, "+");
|
||||
number = number.replace(NON_DIALABLE_CHARS, "");
|
||||
return number;
|
||||
}
|
||||
|
||||
// Check whether the number is valid for the given region.
|
||||
function IsValidNumber(number, md) {
|
||||
return md.possiblePattern.test(number);
|
||||
@ -329,7 +294,7 @@ this.PhoneNumber = (function (dataBase) {
|
||||
var ret;
|
||||
|
||||
// Remove formating characters and whitespace.
|
||||
number = NormalizeNumber(number);
|
||||
number = PhoneNumberNormalizer.Normalize(number);
|
||||
|
||||
// If there is no defaultRegion, we can't parse international access codes.
|
||||
if (!defaultRegion && number[0] !== '+')
|
||||
@ -404,6 +369,5 @@ this.PhoneNumber = (function (dataBase) {
|
||||
return {
|
||||
IsPlain: IsPlainPhoneNumber,
|
||||
Parse: ParseNumber,
|
||||
Normalize: NormalizeNumber
|
||||
};
|
||||
})(PHONE_NUMBER_META_DATA);
|
||||
|
55
dom/phonenumberutils/PhoneNumberNormalizer.jsm
Normal file
55
dom/phonenumberutils/PhoneNumberNormalizer.jsm
Normal file
@ -0,0 +1,55 @@
|
||||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
|
||||
// Don't modify this code. Please use:
|
||||
// https://github.com/andreasgal/PhoneNumber.js
|
||||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["PhoneNumberNormalizer"];
|
||||
|
||||
this.PhoneNumberNormalizer = (function() {
|
||||
const UNICODE_DIGITS = /[\uFF10-\uFF19\u0660-\u0669\u06F0-\u06F9]/g;
|
||||
const VALID_ALPHA_PATTERN = /[a-zA-Z]/g;
|
||||
const LEADING_PLUS_CHARS_PATTERN = /^[+\uFF0B]+/g;
|
||||
const NON_DIALABLE_CHARS = /[^,#+\*\d]/g;
|
||||
|
||||
// Map letters to numbers according to the ITU E.161 standard
|
||||
var E161 = {
|
||||
'a': 2, 'b': 2, 'c': 2,
|
||||
'd': 3, 'e': 3, 'f': 3,
|
||||
'g': 4, 'h': 4, 'i': 4,
|
||||
'j': 5, 'k': 5, 'l': 5,
|
||||
'm': 6, 'n': 6, 'o': 6,
|
||||
'p': 7, 'q': 7, 'r': 7, 's': 7,
|
||||
't': 8, 'u': 8, 'v': 8,
|
||||
'w': 9, 'x': 9, 'y': 9, 'z': 9
|
||||
};
|
||||
|
||||
// Normalize a number by converting unicode numbers and symbols to their
|
||||
// ASCII equivalents and removing all non-dialable characters.
|
||||
function NormalizeNumber(number, numbersOnly) {
|
||||
if (typeof number !== 'string') {
|
||||
return '';
|
||||
}
|
||||
|
||||
number = number.replace(UNICODE_DIGITS,
|
||||
function (ch) {
|
||||
return String.fromCharCode(48 + (ch.charCodeAt(0) & 0xf));
|
||||
});
|
||||
if (!numbersOnly) {
|
||||
number = number.replace(VALID_ALPHA_PATTERN,
|
||||
function (ch) {
|
||||
return String(E161[ch.toLowerCase()] || 0);
|
||||
});
|
||||
}
|
||||
number = number.replace(LEADING_PLUS_CHARS_PATTERN, "+");
|
||||
number = number.replace(NON_DIALABLE_CHARS, "");
|
||||
return number;
|
||||
};
|
||||
|
||||
|
||||
return {
|
||||
Normalize: NormalizeNumber
|
||||
};
|
||||
})();
|
97
dom/phonenumberutils/PhoneNumberService.js
Normal file
97
dom/phonenumberutils/PhoneNumberService.js
Normal file
@ -0,0 +1,97 @@
|
||||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const DEBUG = false;
|
||||
function debug(s) { dump("-*- PhoneNumberService.js: " + s + "\n"); }
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
|
||||
Cu.import("resource://gre/modules/PhoneNumberUtils.jsm");
|
||||
Cu.import("resource://gre/modules/PhoneNumberNormalizer.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
||||
"@mozilla.org/childprocessmessagemanager;1",
|
||||
"nsIMessageSender");
|
||||
|
||||
// PhoneNumberService
|
||||
|
||||
function PhoneNumberService()
|
||||
{
|
||||
if (DEBUG) debug("Constructor");
|
||||
}
|
||||
|
||||
PhoneNumberService.prototype = {
|
||||
__proto__: DOMRequestIpcHelper.prototype,
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
if (DEBUG) debug("receiveMessage: " + aMessage.name);
|
||||
let msg = aMessage.json;
|
||||
|
||||
let req = this.getRequest(msg.requestID);
|
||||
if (!req) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (aMessage.name) {
|
||||
case "PhoneNumberService:FuzzyMatch:Return:KO":
|
||||
Services.DOMRequest.fireError(req.request, msg.errorMsg);
|
||||
break;
|
||||
case "PhoneNumberService:FuzzyMatch:Return:OK":
|
||||
Services.DOMRequest.fireSuccess(req.request, msg.result);
|
||||
break;
|
||||
default:
|
||||
if (DEBUG) debug("Wrong message: " + aMessage.name);
|
||||
}
|
||||
this.removeRequest(msg.requestID);
|
||||
},
|
||||
|
||||
fuzzyMatch: function(aNumber1, aNumber2) {
|
||||
if (DEBUG) debug("fuzzyMatch: " + aNumber1 + ", " + aNumber2);
|
||||
let request = this.createRequest();
|
||||
|
||||
if ((aNumber1 && !aNumber2) || (aNumber2 && !aNumber1)) {
|
||||
// if only one of the numbers is empty/null/undefined and the other
|
||||
// number is not, we can fire false result in next tick
|
||||
Services.DOMRequest.fireSuccessAsync(request, false);
|
||||
} else if ((aNumber1 === aNumber2) ||
|
||||
(PhoneNumberNormalizer.Normalize(aNumber1) === PhoneNumberNormalizer.Normalize(aNumber2))) {
|
||||
// if we have a simple match fire successful request in next tick
|
||||
Services.DOMRequest.fireSuccessAsync(request, true);
|
||||
} else {
|
||||
// invoke fuzzy matching in the parent
|
||||
let options = { number1: aNumber1, number2: aNumber2 };
|
||||
cpmm.sendAsyncMessage("PhoneNumberService:FuzzyMatch",
|
||||
{requestID: this.getRequestId({request: request}),
|
||||
options: options});
|
||||
}
|
||||
|
||||
return request;
|
||||
},
|
||||
|
||||
normalize: function(aNumber) {
|
||||
if (DEBUG) debug("normalize: " + aNumber);
|
||||
return PhoneNumberNormalizer.Normalize(aNumber);
|
||||
},
|
||||
|
||||
init: function(aWindow) {
|
||||
if (DEBUG) debug("init call");
|
||||
this.initDOMRequestHelper(aWindow, [
|
||||
"PhoneNumberService:FuzzyMatch:Return:OK",
|
||||
"PhoneNumberService:FuzzyMatch:Return:KO"
|
||||
]);
|
||||
},
|
||||
|
||||
classID : Components.ID("{e2768710-eb17-11e2-91e2-0800200c9a66}"),
|
||||
contractID : "@mozilla.org/phoneNumberService;1",
|
||||
QueryInterface : XPCOMUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer]),
|
||||
}
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PhoneNumberService]);
|
2
dom/phonenumberutils/PhoneNumberService.manifest
Normal file
2
dom/phonenumberutils/PhoneNumberService.manifest
Normal file
@ -0,0 +1,2 @@
|
||||
component {e2768710-eb17-11e2-91e2-0800200c9a66} PhoneNumberService.js
|
||||
contract @mozilla.org/phoneNumberService;1 {e2768710-eb17-11e2-91e2-0800200c9a66}
|
@ -9,10 +9,12 @@ const DEBUG = false;
|
||||
function debug(s) { if(DEBUG) dump("-*- PhoneNumberutils: " + s + "\n"); }
|
||||
|
||||
const Cu = Components.utils;
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Cu.import("resource://gre/modules/PhoneNumber.jsm");
|
||||
Cu.import("resource://gre/modules/PhoneNumberNormalizer.jsm");
|
||||
Cu.import("resource://gre/modules/mcc_iso3166_table.jsm");
|
||||
|
||||
#ifdef MOZ_B2G_RIL
|
||||
@ -22,6 +24,9 @@ XPCOMUtils.defineLazyServiceGetter(this, "mobileConnection",
|
||||
#endif
|
||||
|
||||
this.PhoneNumberUtils = {
|
||||
init: function() {
|
||||
ppmm.addMessageListener(["PhoneNumberService:FuzzyMatch"], this);
|
||||
},
|
||||
// 1. See whether we have a network mcc
|
||||
// 2. If we don't have that, look for the simcard mcc
|
||||
// 3. If we don't have that or its 0 (not activated), pick up the last used mcc
|
||||
@ -96,8 +101,62 @@ this.PhoneNumberUtils = {
|
||||
},
|
||||
|
||||
normalize: function Normalize(aNumber, aNumbersOnly) {
|
||||
var normalized = PhoneNumber.Normalize(aNumber, aNumbersOnly);
|
||||
let normalized = PhoneNumberNormalizer.Normalize(aNumber, aNumbersOnly);
|
||||
if (DEBUG) debug("normalize(" + aNumber + "): " + normalized + ", " + aNumbersOnly);
|
||||
return normalized;
|
||||
},
|
||||
|
||||
fuzzyMatch: function fuzzyMatch(aNumber1, aNumber2) {
|
||||
let normalized1 = this.normalize(aNumber1);
|
||||
let normalized2 = this.normalize(aNumber2);
|
||||
if (DEBUG) debug("Normalized Number1: " + normalized1 + ", Number2: " + normalized2);
|
||||
if (normalized1 === normalized2) {
|
||||
return true;
|
||||
}
|
||||
let parsed1 = this.parse(aNumber1);
|
||||
let parsed2 = this.parse(aNumber2);
|
||||
if (parsed1 && parsed2) {
|
||||
if (parsed1.internationalNumber === parsed2.internationalNumber
|
||||
|| parsed1.nationalNumber === parsed2.nationalNumber) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
let countryName = this.getCountryName();
|
||||
let ssPref = "dom.phonenumber.substringmatching." + countryName;
|
||||
if (Services.prefs.getPrefType(ssPref) == Ci.nsIPrefBranch.PREF_INT) {
|
||||
let val = Services.prefs.getIntPref(ssPref);
|
||||
if (normalized1.slice(-val) === normalized2.slice(-val)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
if (DEBUG) debug("receiveMessage " + aMessage.name);
|
||||
let mm = aMessage.target;
|
||||
let msg = aMessage.data;
|
||||
|
||||
switch (aMessage.name) {
|
||||
case "PhoneNumberService:FuzzyMatch":
|
||||
mm.sendAsyncMessage("PhoneNumberService:FuzzyMatch:Return:OK", {
|
||||
requestID: msg.requestID,
|
||||
result: this.fuzzyMatch(msg.options.number1, msg.options.number2)
|
||||
});
|
||||
break;
|
||||
default:
|
||||
if (DEBUG) debug("WRONG MESSAGE NAME: " + aMessage.name);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let inParent = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime)
|
||||
.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
|
||||
if (inParent) {
|
||||
Cu.import("resource://gre/modules/PhoneNumber.jsm");
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
|
||||
"@mozilla.org/parentprocessmessagemanager;1",
|
||||
"nsIMessageListenerManager");
|
||||
PhoneNumberUtils.init();
|
||||
}
|
||||
|
||||
|
@ -6,13 +6,18 @@
|
||||
|
||||
TEST_DIRS += ['tests']
|
||||
|
||||
EXTRA_COMPONENTS += [
|
||||
'PhoneNumberService.js',
|
||||
'PhoneNumberService.manifest',
|
||||
]
|
||||
|
||||
EXTRA_JS_MODULES += [
|
||||
'PhoneNumber.jsm',
|
||||
'PhoneNumberMetaData.jsm',
|
||||
'PhoneNumberNormalizer.jsm',
|
||||
'mcc_iso3166_table.jsm',
|
||||
]
|
||||
|
||||
EXTRA_PP_JS_MODULES += [
|
||||
'PhoneNumberUtils.jsm',
|
||||
]
|
||||
|
||||
|
@ -11,9 +11,14 @@ relativesrcdir = @relativesrcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MOCHITEST_FILES = \
|
||||
test_phonenumberutils_basics.html \
|
||||
$(NULL)
|
||||
|
||||
MOCHITEST_CHROME_FILES = \
|
||||
test_phonenumber.xul \
|
||||
test_phonenumberutils.xul \
|
||||
test_phonenumberservice.xul \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
@ -21,6 +21,7 @@
|
||||
"use strict";
|
||||
|
||||
Components.utils.import("resource://gre/modules/PhoneNumber.jsm");
|
||||
Components.utils.import("resource://gre/modules/PhoneNumberNormalizer.jsm");
|
||||
|
||||
function IsPlain(dial, expected) {
|
||||
var result = PhoneNumber.IsPlain(dial);
|
||||
@ -32,7 +33,7 @@ function IsPlain(dial, expected) {
|
||||
}
|
||||
|
||||
function Normalize(dial, expected) {
|
||||
var result = PhoneNumber.Normalize(dial);
|
||||
var result = PhoneNumberNormalizer.Normalize(dial);
|
||||
if (result !== expected) {
|
||||
ok(false, "normalized " + dial + " to " + result + ", expected " + expected + " instead.");
|
||||
} else {
|
||||
@ -41,7 +42,7 @@ function Normalize(dial, expected) {
|
||||
}
|
||||
|
||||
function Normalize(dial, expected) {
|
||||
var result = PhoneNumber.Normalize(dial);
|
||||
var result = PhoneNumberNormalizer.Normalize(dial);
|
||||
if (result != expected) {
|
||||
ok(false, "Normalize error!\n");
|
||||
print("expected: " + expected);
|
||||
|
158
dom/phonenumberutils/tests/test_phonenumberservice.xul
Normal file
158
dom/phonenumberutils/tests/test_phonenumberservice.xul
Normal file
@ -0,0 +1,158 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
- http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
|
||||
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Mozilla Bug 781379">
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=809213"
|
||||
target="_blank">Mozilla Bug 809213</a>
|
||||
</body>
|
||||
|
||||
<script type="application/javascript;version=1.8">
|
||||
|
||||
"use strict";
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
Services.prefs.setIntPref("dom.phonenumber.substringmatching.BR", 8);
|
||||
Services.prefs.setCharPref("ril.lastKnownSimMcc", "310");
|
||||
|
||||
var pm = SpecialPowers.Cc["@mozilla.org/permissionmanager;1"]
|
||||
.getService(SpecialPowers.Ci.nsIPermissionManager);
|
||||
|
||||
pm.addFromPrincipal(window.document.nodePrincipal, "phonenumberservice",
|
||||
SpecialPowers.Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
|
||||
function onUnwantedSuccess() {
|
||||
ok(false, "onUnwantedSuccess: shouldn't get here");
|
||||
}
|
||||
|
||||
function onFailure() {
|
||||
ok(false, "in on Failure!");
|
||||
}
|
||||
|
||||
var req;
|
||||
var index = 0;
|
||||
var mozPhoneNumberService = window.navigator.mozPhoneNumberService;
|
||||
ok(mozPhoneNumberService, "mozPhoneNumberService exists");
|
||||
var steps = [
|
||||
function() {
|
||||
req = mozPhoneNumberService.fuzzyMatch("123", "123");
|
||||
req.onsuccess = function(e) {
|
||||
is(req.result, true, "same number");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
req = mozPhoneNumberService.fuzzyMatch("abcdef", "222333");
|
||||
req.onsuccess = function(e) {
|
||||
is(req.result, true, "normalize first number");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
req = mozPhoneNumberService.fuzzyMatch("abc333", "222def");
|
||||
req.onsuccess = function(e) {
|
||||
is(req.result, true, "normalize first and second number");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
req = mozPhoneNumberService.fuzzyMatch("1234567", "1234568");
|
||||
req.onsuccess = function(e) {
|
||||
is(req.result, false, "different numbers should not match");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
req = mozPhoneNumberService.fuzzyMatch("1234567", "123456");
|
||||
req.onsuccess = function(e) {
|
||||
is(req.result, false, "different length numbers should not match");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
req = mozPhoneNumberService.fuzzyMatch("1234567", "123456---");
|
||||
req.onsuccess = function(e) {
|
||||
is(req.result, false, "invalid number should not match valid number");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
req = mozPhoneNumberService.fuzzyMatch("111", undefined);
|
||||
req.onsuccess = function(e) {
|
||||
is(req.result, false, "missing second argument should not match");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
req = mozPhoneNumberService.fuzzyMatch(undefined, "111");
|
||||
req.onsuccess = function(e) {
|
||||
is(req.result, false, "missing first argument should not match");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
req = mozPhoneNumberService.fuzzyMatch(null, "");
|
||||
req.onsuccess = function(e) {
|
||||
is(req.result, true, "missing first argument should fuzzy match empty string");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
req = mozPhoneNumberService.fuzzyMatch("+552155555555", "2155555555");
|
||||
req.onsuccess = function(e) {
|
||||
is(req.result, true, "test internationalization of number");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
req = mozPhoneNumberService.fuzzyMatch("aaa123456789", "zzzzz123456789");
|
||||
req.onsuccess = function(e) {
|
||||
is(req.result, true, "substring matching should be in effect");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "all done!\n");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
];
|
||||
|
||||
function next() {
|
||||
ok(true, "Begin!");
|
||||
if (index >= steps.length) {
|
||||
ok(false, "Shouldn't get here!");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
var i = index++;
|
||||
steps[i]();
|
||||
} catch(ex) {
|
||||
ok(false, "Caught exception", ex);
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(next);
|
||||
</script>
|
||||
</window>
|
@ -20,8 +20,12 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
Components.utils.import("resource://gre/modules/PhoneNumberUtils.jsm");
|
||||
|
||||
Services.prefs.setIntPref("dom.phonenumber.substringmatching.BR", 8);
|
||||
Services.prefs.setCharPref("ril.lastKnownSimMcc", "310");
|
||||
|
||||
function CantParseWithMcc(dial, mcc) {
|
||||
var result = PhoneNumberUtils.parseWithMCC(dial, mcc);
|
||||
if (result) {
|
||||
@ -43,6 +47,11 @@ function ParseWithMcc(dial, mcc) {
|
||||
}
|
||||
}
|
||||
|
||||
function FuzzyMatch(number1, number2, expect) {
|
||||
var result = PhoneNumberUtils.fuzzyMatch(number1, number2);
|
||||
is(result, expect, "FuzzyMatch OK!");
|
||||
}
|
||||
|
||||
// Unknown mcc
|
||||
CantParseWithMcc("1234", 123);
|
||||
ParseWithMcc("4165555555", 302);
|
||||
@ -50,5 +59,10 @@ ParseWithMcc("4165555555", 302);
|
||||
is(PhoneNumberUtils.normalize("123abc", true), "123", "NumbersOnly");
|
||||
is(PhoneNumberUtils.normalize("123abc", false), "123222", "NumbersOnly");
|
||||
|
||||
FuzzyMatch("123abc", "123222", true);
|
||||
FuzzyMatch("123456789", "123456789", true);
|
||||
FuzzyMatch("111", null, false);
|
||||
FuzzyMatch("+552155555555", "2155555555", true);
|
||||
FuzzyMatch("aaa123456789", "zzzzz123456789", true);
|
||||
</script>
|
||||
</window>
|
||||
|
32
dom/phonenumberutils/tests/test_phonenumberutils_basics.html
Normal file
32
dom/phonenumberutils/tests/test_phonenumberutils_basics.html
Normal file
@ -0,0 +1,32 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=674720
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 883923 PhoneNumberUtils FuzzyMatch</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=883923">Mozilla Bug 883923</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
"use strict";
|
||||
|
||||
var mozPhoneNumberService = window.navigator.mozPhoneNumberService;
|
||||
if (mozPhoneNumberService) {
|
||||
is(mozPhoneNumberService.fuzzyMatch, undefined, "Fuzzy Match should not be accesible");
|
||||
is(mozPhoneNumberService.normalize, undefined, "Normalize should not be accessible");
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
15
dom/webidl/PhoneNumberService.webidl
Normal file
15
dom/webidl/PhoneNumberService.webidl
Normal file
@ -0,0 +1,15 @@
|
||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/.
|
||||
*/
|
||||
|
||||
[JSImplementation="@mozilla.org/phoneNumberService;1", NavigatorProperty="mozPhoneNumberService"]
|
||||
interface PhoneNumberService {
|
||||
|
||||
[Func="Navigator::HasPhoneNumberSupport"]
|
||||
DOMRequest fuzzyMatch([TreatNullAs=EmptyString, TreatUndefinedAs=EmptyString] DOMString number1, [TreatNullAs=EmptyString, TreatUndefinedAs=EmptyString] DOMString number2);
|
||||
|
||||
[Func="Navigator::HasPhoneNumberSupport"]
|
||||
DOMString normalize(DOMString number);
|
||||
};
|
@ -224,6 +224,7 @@ webidl_files = \
|
||||
PerformanceNavigation.webidl \
|
||||
PerformanceTiming.webidl \
|
||||
PeriodicWave.webidl \
|
||||
PhoneNumberService.webidl \
|
||||
Plugin.webidl \
|
||||
PluginArray.webidl \
|
||||
Position.webidl \
|
||||
|
@ -283,6 +283,8 @@
|
||||
@BINPATH@/components/ConsoleAPI.js
|
||||
@BINPATH@/components/ContactManager.js
|
||||
@BINPATH@/components/ContactManager.manifest
|
||||
@BINPATH@/components/PhoneNumberService.js
|
||||
@BINPATH@/components/PhoneNumberService.manifest
|
||||
@BINPATH@/components/SettingsManager.js
|
||||
@BINPATH@/components/SettingsManager.manifest
|
||||
@BINPATH@/components/SettingsService.js
|
||||
|
Loading…
Reference in New Issue
Block a user