зеркало из https://github.com/mozilla/gecko-dev.git
Bug 877302 - [Dialer] when searching for a number in contacts, display partial matches (matching the end of the number). r=bent, reuben
This commit is contained in:
Родитель
2028ac5d64
Коммит
abfdc384e8
|
@ -377,16 +377,22 @@ pref("dom.ipc.processCount", 100000);
|
|||
|
||||
pref("dom.ipc.browser_frames.oop_by_default", false);
|
||||
|
||||
// Temporary permission hack for WebSMS
|
||||
// WebSMS
|
||||
pref("dom.sms.enabled", true);
|
||||
pref("dom.sms.strict7BitEncoding", false); // Disabled by default.
|
||||
pref("dom.sms.requestStatusReport", true); // Enabled by default.
|
||||
|
||||
// Temporary permission hack for WebContacts
|
||||
// WebContacts
|
||||
pref("dom.mozContacts.enabled", true);
|
||||
pref("dom.navigator-property.disable.mozContacts", false);
|
||||
pref("dom.global-constructor.disable.mozContact", false);
|
||||
|
||||
// Shortnumber matching needed for e.g. Brazil:
|
||||
// 01187654321 can be found with 87654321
|
||||
pref("dom.phonenumber.substringmatching.BR", 8);
|
||||
pref("dom.phonenumber.substringmatching.CO", 10);
|
||||
pref("dom.phonenumber.substringmatching.VE", 7);
|
||||
|
||||
// WebAlarms
|
||||
pref("dom.mozAlarms.enabled", true);
|
||||
|
||||
|
|
|
@ -482,7 +482,11 @@ ContactDB.prototype = {
|
|||
matchSearch[parsedNumber.nationalNumber] = 1;
|
||||
matchSearch[parsedNumber.internationalNumber] = 1;
|
||||
matchSearch[PhoneNumberUtils.normalize(parsedNumber.nationalFormat)] = 1;
|
||||
matchSearch[PhoneNumberUtils.normalize(parsedNumber.internationalFormat)] = 1
|
||||
matchSearch[PhoneNumberUtils.normalize(parsedNumber.internationalFormat)] = 1;
|
||||
|
||||
if (this.substringMatching && normalized.length > this.substringMatching) {
|
||||
matchSearch[normalized.slice(-this.substringMatching)] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// containsSearch holds incremental search values for:
|
||||
|
@ -877,6 +881,11 @@ ContactDB.prototype = {
|
|||
let index = store.index("telMatch");
|
||||
let normalized = PhoneNumberUtils.normalize(options.filterValue,
|
||||
/*numbersOnly*/ true);
|
||||
|
||||
// Some countries need special handling for number matching. Bug 877302
|
||||
if (this.substringMatching && normalized.length > this.substringMatching) {
|
||||
normalized = normalized.slice(-this.substringMatching);
|
||||
}
|
||||
request = index.mozGetAll(normalized, limit);
|
||||
} else {
|
||||
// XXX: "contains" should be handled separately, this is "startsWith"
|
||||
|
@ -931,7 +940,12 @@ ContactDB.prototype = {
|
|||
}.bind(this);
|
||||
},
|
||||
|
||||
// Enable special phone number substring matching. Does not update existing DB entries.
|
||||
enableSubstringMatching: function enableSubstringMatching(aDigits) {
|
||||
this.substringMatching = aDigits;
|
||||
},
|
||||
|
||||
init: function init(aGlobal) {
|
||||
this.initDBHelper(DB_NAME, DB_VERSION, [STORE_NAME, SAVED_GETALL_STORE_NAME, REVISION_STORE], aGlobal);
|
||||
this.initDBHelper(DB_NAME, DB_VERSION, [STORE_NAME, SAVED_GETALL_STORE_NAME, REVISION_STORE], aGlobal);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -16,6 +16,7 @@ this.EXPORTED_SYMBOLS = [];
|
|||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/ContactDB.jsm");
|
||||
Cu.import("resource://gre/modules/PhoneNumberUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
|
||||
"@mozilla.org/parentprocessmessagemanager;1",
|
||||
|
@ -42,22 +43,44 @@ let ContactService = {
|
|||
this._db = new ContactDB(myGlobal);
|
||||
this._db.init(myGlobal);
|
||||
|
||||
let countryName = PhoneNumberUtils.getCountryName();
|
||||
if (Services.prefs.getPrefType("dom.phonenumber.substringmatching." + countryName) == Ci.nsIPrefBranch.PREF_INT) {
|
||||
if (DEBUG) debug("Enable Substring Matching for Phone Numbers: " + countryName);
|
||||
let val = Services.prefs.getIntPref("dom.phonenumber.substringmatching." + countryName);
|
||||
if (val && val > 0) {
|
||||
this._db.enableSubstringMatching(val);
|
||||
}
|
||||
}
|
||||
|
||||
Services.obs.addObserver(this, "profile-before-change", false);
|
||||
Services.prefs.addObserver("dom.phonenumber.substringmatching", this, false);
|
||||
},
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
myGlobal = null;
|
||||
this._messages.forEach(function(msgName) {
|
||||
ppmm.removeMessageListener(msgName, this);
|
||||
}.bind(this));
|
||||
Services.obs.removeObserver(this, "profile-before-change");
|
||||
ppmm = null;
|
||||
this._messages = null;
|
||||
if (this._db)
|
||||
this._db.close();
|
||||
this._db = null;
|
||||
this._children = null;
|
||||
this._cursors = null;
|
||||
if (aTopic === 'profile-before-change') {
|
||||
myGlobal = null;
|
||||
this._messages.forEach(function(msgName) {
|
||||
ppmm.removeMessageListener(msgName, this);
|
||||
}.bind(this));
|
||||
Services.obs.removeObserver(this, "profile-before-change");
|
||||
Services.prefs.removeObserver("dom.phonenumber.substringmatching", this);
|
||||
ppmm = null;
|
||||
this._messages = null;
|
||||
if (this._db)
|
||||
this._db.close();
|
||||
this._db = null;
|
||||
this._children = null;
|
||||
this._cursors = null;
|
||||
} else if (aTopic === 'nsPref:changed' && aData.contains("dom.phonenumber.substringmatching")) {
|
||||
// We don't fully support changing substringMatching during runtime. This is mostly for testing.
|
||||
let countryName = PhoneNumberUtils.getCountryName();
|
||||
if (Services.prefs.getPrefType("dom.phonenumber.substringmatching." + countryName) == Ci.nsIPrefBranch.PREF_INT) {
|
||||
let val = Services.prefs.getIntPref("dom.phonenumber.substringmatching." + countryName);
|
||||
if (val && val > 0) {
|
||||
this._db.enableSubstringMatching(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
assertPermission: function(aMessage, aPerm) {
|
||||
|
|
|
@ -13,6 +13,7 @@ include $(DEPTH)/config/autoconf.mk
|
|||
|
||||
MOCHITEST_FILES = \
|
||||
test_contacts_basics.html \
|
||||
test_contacts_substringmatching.html \
|
||||
test_contacts_events.html \
|
||||
test_contacts_blobs.html \
|
||||
test_contacts_international.html \
|
||||
|
|
|
@ -218,6 +218,15 @@ var steps = [
|
|||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Deleting database");
|
||||
req = mozContacts.clear()
|
||||
req.onsuccess = function () {
|
||||
ok(true, "Deleted the database");
|
||||
next();
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "all done!\n");
|
||||
SimpleTest.finish();
|
||||
|
|
|
@ -0,0 +1,261 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=877302
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 877302 substring matching for WebContacts</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=877302">Mozilla Bug 877302</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
"use strict";
|
||||
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/ContactService.jsm");
|
||||
}
|
||||
|
||||
var substringLength = 8;
|
||||
SpecialPowers.setIntPref("dom.phonenumber.substringmatching.BR", substringLength);
|
||||
|
||||
SpecialPowers.addPermission("contacts-write", true, document);
|
||||
SpecialPowers.addPermission("contacts-read", true, document);
|
||||
SpecialPowers.addPermission("contacts-create", true, document);
|
||||
|
||||
var sample_id1;
|
||||
var createResult1;
|
||||
var findResult1;
|
||||
|
||||
function onFailure() {
|
||||
ok(false, "in on Failure!");
|
||||
}
|
||||
|
||||
var prop = {
|
||||
tel: [{value: "7932012345" }, {value: "7932012346"}]
|
||||
};
|
||||
|
||||
var prop2 = {
|
||||
tel: [{value: "01187654321" }]
|
||||
};
|
||||
|
||||
var req;
|
||||
var index = 0;
|
||||
|
||||
var mozContacts = window.navigator.mozContacts;
|
||||
ok(mozContacts, "mozContacts exists");
|
||||
ok("mozContact" in window, "mozContact exists");
|
||||
var steps = [
|
||||
function () {
|
||||
ok(true, "Adding contact");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init(prop);
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
sample_id1 = createResult1.id;
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Retrieving all contacts");
|
||||
req = mozContacts.find({});
|
||||
req.onsuccess = function () {
|
||||
is(req.result.length, 1, "One contact.");
|
||||
findResult1 = req.result[0];
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Retrieving by substring 1");
|
||||
var length = prop.tel[0].value.length;
|
||||
var num = prop.tel[0].value.substring(length - substringLength, length);
|
||||
var options = {filterBy: ["tel"],
|
||||
filterOp: "match",
|
||||
filterValue: num};
|
||||
req = mozContacts.find(options);
|
||||
req.onsuccess = function () {
|
||||
is(req.result.length, 1, "Found exactly 1 contact.");
|
||||
findResult1 = req.result[0];
|
||||
ok(findResult1.id == sample_id1, "Same ID");
|
||||
is(findResult1.tel[0].value, "7932012345", "Same Value");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Retrieving by substring 2");
|
||||
var length = prop.tel[1].value.length;
|
||||
var num = prop.tel[1].value.substring(length - substringLength, length);
|
||||
var options = {filterBy: ["tel"],
|
||||
filterOp: "match",
|
||||
filterValue: num};
|
||||
req = mozContacts.find(options);
|
||||
req.onsuccess = function () {
|
||||
is(req.result.length, 1, "Found exactly 1 contact.");
|
||||
findResult1 = req.result[0];
|
||||
ok(findResult1.id == sample_id1, "Same ID");
|
||||
is(findResult1.tel[0].value, "7932012345", "Same Value");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Retrieving by substring 3");
|
||||
var length = prop.tel[0].value.length;
|
||||
var num = prop.tel[0].value.substring(length - substringLength + 1, length);
|
||||
var options = {filterBy: ["tel"],
|
||||
filterOp: "match",
|
||||
filterValue: num};
|
||||
req = mozContacts.find(options);
|
||||
req.onsuccess = function () {
|
||||
is(req.result.length, 0, "Found exactly 0 contacts.");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Retrieving by substring 4");
|
||||
var length = prop.tel[0].value.length;
|
||||
var num = prop.tel[0].value.substring(length - substringLength - 1, length);
|
||||
var options = {filterBy: ["tel"],
|
||||
filterOp: "match",
|
||||
filterValue: num};
|
||||
req = mozContacts.find(options);
|
||||
req.onsuccess = function () {
|
||||
is(req.result.length, 1, "Found exactly 1 contacts.");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Adding contact");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init(prop2);
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
sample_id1 = createResult1.id;
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Retrieving by substring 5");
|
||||
var options = {filterBy: ["tel"],
|
||||
filterOp: "match",
|
||||
filterValue: "87654321"};
|
||||
req = mozContacts.find(options);
|
||||
req.onsuccess = function () {
|
||||
is(req.result.length, 1, "Found exactly 1 contacts.");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Retrieving by substring 6");
|
||||
var options = {filterBy: ["tel"],
|
||||
filterOp: "match",
|
||||
filterValue: "01187654321"};
|
||||
req = mozContacts.find(options);
|
||||
req.onsuccess = function () {
|
||||
is(req.result.length, 1, "Found exactly 1 contacts.");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Retrieving by substring 7");
|
||||
var options = {filterBy: ["tel"],
|
||||
filterOp: "match",
|
||||
filterValue: "909087654321"};
|
||||
req = mozContacts.find(options);
|
||||
req.onsuccess = function () {
|
||||
is(req.result.length, 1, "Found exactly 1 contacts.");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Retrieving by substring 8");
|
||||
var options = {filterBy: ["tel"],
|
||||
filterOp: "match",
|
||||
filterValue: "0411187654321"};
|
||||
req = mozContacts.find(options);
|
||||
req.onsuccess = function () {
|
||||
is(req.result.length, 1, "Found exactly 1 contacts.");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Retrieving by substring 9");
|
||||
var options = {filterBy: ["tel"],
|
||||
filterOp: "match",
|
||||
filterValue: "90411187654321"};
|
||||
req = mozContacts.find(options);
|
||||
req.onsuccess = function () {
|
||||
is(req.result.length, 1, "Found exactly 1 contacts.");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Retrieving by substring 10");
|
||||
var options = {filterBy: ["tel"],
|
||||
filterOp: "match",
|
||||
filterValue: "+551187654321"};
|
||||
req = mozContacts.find(options);
|
||||
req.onsuccess = function () {
|
||||
is(req.result.length, 1, "Found exactly 1 contacts.");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Deleting database");
|
||||
req = mozContacts.clear()
|
||||
req.onsuccess = function () {
|
||||
ok(true, "Deleted the database");
|
||||
next();
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "all done!\n");
|
||||
SpecialPowers.setIntPref("dom.phonenumber.substringmatching.BR", -1);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
];
|
||||
|
||||
function next() {
|
||||
ok(true, "Begin!");
|
||||
if (index >= steps.length) {
|
||||
ok(false, "Shouldn't get here!");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
steps[index]();
|
||||
} catch(ex) {
|
||||
ok(false, "Caught exception", ex);
|
||||
}
|
||||
index += 1;
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(next);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -30,7 +30,7 @@ this.PhoneNumberUtils = {
|
|||
// mcc for Brasil
|
||||
_mcc: '724',
|
||||
|
||||
_getCountryName: function() {
|
||||
getCountryName: function getCountryName() {
|
||||
let mcc;
|
||||
let countryName;
|
||||
|
||||
|
@ -66,7 +66,7 @@ this.PhoneNumberUtils = {
|
|||
|
||||
parse: function(aNumber) {
|
||||
if (DEBUG) debug("call parse: " + aNumber);
|
||||
let result = PhoneNumber.Parse(aNumber, this._getCountryName());
|
||||
let result = PhoneNumber.Parse(aNumber, this.getCountryName());
|
||||
if (DEBUG) {
|
||||
if (result) {
|
||||
debug("InternationalFormat: " + result.internationalFormat);
|
||||
|
|
Загрузка…
Ссылка в новой задаче