mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
Bug 769245 - Contacts API: Add ContactEmail Type. r=sicking
This commit is contained in:
parent
79a6737a47
commit
96c377da98
@ -2,7 +2,7 @@
|
||||
* 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"
|
||||
"use strict";
|
||||
|
||||
/* static functions */
|
||||
let DEBUG = 0;
|
||||
@ -78,6 +78,29 @@ ContactAddress.prototype = {
|
||||
QueryInterface : XPCOMUtils.generateQI([nsIDOMContactAddress])
|
||||
}
|
||||
|
||||
//ContactEmail
|
||||
|
||||
const CONTACTEMAIL_CONTRACTID = "@mozilla.org/contactEmail;1";
|
||||
const CONTACTEMAIL_CID = Components.ID("{94811520-c11f-11e1-afa7-0800200c9a66}");
|
||||
const nsIDOMContactEmail = Components.interfaces.nsIDOMContactEmail;
|
||||
|
||||
function ContactEmail(aType, aAddress) {
|
||||
this.type = aType || null;
|
||||
this.address = aAddress || null;
|
||||
};
|
||||
|
||||
ContactEmail.prototype = {
|
||||
|
||||
classID : CONTACTEMAIL_CID,
|
||||
classInfo : XPCOMUtils.generateCI({classID: CONTACTEMAIL_CID,
|
||||
contractID: CONTACTEMAIL_CONTRACTID,
|
||||
classDescription: "ContactEmail",
|
||||
interfaces: [nsIDOMContactEmail],
|
||||
flags: nsIClassInfo.DOM_OBJECT}),
|
||||
|
||||
QueryInterface : XPCOMUtils.generateQI([nsIDOMContactEmail])
|
||||
}
|
||||
|
||||
//ContactTelephone
|
||||
|
||||
const CONTACTTELEPHONE_CONTRACTID = "@mozilla.org/contactTelephone;1";
|
||||
@ -134,9 +157,15 @@ Contact.prototype = {
|
||||
init: function init(aProp) {
|
||||
// Accept non-array strings for DOMString[] properties and convert them.
|
||||
function _create(aField) {
|
||||
if (typeof aField == "string")
|
||||
return new Array(aField);
|
||||
if (Array.isArray(aField)) {
|
||||
for (let i = 0; i < aField.length; i++) {
|
||||
if (typeof aField[i] !== "string")
|
||||
aField[i] = String(aField[i]);
|
||||
}
|
||||
return aField;
|
||||
} else if (aField != null) {
|
||||
return [String(aField)];
|
||||
}
|
||||
};
|
||||
|
||||
this.name = _create(aProp.name) || null;
|
||||
@ -146,7 +175,16 @@ Contact.prototype = {
|
||||
this.familyName = _create(aProp.familyName) || null;
|
||||
this.honorificSuffix = _create(aProp.honorificSuffix) || null;
|
||||
this.nickname = _create(aProp.nickname) || null;
|
||||
this.email = _create(aProp.email) || null;
|
||||
|
||||
if (aProp.email) {
|
||||
aProp.email = Array.isArray(aProp.email) ? aProp.email : [aProp.email];
|
||||
this.email = new Array();
|
||||
for (let i = 0; i < aProp.email.length; i++)
|
||||
this.email.push(new ContactEmail(aProp.email[i].type, aProp.email[i].address));
|
||||
} else {
|
||||
this.email = null;
|
||||
}
|
||||
|
||||
this.photo = _create(aProp.photo) || null;
|
||||
this.url = _create(aProp.url) || null;
|
||||
this.category = _create(aProp.category) || null;
|
||||
@ -445,4 +483,4 @@ ContactManager.prototype = {
|
||||
}
|
||||
|
||||
const NSGetFactory = XPCOMUtils.generateNSGetFactory(
|
||||
[Contact, ContactManager, ContactProperties, ContactAddress, ContactTelephone, ContactFindOptions])
|
||||
[Contact, ContactManager, ContactProperties, ContactAddress, ContactTelephone, ContactFindOptions, ContactEmail])
|
||||
|
@ -7,6 +7,9 @@ contract @mozilla.org/contactAddress;1 {eba48030-89e8-11e1-b0c4-0800200c9a66}
|
||||
component {82601b20-89e8-11e1-b0c4-0800200c9a66} ContactManager.js
|
||||
contract @mozilla.org/contactTelephone;1 {82601b20-89e8-11e1-b0c4-0800200c9a66}
|
||||
|
||||
component {94811520-c11f-11e1-afa7-0800200c9a66} ContactManager.js
|
||||
contract @mozilla.org/contactEmail;1 {94811520-c11f-11e1-afa7-0800200c9a66}
|
||||
|
||||
component {e31daea0-0cb6-11e1-be50-0800200c9a66} ContactManager.js
|
||||
contract @mozilla.org/contactFindOptions;1 {e31daea0-0cb6-11e1-be50-0800200c9a66}
|
||||
|
||||
|
@ -22,7 +22,7 @@ Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/IndexedDBHelper.jsm");
|
||||
|
||||
const DB_NAME = "contacts";
|
||||
const DB_VERSION = 2;
|
||||
const DB_VERSION = 3;
|
||||
const STORE_NAME = "contacts";
|
||||
|
||||
function ContactDB(aGlobal) {
|
||||
@ -101,6 +101,31 @@ ContactDB.prototype = {
|
||||
// Create new searchable indexes.
|
||||
objectStore.createIndex("tel", "search.tel", { unique: false, multiEntry: true });
|
||||
objectStore.createIndex("category", "properties.category", { unique: false, multiEntry: true });
|
||||
} else if (currVersion == 2) {
|
||||
debug("upgrade 2");
|
||||
// Create a new scheme for the email field. We move from an array of emailaddresses to an array of
|
||||
// ContactEmail.
|
||||
if (!objectStore) {
|
||||
objectStore = aTransaction.objectStore(STORE_NAME);
|
||||
}
|
||||
// Delete old email index.
|
||||
objectStore.deleteIndex("email");
|
||||
|
||||
// Upgrade existing email field in the DB.
|
||||
objectStore.openCursor().onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
debug("upgrade email1: " + JSON.stringify(cursor.value));
|
||||
cursor.value.properties.email =
|
||||
cursor.value.properties.email.map(function(address) { return { address: address }; });
|
||||
cursor.update(cursor.value);
|
||||
debug("upgrade email2: " + JSON.stringify(cursor.value));
|
||||
cursor.continue();
|
||||
}
|
||||
};
|
||||
|
||||
// Create new searchable indexes.
|
||||
objectStore.createIndex("email", "search.email", { unique: false, multiEntry: true });
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -172,8 +197,16 @@ ContactDB.prototype = {
|
||||
}
|
||||
}
|
||||
debug("lookup: " + JSON.stringify(contact.search[field]));
|
||||
} else if (field == "email") {
|
||||
let address = aContact.properties[field][i].address;
|
||||
if (address && typeof address == "string") {
|
||||
contact.search[field].push(address.toLowerCase());
|
||||
}
|
||||
} else {
|
||||
contact.search[field].push(aContact.properties[field][i].toLowerCase());
|
||||
let val = aContact.properties[field][i];
|
||||
if (typeof val == "string") {
|
||||
contact.search[field].push(val.toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -319,7 +352,9 @@ ContactDB.prototype = {
|
||||
request = index.mozGetAll(options.filterValue, limit);
|
||||
} else {
|
||||
// not case sensitive
|
||||
let tmp = options.filterValue.toLowerCase();
|
||||
let tmp = typeof options.filterValue == "string"
|
||||
? options.filterValue.toLowerCase()
|
||||
: options.filterValue.toString().toLowerCase();
|
||||
let range = this._global.IDBKeyRange.bound(tmp, tmp + "\uFFFF");
|
||||
let index = store.index(key + "LowerCase");
|
||||
request = index.mozGetAll(range, limit);
|
||||
|
@ -2,7 +2,7 @@
|
||||
* 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"
|
||||
"use strict";
|
||||
|
||||
let DEBUG = 0;
|
||||
if (DEBUG)
|
||||
|
@ -76,7 +76,8 @@ var properties1 = {
|
||||
givenName: ["Test1","Test2"],
|
||||
nickname: "nicktest",
|
||||
tel: [{type: "work", number: "123456"} , {type: "home", number: "+9-876-5432"}],
|
||||
adr: adr1
|
||||
adr: adr1,
|
||||
email: [{type: "work", address: "x@y.com"}]
|
||||
};
|
||||
|
||||
var properties2 = {
|
||||
@ -88,7 +89,7 @@ var properties2 = {
|
||||
additionalName: "dummyadditionalName",
|
||||
nickname: "dummyNickname",
|
||||
tel: [{type: "test", number: "123456789"},{type: "home", number: "234567890"}],
|
||||
email: ["a@b.c", "b@c.d"],
|
||||
email: [{type: "test", address: "a@b.c"}, {address: "b@c.d"}],
|
||||
adr: [adr1, adr2],
|
||||
impp: ["im1", "im2"],
|
||||
org: ["org1", "org2"],
|
||||
@ -148,6 +149,11 @@ function checkTel(tel1, tel2) {
|
||||
checkStr(tel1.number, tel2.number, "Same number");
|
||||
}
|
||||
|
||||
function checkEmail(email1, email2) {
|
||||
checkStr(email1.type, email2.type, "Same type");
|
||||
checkStr(email1.address, email2.address, "Same address");
|
||||
}
|
||||
|
||||
function checkContacts(contact1, contact2) {
|
||||
checkStr(contact1.name, contact2.name, "Same name");
|
||||
checkStr(contact1.honorificPrefix, contact2.honorificPrefix, "Same honorificPrefix");
|
||||
@ -156,7 +162,6 @@ function checkContacts(contact1, contact2) {
|
||||
checkStr(contact1.familyName, contact2.familyName, "Same familyName");
|
||||
checkStr(contact1.honorificSuffix, contact2.honorificSuffix, "Same honorificSuffix");
|
||||
checkStr(contact1.nickname, contact2.nickname, "Same nickname");
|
||||
checkStr(contact1.email, contact2.email, "Same email");
|
||||
checkStr(contact1.photo, contact2.photo, "Same photo");
|
||||
checkStr(contact1.url, contact2.url, "Same url");
|
||||
checkStr(contact1.category, contact2.category, "Same category");
|
||||
@ -169,6 +174,8 @@ function checkContacts(contact1, contact2) {
|
||||
is(contact1.sex, contact2.sex, "Same sex");
|
||||
is(contact1.genderIdentity, contact2.genderIdentity, "Same genderIdentity");
|
||||
|
||||
for (var i in contact1.email)
|
||||
checkEmail(contact1.email[i], contact2.email[i]);
|
||||
for (var i in contact1.adr)
|
||||
checkAddress(contact1.adr[i], contact2.adr[i]);
|
||||
for (var i in contact1.tel)
|
||||
@ -269,6 +276,21 @@ var steps = [
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Searching for exact email");
|
||||
var options = {filterBy: ["email"],
|
||||
filterOp: "equals",
|
||||
filterValue: properties1.email[0].address};
|
||||
req = mozContacts.find(options);
|
||||
req.onsuccess = function () {
|
||||
ok(req.result.length == 1, "Found exactly 1 contact.");
|
||||
findResult1 = req.result[0];
|
||||
ok(findResult1.id == sample_id1, "Same ID");
|
||||
checkContacts(findResult1, createResult1);
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Retrieving by substring and update");
|
||||
mozContacts.oncontactchange = function(event) {
|
||||
@ -616,14 +638,14 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Modifying contact3");
|
||||
findResult1.email = (properties1.nickname);
|
||||
findResult1.email = [{address: properties1.nickname}];
|
||||
findResult1.nickname = "TEST";
|
||||
var newContact = new mozContact();
|
||||
newContact.init(findResult1);
|
||||
req = mozContacts.save(newContact);
|
||||
req.onsuccess = function () {
|
||||
var options = {filterBy: ["nickname", "email", "name"],
|
||||
filterOp: "equals",
|
||||
filterOp: "contains",
|
||||
filterValue: properties1.nickname};
|
||||
// One contact has it in nickname and the other in email
|
||||
var req2 = mozContacts.find(options);
|
||||
@ -741,7 +763,7 @@ var steps = [
|
||||
ok(true, "Searching contacts by email");
|
||||
var options = {filterBy: ["email"],
|
||||
filterOp: "contains",
|
||||
filterValue: properties2.email[0].substring(0, 4)};
|
||||
filterValue: properties2.email[0].address.substring(0, 4)};
|
||||
req = mozContacts.find(options);
|
||||
req.onsuccess = function () {
|
||||
ok(req.result.length == 1, "Found exactly 1 contact.");
|
||||
@ -865,12 +887,12 @@ var steps = [
|
||||
ok(true, "Testing clone contact2");
|
||||
var cloned = new mozContact(createResult1);
|
||||
ok(cloned.id != createResult1.id, "Cloned contact has new ID");
|
||||
cloned.email = "new email!";
|
||||
cloned.email = {address: "new email!"};
|
||||
cloned.givenName = "Tom";
|
||||
req = mozContacts.save(cloned);
|
||||
req.onsuccess = function () {
|
||||
ok(cloned.id, "The contact now has an ID.");
|
||||
ok(cloned.email == "new email!", "Same Email");
|
||||
ok(cloned.email.address == "new email!", "Same Email");
|
||||
ok(createResult1.email != cloned.email, "Clone has different email");
|
||||
ok(cloned.givenName == "Tom", "New Name");
|
||||
next();
|
||||
@ -892,7 +914,7 @@ var steps = [
|
||||
function () {
|
||||
ok(true, "Search with redundant fields should only return 1 contact");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init({name: "XXX", nickname: "XXX", email: "XXX", tel: {number: "XXX"}});
|
||||
createResult1.init({name: "XXX", nickname: "XXX", email: [{address: "XXX"}], tel: {number: "XXX"}});
|
||||
req = mozContacts.save(createResult1);
|
||||
req.onsuccess = function() {
|
||||
var options = {filterBy: [],
|
||||
@ -1098,6 +1120,40 @@ var steps = [
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Adding empty contact");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init({givenName: 5});
|
||||
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, "Test category search with equals");
|
||||
var options = {filterBy: ["givenName"],
|
||||
filterOp: "contains",
|
||||
filterValue: 5};
|
||||
req = mozContacts.find(options);
|
||||
req.onsuccess = function () {
|
||||
ok(req.result.length == 1, "1 Entry.");
|
||||
checkContacts(req.result[0], createResult1);
|
||||
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");
|
||||
clearTemps();
|
||||
|
@ -25,6 +25,13 @@ interface nsIDOMContactTelephone : nsISupports
|
||||
attribute DOMString number;
|
||||
};
|
||||
|
||||
[scriptable, uuid(94811520-c11f-11e1-afa7-0800200c9a66)]
|
||||
interface nsIDOMContactEmail : nsISupports
|
||||
{
|
||||
attribute DOMString type;
|
||||
attribute DOMString address;
|
||||
};
|
||||
|
||||
[scriptable, uuid(e31daea0-0cb6-11e1-be50-0800200c9a66)]
|
||||
interface nsIDOMContactFindOptions : nsISupports
|
||||
{
|
||||
@ -46,7 +53,7 @@ interface nsIDOMContactProperties : nsISupports
|
||||
attribute jsval familyName; // DOMString[]
|
||||
attribute jsval honorificSuffix; // DOMString[]
|
||||
attribute jsval nickname; // DOMString[]
|
||||
attribute jsval email; // DOMString[]
|
||||
attribute jsval email; // ContactEmail[]
|
||||
attribute jsval photo; // DOMString[]
|
||||
attribute jsval url; // DOMString[]
|
||||
attribute jsval category; // DOMString[]
|
||||
|
@ -519,6 +519,7 @@ var interfaceNamesInGlobalScope =
|
||||
"WebGLActiveInfo",
|
||||
"SVGGradientElement",
|
||||
"ContactTelephone",
|
||||
"ContactEmail",
|
||||
"SVGFitToViewBox",
|
||||
"SVGAElement"
|
||||
]
|
||||
|
Loading…
Reference in New Issue
Block a user