Backed out 8 changesets (bug 916267, bug 850430) for mochitest failures

This commit is contained in:
Reuben Morais 2013-09-30 01:44:06 -03:00
parent 5e75884e6a
commit 551b5f8e6c
29 changed files with 1143 additions and 969 deletions

View File

@ -17,4 +17,5 @@
#
# Modifying this file will now automatically clobber the buildbot machines \o/
#
Bug 916267 needs a clobber on Windows.
Bug 901789 needs a clobber.

View File

@ -177,6 +177,7 @@
#endif
@BINPATH@/components/dom_camera.xpt
@BINPATH@/components/dom_canvas.xpt
@BINPATH@/components/dom_contacts.xpt
@BINPATH@/components/dom_alarm.xpt
@BINPATH@/components/dom_core.xpt
@BINPATH@/components/dom_css.xpt

View File

@ -187,6 +187,7 @@
#endif
@BINPATH@/components/dom_camera.xpt
@BINPATH@/components/dom_canvas.xpt
@BINPATH@/components/dom_contacts.xpt
@BINPATH@/components/dom_alarm.xpt
@BINPATH@/components/dom_core.xpt
@BINPATH@/components/dom_css.xpt

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,6 @@
component {35ad8a4e-9486-44b6-883d-550f14635e49} ContactManager.js
contract @mozilla.org/contactProperties;1 {35ad8a4e-9486-44b6-883d-550f14635e49}
component {9cbfa81c-bcab-4ca9-b0d2-f4318f295e33} ContactManager.js
contract @mozilla.org/contactAddress;1 {9cbfa81c-bcab-4ca9-b0d2-f4318f295e33}
@ -7,8 +10,16 @@ contract @mozilla.org/contactField;1 {ad19a543-69e4-44f0-adfa-37c011556bc1}
component {4d42c5a9-ea5d-4102-80c3-40cc986367ca} ContactManager.js
contract @mozilla.org/contactTelField;1 {4d42c5a9-ea5d-4102-80c3-40cc986367ca}
component {0a5b1fab-70da-46dd-b902-619904d920c2} ContactManager.js
contract @mozilla.org/contactFindSortOptions;1 {0a5b1fab-70da-46dd-b902-619904d920c2}
component {28ce07d0-45d9-4b7a-8843-521df4edd8bc} ContactManager.js
contract @mozilla.org/contactFindOptions;1 {28ce07d0-45d9-4b7a-8843-521df4edd8bc}
component {72a5ee28-81d8-4af8-90b3-ae935396cc66} ContactManager.js
contract @mozilla.org/contact;1 {72a5ee28-81d8-4af8-90b3-ae935396cc66}
category JavaScript-global-constructor mozContact @mozilla.org/contact;1
component {8beb3a66-d70a-4111-b216-b8e995ad3aff} ContactManager.js
contract @mozilla.org/contactManager;1 {8beb3a66-d70a-4111-b216-b8e995ad3aff}
category JavaScript-navigator-property mozContacts @mozilla.org/contactManager;1

View File

@ -20,28 +20,24 @@ Cu.import("resource://gre/modules/IndexedDBHelper.jsm");
Cu.import("resource://gre/modules/PhoneNumberUtils.jsm");
const DB_NAME = "contacts";
const DB_VERSION = 15;
const DB_VERSION = 14;
const STORE_NAME = "contacts";
const SAVED_GETALL_STORE_NAME = "getallcache";
const CHUNK_SIZE = 20;
const REVISION_STORE = "revision";
const REVISION_KEY = "revision";
function optionalDate(aValue) {
if (aValue) {
if (!(aValue instanceof Date)) {
return new Date(aValue);
}
return aValue;
}
return undefined;
}
function exportContact(aRecord) {
if (aRecord) {
delete aRecord.search;
}
return aRecord;
let contact = {};
contact.properties = aRecord.properties;
for (let field in aRecord.properties)
contact.properties[field] = aRecord.properties[field];
contact.updated = aRecord.updated;
contact.published = aRecord.published;
contact.id = aRecord.id;
return contact;
}
function ContactDispatcher(aContacts, aFullContacts, aCallback, aNewTxn, aClearDispatcher, aFailureCb) {
@ -154,7 +150,9 @@ ContactDB.prototype = {
for (let i = 0; i < contacts.length; i++) {
let contact = {};
contact.properties = contacts[i];
contact.id = idService.generateUUID().toString().replace(/[{}-]/g, "");
contact.id = idService.generateUUID().toString().replace('-', '', 'g')
.replace('{', '')
.replace('}', '');
contact = this.makeImport(contact);
this.updateRecordMetadata(contact);
if (DEBUG) debug("import: " + JSON.stringify(contact));
@ -551,47 +549,6 @@ ContactDB.prototype = {
}
};
},
function upgrade14to15() {
if (DEBUG) debug("Fix array properties saved as scalars");
if (!objectStore) {
objectStore = aTransaction.objectStore(STORE_NAME);
}
const ARRAY_PROPERTIES = ["photo", "adr", "email", "url", "impp", "tel",
"name", "honorificPrefix", "givenName",
"additionalName", "familyName", "honorificSuffix",
"nickname", "category", "org", "jobTitle",
"note", "key"];
const PROPERTIES_WITH_TYPE = ["adr", "email", "url", "impp", "tel"];
objectStore.openCursor().onsuccess = function(event) {
let cursor = event.target.result;
let changed = false;
if (cursor) {
let props = cursor.value.properties;
for (let prop of ARRAY_PROPERTIES) {
if (props[prop]) {
if (!Array.isArray(props[prop])) {
cursor.value.properties[prop] = [props[prop]];
changed = true;
}
if (PROPERTIES_WITH_TYPE.indexOf(prop) !== -1) {
for (let subprop of cursor.value.properties[prop]) {
if (!Array.isArray(subprop.type)) {
subprop.type = [subprop.type];
changed = true;
}
}
}
}
}
if (changed) {
cursor.update(cursor.value);
}
cursor.continue();
} else {
next();
}
};
},
];
let index = aOldVersion;
@ -619,7 +576,31 @@ ContactDB.prototype = {
},
makeImport: function makeImport(aContact) {
let contact = {properties: {}};
let contact = {};
contact.properties = {
name: [],
honorificPrefix: [],
givenName: [],
additionalName: [],
familyName: [],
honorificSuffix: [],
nickname: [],
email: [],
photo: [],
url: [],
category: [],
adr: [],
tel: [],
org: [],
jobTitle: [],
bday: null,
note: [],
impp: [],
anniversary: null,
sex: null,
genderIdentity: null,
key: [],
};
contact.search = {
givenName: [],
@ -706,9 +687,10 @@ ContactDB.prototype = {
}
}
}
if (DEBUG) debug("contact:" + JSON.stringify(contact));
contact.updated = optionalDate(aContact.updated);
contact.published = optionalDate(aContact.published);
contact.updated = aContact.updated;
contact.published = aContact.published;
contact.id = aContact.id;
return contact;

View File

@ -61,30 +61,29 @@ var c4 = {
};
var c5 = {
familyName: [],
givenName: [],
nickname: "empty"
};
var c6 = {
name: ["e"],
name: "e",
familyName: ["e","e","e"],
givenName: ["e","e","e"],
};
var c7 = {
name: ["e"],
name: "e",
familyName: ["e","e","e"],
givenName: ["e","e","e"],
};
var c8 = {
name: ["e"],
name: "e",
familyName: ["e","e","e"],
givenName: ["e","e","e"],
};
var adr1 = {
type: ["work"],
type: "work",
streetAddress: "street 1",
locality: "locality 1",
region: "region 1",
@ -93,7 +92,7 @@ var adr1 = {
};
var adr2 = {
type: ["home, fax"],
type: "home, fax",
streetAddress: "street2",
locality: "locality2",
region: "region2",
@ -105,34 +104,34 @@ var properties1 = {
name: ["Test1 TestFamilyName", "Test2 Wagner"],
familyName: ["TestFamilyName","Wagner"],
givenName: ["Test1","Test2"],
nickname: ["nicktest"],
nickname: "nicktest",
tel: [{type: ["work"], value: "123456", carrier: "testCarrier"} , {type: ["home", "fax"], value: "+55 (31) 9876-3456"}, {type: ["home"], value: "+49 451 491934"}],
adr: [adr1],
adr: adr1,
email: [{type: ["work"], value: "x@y.com"}],
};
var properties2 = {
name: ["dummyHonorificPrefix dummyGivenName dummyFamilyName dummyHonorificSuffix", "dummyHonorificPrefix2"],
familyName: ["dummyFamilyName"],
givenName: ["dummyGivenName"],
familyName: "dummyFamilyName",
givenName: "dummyGivenName",
honorificPrefix: ["dummyHonorificPrefix","dummyHonorificPrefix2"],
honorificSuffix: ["dummyHonorificSuffix"],
additionalName: ["dummyadditionalName"],
nickname: ["dummyNickname"],
honorificSuffix: "dummyHonorificSuffix",
additionalName: "dummyadditionalName",
nickname: "dummyNickname",
tel: [{type: ["test"], value: "7932012345", carrier: "myCarrier", pref: 1},{type: ["home", "custom"], value: "7932012346", pref: 0}],
email: [{type: ["test"], value: "a@b.c"}, {value: "b@c.d", pref: 1}],
adr: [adr1, adr2],
impp: [{type: ["aim"], value:"im1", pref: 1}, {value: "im2"}],
org: ["org1", "org2"],
jobTitle: ["boss", "superboss"],
note: ["test note"],
note: "test note",
category: ["cat1", "cat2"],
url: [{type: ["work", "work2"], value: "www.1.com", pref: 1}, {value:"www2.com"}],
bday: new Date("1980, 12, 01"),
anniversary: new Date("2000, 12, 01"),
sex: "male",
genderIdentity: "test",
key: ["ERPJ394GJJWEVJ0349GJ09W3H4FG0WFW80VHW3408GH30WGH348G3H"]
key: "ERPJ394GJJWEVJ0349GJ09W3H4FG0WFW80VHW3408GH30WGH348G3H"
};
var sample_id1;
@ -167,39 +166,20 @@ function checkStr(str1, str2, msg) {
ok(false, "Expected both strings to be either present or absent");
return;
}
if (!str1 || str1 == "null") {
str1 = null;
}
if (!str2 || str2 == "null") {
str2 = null;
}
is(str1, str2, msg);
}
function checkStrArray(str1, str2, msg) {
function normalize_falsy(v) {
if (!v || v == "null" || v == "undefined") {
return "";
}
return v;
// comparing /[null(,null)+]/ and undefined should pass
function nonNull(e) {
return e != null;
}
function optArray(val) {
return Array.isArray(val) ? val : [val];
if ((Array.isArray(str1) && str1.filter(nonNull).length == 0 && str2 == undefined)
||(Array.isArray(str2) && str2.filter(nonNull).length == 0 && str1 == undefined)) {
ok(true, msg);
} else if (str1) {
is(JSON.stringify(typeof str1 == "string" ? [str1] : str1), JSON.stringify(typeof str2 == "string" ? [str2] : str2), msg);
}
str1 = optArray(str1).map(normalize_falsy).filter(v => v != "");
str2 = optArray(str2).map(normalize_falsy).filter(v => v != "");
ise(JSON.stringify(str1), JSON.stringify(str2), msg);
}
function checkPref(pref1, pref2) {
// If on Android treat one preference as 0 and the other as undefined as matching
if (isAndroid) {
if ((!pref1 && pref2 == undefined) || (pref1 == undefined && !pref2)) {
pref1 = false;
pref2 = false;
}
}
ise(!!pref1, !!pref2, "Same pref");
}
function checkAddress(adr1, adr2) {
@ -208,31 +188,44 @@ function checkAddress(adr1, adr2) {
return;
}
checkStrArray(adr1.type, adr2.type, "Same type");
checkStr(adr1.streetAddress, adr2.streetAddress, "Same streetAddress");
checkStr(adr1.locality, adr2.locality, "Same locality");
checkStr(adr1.region, adr2.region, "Same region");
checkStr(adr1.postalCode, adr2.postalCode, "Same postalCode");
checkStr(adr1.countryName, adr2.countryName, "Same countryName");
checkStrArray(adr1.streetAddress, adr2.streetAddress, "Same streetAddress");
checkStrArray(adr1.locality, adr2.locality, "Same locality");
checkStrArray(adr1.region, adr2.region, "Same region");
checkStrArray(adr1.postalCode, adr2.postalCode, "Same postalCode");
checkStrArray(adr1.countryName, adr2.countryName, "Same countryName");
checkPref(adr1.pref, adr2.pref);
}
function checkTel(tel1, tel2) {
if (tel1 ^ tel2) {
ok(false, "Expected both tels to be either present or absent");
return;
}
checkStrArray(tel1.type, tel2.type, "Same type");
checkStrArray(tel1.value, tel2.value, "Same value");
checkStrArray(tel1.carrier, tel2.carrier, "Same carrier");
checkPref(tel1.pref, tel2.pref);
}
function checkField(field1, field2) {
if (field1 ^ field2) {
ok(false, "Expected both fields to be either present or absent");
return;
}
checkStrArray(field1.type, field2.type, "Same type");
checkStr(field1.value, field2.value, "Same value");
checkStrArray(field1.value, field2.value, "Same value");
checkPref(field1.pref, field2.pref);
}
function checkTel(tel1, tel2) {
if (tel1 ^ tel2) {
ok(false, "Expected both tels to be either present or absent");
return;
function checkPref(pref1, pref2) {
// If on Android treat one preference as 0 and the other as undefined as matching
if (isAndroid) {
if ((pref1 == 0 && pref2 == undefined) || (pref1 == undefined && pref2 == 0)) {
pref1 = 0;
pref2 = 0;
}
}
checkField(tel1, tel2);
checkStr(tel1.carrier, tel2.carrier, "Same carrier");
is(pref1, pref2, "Same pref");
}
function checkCategory(category1, category2) {
@ -246,42 +239,21 @@ function checkCategory(category1, category2) {
}
function removeAndroidDefaultCategory(category) {
if (!category) {
return category;
if (category == undefined) {
return;
}
var result = [];
for (var i of category) {
for (var i = 0; i < category.length; i++) {
// Some devices may return the full group name (prefixed with "System Group: ")
if (i != "My Contacts" && i != "System Group: My Contacts") {
result.push(i);
if (category[i] == "My Contacts" || category[i] == "System Group: My Contacts") {
category.splice(i, 1);
}
}
return result;
}
function checkArrayField(array1, array2, func, msg) {
if (!!array1 ^ !!array2) {
ok(false, "Expected both arrays to be either present or absent");
return;
}
if (!array1 && !array2) {
ok(true, msg);
return;
}
ise(array1.length, array2.length, "Same length");
for (var i = 0; i < array1.length; ++i) {
func(array1[i], array2[i], msg);
}
return category;
}
function checkContacts(contact1, contact2) {
if (!!contact1 ^ !!contact2) {
ok(false, "Expected both contacts to be either present or absent");
return;
}
checkStrArray(contact1.name, contact2.name, "Same name");
checkStrArray(contact1.honorificPrefix, contact2.honorificPrefix, "Same honorificPrefix");
checkStrArray(contact1.givenName, contact2.givenName, "Same givenName");
@ -299,11 +271,21 @@ function checkContacts(contact1, contact2) {
checkStr(contact1.genderIdentity, contact2.genderIdentity, "Same genderIdentity");
checkStrArray(contact1.key, contact2.key, "Same key");
checkArrayField(contact1.adr, contact2.adr, checkAddress, "Same adr");
checkArrayField(contact1.tel, contact2.tel, checkTel, "Same tel");
checkArrayField(contact1.email, contact2.email, checkField, "Same email");
checkArrayField(contact1.url, contact2.url, checkField, "Same url");
checkArrayField(contact1.impp, contact2.impp, checkField, "Same impp");
for (var i in contact1.email) {
checkField(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) {
checkTel(contact1.tel[i], contact2.tel[i]);
}
for (var i in contact1.url) {
checkField(contact1.url[i], contact2.url[i]);
}
for (var i in contact1.impp) {
checkField(contact1.impp[i], contact2.impp[i]);
}
}
var req;
@ -311,10 +293,6 @@ var index = 0;
var initialRev;
var defaultOptions = {
sortBy: "givenName",
};
function checkRevision(revision, msg, then) {
var revReq = mozContacts.getRevision();
revReq.onsuccess = function(e) {
@ -341,6 +319,8 @@ function checkCount(count, msg, then) {
}
var mozContacts = window.navigator.mozContacts;
ok(mozContacts, "mozContacts exists");
ok("mozContact" in window, "mozContact exists");
var steps = [
function() {
req = mozContacts.getRevision();
@ -374,7 +354,7 @@ var steps = [
},
function () {
ok(true, "Retrieving all contacts");
req = mozContacts.find(defaultOptions);
req = mozContacts.find({});
req.onsuccess = function () {
is(req.result.length, 0, "Empty database.");
checkRevision(1, "Revision was not incremented on find", next);
@ -383,7 +363,8 @@ var steps = [
},
function () {
ok(true, "Adding empty contact");
createResult1 = new mozContact({});
createResult1 = new mozContact();
createResult1.init({});
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
@ -396,7 +377,7 @@ var steps = [
},
function () {
ok(true, "Retrieving all contacts");
req = mozContacts.find(defaultOptions);
req = mozContacts.find({});
req.onsuccess = function () {
is(req.result.length, 1, "One contact.");
findResult1 = req.result[0];
@ -408,7 +389,7 @@ var steps = [
ok(true, "Deleting empty contact");
req = navigator.mozContacts.remove(findResult1);
req.onsuccess = function () {
var req2 = mozContacts.find(defaultOptions);
var req2 = mozContacts.find({});
req2.onsuccess = function () {
is(req2.result.length, 0, "Empty Database.");
clearTemps();
@ -420,7 +401,8 @@ var steps = [
},
function () {
ok(true, "Adding a new contact1");
createResult1 = new mozContact(properties1);
createResult1 = new mozContact();
createResult1.init(properties1);
mozContacts.oncontactchange = function(event) {
is(event.contactID, createResult1.id, "Same contactID");
@ -505,7 +487,8 @@ var steps = [
is(event.contactID, createResult2.id, "Same contactID");
is(event.reason, "create", "Same reason");
}
createResult2 = new mozContact({name: ["newName"]});
createResult2 = new mozContact();
createResult2.init({name: "newName"});
req = navigator.mozContacts.save(createResult2);
req.onsuccess = function () {
ok(createResult2.id, "The contact now has an ID.");
@ -590,7 +573,8 @@ var steps = [
},
function () {
ok(true, "Adding a new contact with properties1");
createResult1 = new mozContact(properties1);
createResult1 = new mozContact();
createResult1.init(properties1);
mozContacts.oncontactchange = null;
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
@ -804,16 +788,14 @@ var steps = [
},
function () {
ok(true, "Retrieving all contacts");
req = mozContacts.find(defaultOptions);
req = mozContacts.find({});
req.onsuccess = function() {
is(req.result.length, 1, "Found exactly 1 contact.");
findResult1 = req.result[0];
ok(findResult1.id == sample_id1, "Same ID");
checkContacts(createResult1, findResult1);
if (!isAndroid) {
ok(findResult1.updated, "Has updated field");
ok(findResult1.published, "Has published field");
}
ok(findResult1.updated, "Has updated field");
ok(findResult1.published, "Has published field");
next();
}
req.onerror = onFailure;
@ -826,7 +808,7 @@ var steps = [
findResult1.impp = properties1.impp = [{value:"phil impp"}];
req = navigator.mozContacts.save(findResult1);
req.onsuccess = function () {
var req2 = mozContacts.find(defaultOptions);
var req2 = mozContacts.find({});
req2.onsuccess = function() {
is(req2.result.length, 1, "Found exactly 1 contact.");
findResult2 = req2.result[0];
@ -890,7 +872,7 @@ var steps = [
findResult1.impp = properties1.impp = [{value: "phil impp"}];
req = mozContacts.save(findResult1);
req.onsuccess = function () {
var req2 = mozContacts.find(defaultOptions);
var req2 = mozContacts.find({});
req2.onsuccess = function () {
is(req2.result.length, 1, "Found exactly 1 contact.");
findResult1 = req2.result[0];
@ -955,8 +937,9 @@ var steps = [
SpecialPowers.executeSoon(next);
} else {
findResult1.email = [{value: properties1.nickname}];
findResult1.nickname = ["TEST"];
var newContact = new mozContact(findResult1);
findResult1.nickname = "TEST";
var newContact = new mozContact();
newContact.init(findResult1);
req = mozContacts.save(newContact);
req.onsuccess = function () {
var options = {filterBy: ["email", "givenName"],
@ -978,7 +961,7 @@ var steps = [
ok(true, "Deleting contact" + findResult1);
req = mozContacts.remove(findResult1);
req.onsuccess = function () {
var req2 = mozContacts.find(defaultOptions);
var req2 = mozContacts.find({});
req2.onsuccess = function () {
is(req2.result.length, 1, "One contact left.");
findResult1 = req2.result[0];
@ -999,7 +982,8 @@ var steps = [
},
function () {
ok(true, "Adding a new contact");
createResult1 = new mozContact(properties1);
createResult1 = new mozContact();
createResult1.init(properties1);
req = mozContacts.save(createResult1)
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
@ -1010,7 +994,8 @@ var steps = [
},
function () {
ok(true, "Adding a new contact2");
createResult2 = new mozContact(properties2);
createResult2 = new mozContact();
createResult2.init(properties2);
req = mozContacts.save(createResult2);
req.onsuccess = function () {
ok(createResult2.id, "The contact now has an ID.");
@ -1021,10 +1006,10 @@ var steps = [
},
function () {
ok(true, "Retrieving all contacts");
req = mozContacts.find({sortBy: "familyName"});
req = mozContacts.find({sortBy: 'FamilyName',})
req.onsuccess = function () {
is(req.result.length, 2, "Found exactly 2 contact.");
checkContacts(req.result[1], properties1);
checkContacts(properties2, req.result[1]);
next();
}
req.onerror = onFailure;
@ -1101,14 +1086,16 @@ var steps = [
function () {
ok(true, "Adding 20 contacts");
for (var i=0; i<19; i++) {
createResult1 = new mozContact(properties1);
createResult1 = new mozContact();
createResult1.init(properties1);
req = mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
};
req.onerror = onFailure;
};
createResult1 = new mozContact(properties1);
createResult1 = new mozContact();
createResult1.init(properties1);
req = mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
@ -1119,7 +1106,7 @@ var steps = [
},
function () {
ok(true, "Retrieving all contacts");
req = mozContacts.find(defaultOptions);
req = mozContacts.find({});
req.onsuccess = function () {
is(req.result.length, 20, "20 Entries.");
next();
@ -1165,10 +1152,11 @@ var steps = [
ok(true, "Retrieving all contacts3");
var options = {filterBy: ["givenName", "tel", "email"],
filterOp: "startsWith",
filterValue: properties1.givenName[0].substring(0, 4)};
filterValue: properties1.givenName[0].substring(0, 4),
filterLimit: 15 };
req = mozContacts.find(options);
req.onsuccess = function () {
is(req.result.length, 20, "20 Entries.");
is(req.result.length, 15, "15 Entries.");
checkContacts(createResult1, req.result[10]);
next();
}
@ -1185,7 +1173,8 @@ var steps = [
},
function () {
ok(true, "Testing clone contact");
createResult1 = new mozContact(properties1);
createResult1 = new mozContact();
createResult1.init(properties1);
req = mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
@ -1198,14 +1187,14 @@ var steps = [
ok(true, "Testing clone contact2");
var cloned = new mozContact(createResult1);
ok(cloned.id != createResult1.id, "Cloned contact has new ID");
cloned.email = [{value: "new email!"}];
cloned.givenName = ["Tom"];
cloned.email = {value: "new email!"};
cloned.givenName = "Tom";
req = mozContacts.save(cloned);
req.onsuccess = function () {
ok(cloned.id, "The contact now has an ID.");
is(cloned.email[0].value, "new email!", "Same Email");
isnot(createResult1.email[0].value, cloned.email[0].value, "Clone has different email");
is(cloned.givenName, "Tom", "New Name");
ok(cloned.email[0].value == "new email!", "Same Email");
ok(createResult1.email != cloned.email, "Clone has different email");
ok(cloned.givenName == "Tom", "New Name");
next();
}
req.onerror = onFailure;
@ -1215,7 +1204,7 @@ var steps = [
var options = {filterBy: ["givenName"],
filterOp: "startsWith",
filterValue: properties2.givenName[0].substring(0, 4)};
req = mozContacts.find(defaultOptions);
req = mozContacts.find({});
req.onsuccess = function () {
is(req.result.length, 2, "2 Entries.");
next();
@ -1224,14 +1213,11 @@ var steps = [
},
function () {
ok(true, "Search with redundant fields should only return 1 contact");
createResult1 = new mozContact({name: ["XXX"],
givenName: ["XXX"],
email: [{value: "XXX"}],
tel: [{value: "XXX"}]
});
createResult1 = new mozContact();
createResult1.init({name: "XXX", givenName: "XXX", email: [{value: "XXX"}], tel: {value: "XXX"}});
req = mozContacts.save(createResult1);
req.onsuccess = function() {
var options = {filterBy: ["givenName", "familyName"],
var options = {filterBy: [],
filterOp: "equals",
filterValue: "XXX"};
var req2 = mozContacts.find(options);
@ -1254,7 +1240,8 @@ var steps = [
},
function () {
ok(true, "Test sorting");
createResult1 = new mozContact(c3);
createResult1 = new mozContact();
createResult1.init(c3);
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
@ -1265,7 +1252,8 @@ var steps = [
},
function () {
ok(true, "Test sorting");
createResult1 = new mozContact(c2);
createResult1 = new mozContact();
createResult1.init(c2);
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
@ -1276,7 +1264,8 @@ var steps = [
},
function () {
ok(true, "Test sorting");
createResult1 = new mozContact(c4);
createResult1 = new mozContact();
createResult1.init(c4);
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
@ -1287,7 +1276,8 @@ var steps = [
},
function () {
ok(true, "Test sorting");
createResult1 = new mozContact(c1);
createResult1 = new mozContact();
createResult1.init(c1);
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
@ -1328,7 +1318,8 @@ var steps = [
},
function () {
ok(true, "Test sorting");
createResult1 = new mozContact(c5);
createResult1 = new mozContact();
createResult1.init(c5);
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
@ -1355,16 +1346,17 @@ var steps = [
},
function () {
ok(true, "Don't allow to add custom fields");
createResult1 = new mozContact({givenName: ["customTest"], yyy: "XXX"});
createResult1 = new mozContact();
createResult1.init({givenName: "customTest", yyy: "XXX"});
req = mozContacts.save(createResult1);
req.onsuccess = function() {
var options = {filterBy: ["givenName"],
var options = {filterBy: [],
filterOp: "equals",
filterValue: "customTest"};
var req2 = mozContacts.find(options);
req2.onsuccess = function() {
is(req2.result.length, 1, "1 Entry");
checkStrArray(req2.result[0].givenName, ["customTest"], "same name");
checkStrArray(req2.result.givenName, "customTest", "same name");
ok(req2.result.yyy === undefined, "custom property undefined");
next();
}
@ -1383,7 +1375,8 @@ var steps = [
},
function () {
ok(true, "Test sorting");
createResult1 = new mozContact(c7);
createResult1 = new mozContact();
createResult1.init(c7);
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
@ -1394,7 +1387,8 @@ var steps = [
},
function () {
ok(true, "Test sorting");
createResult1 = new mozContact(c6);
createResult1 = new mozContact();
createResult1.init(c6);
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
@ -1405,7 +1399,8 @@ var steps = [
},
function () {
ok(true, "Test sorting");
createResult1 = new mozContact(c8);
createResult1 = new mozContact();
createResult1.init(c8);
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
@ -1435,7 +1430,7 @@ var steps = [
},
function () {
ok(true, "Deleting database");
req = mozContacts.clear();
req = mozContacts.clear()
req.onsuccess = function () {
ok(true, "Deleted the database");
next();
@ -1444,7 +1439,8 @@ var steps = [
},
function () {
ok(true, "Adding a new contact with properties2");
createResult2 = new mozContact(properties2);
createResult2 = new mozContact();
createResult2.init(properties2);
req = mozContacts.save(createResult2);
req.onsuccess = function () {
ok(createResult2.id, "The contact now has an ID.");
@ -1489,8 +1485,9 @@ var steps = [
req.onerror = onFailure;
},
function () {
ok(true, "Adding contact for category search");
createResult1 = new mozContact({name: ["5"], givenName: ["5"]});
ok(true, "Adding empty contact");
createResult1 = new mozContact();
createResult1.init({name: "5", givenName: "5"});
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
@ -1525,10 +1522,20 @@ var steps = [
ok(true, "Adding contact with invalid data");
var input = document.createElement("input");
var obj = {
name: [1, 2],
familyName: 3,
givenName: 4,
honorificPrefix: [],
honorificSuffix: [{foo: "bar"}],
honorificSuffix: {foo: "bar"},
additionalName: 7,
nickname: [8, 9],
org: [10, 11],
jobTitle: [12, 13],
note: 14,
category: [15, 16],
sex: 17,
genderIdentity: 18,
key: 4,
email: input,
adr: input,
tel: input,
@ -1546,12 +1553,12 @@ var steps = [
}
}
})());
createResult1 = new mozContact(obj);
createResult1 = new mozContact();
createResult1.init(obj);
req = mozContacts.save(createResult1);
req.onsuccess = function () {
checkContacts(createResult1, {
honorificPrefix: ["string"],
honorificSuffix: ["[object Object]"],
honorificPrefix: "string",
sex: "17",
genderIdentity: "18"
});
@ -1560,7 +1567,8 @@ var steps = [
},
function () {
ok(true, "Adding contact with no number but carrier");
createResult1 = new mozContact({ tel: [{type: ["home"], carrier: "myCarrier"} ] });
createResult1 = new mozContact();
createResult1.init({ tel: [{type: ["home"], carrier: "myCarrier"} ] });
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
@ -1570,7 +1578,8 @@ var steps = [
},
function () {
ok(true, "Adding contact with email but no value");
createResult1 = new mozContact({ email: [{type: ["home"]}] });
createResult1 = new mozContact();
createResult1.init({ email: [{type: ["home"]}] });
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
@ -1580,7 +1589,8 @@ var steps = [
},
function () {
ok(true, "Testing numbersOnly search 1");
createResult1 = new mozContact({ name: ["aaaaaaaaa"], givenName: ["aaaaaaaaa"], tel: [{ value: "1234567890"}]});
createResult1 = new mozContact();
createResult1.init({ name: ["aaaaaaaaa"], givenName: ["aaaaaaaaa"], tel: [{ value: "1234567890"}]});
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
@ -1660,10 +1670,17 @@ var steps = [
},
function() {
ok(true, "Test setting array properties to scalar values")
const DOMStrings = ["name","honorificPrefix","givenName","additionalName",
"familyName", "honorificSuffix","nickname","category",
"org","jobTitle","note"];
const FIELDS = ["email","url","adr","tel","impp"];
createResult1 = new mozContact();
for (var prop of DOMStrings) {
createResult1[prop] = "foo";
ok(Array.isArray(createResult1[prop]), prop + " is array");
}
for (var prop of FIELDS) {
createResult1[prop] = {type: ["foo"]};
createResult1[prop] = {type: "foo"};
ok(Array.isArray(createResult1[prop]), prop + " is array");
}
next();

View File

@ -90,14 +90,14 @@ var randomBlob = getRandomBlob(1024);
var randomBlob2 = getRandomBlob(1024);
var properties1 = {
name: ["xTestname1"],
givenName: ["xTestname1"],
name: "xTestname1",
givenName: "xTestname1",
photo: [randomBlob]
};
var properties2 = {
name: ["yTestname2"],
givenName: ["yTestname2"],
name: "yTestname2",
givenName: "yTestname2",
photo: [randomBlob, randomBlob2]
};
@ -177,7 +177,8 @@ var steps = [
},
function () {
ok(true, "Adding contact with photo");
createResult1 = new mozContact(properties1);
createResult1 = new mozContact();
createResult1.init(properties1);
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
@ -190,7 +191,7 @@ var steps = [
ok(true, "Retrieving by substring");
var options = {filterBy: ["givenName"],
filterOp: "startsWith",
filterValue: properties1.givenName[0].substring(0,3)};
filterValue: properties1.givenName.substring(0,3)};
req = mozContacts.find(options);
req.onsuccess = function () {
ok(req.result.length == 1, "Found exactly 1 contact.");
@ -202,7 +203,8 @@ var steps = [
},
function () {
ok(true, "Adding contact with 2 photos");
createResult1 = new mozContact(properties2);
createResult1 = new mozContact();
createResult1.init(properties2);
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
@ -215,7 +217,7 @@ var steps = [
ok(true, "Retrieving by substring");
var options = {filterBy: ["givenName"],
filterOp: "startsWith",
filterValue: properties2.givenName[0].substring(0,3)};
filterValue: properties2.givenName.substring(0,3)};
req = mozContacts.find(options);
req.onsuccess = function () {
ok(req.result.length == 1, "Found exactly 1 contact.");
@ -225,6 +227,58 @@ var steps = [
};
req.onerror = onFailure;
},
function () {
ok(true, "Adding photo as String");
createResult1 = new mozContact();
createResult1.init({givenName: "asdf", photo: ["xyz"]});
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
sample_id1 = createResult1.id;
is(createResult1.photo, null, "No photo")
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Adding photo as String");
createResult1 = new mozContact();
createResult1.init({givenName: "jkl", photo: "xyz"});
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
is(createResult1.photo, null, "No photo")
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Retrieving by substring");
var options = {filterBy: ["givenName"],
filterOp: "startsWith",
filterValue: "asdf"};
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");
is(findResult1.photo, null, "No photo");
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Adding photo as Object");
createResult1 = new mozContact();
createResult1.init({photo: [{}]});
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
is(createResult1.photo, null, "No photo")
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Deleting database");
req = mozContacts.clear()

View File

@ -36,7 +36,7 @@ var androidVersion = SpecialPowers.Cc['@mozilla.org/system-info;1']
.getProperty('version');
let adr1 = {
type: ["work"],
type: "work",
streetAddress: "street 1",
locality: "locality 1",
region: "region 1",
@ -48,9 +48,9 @@ let properties1 = {
name: ["Testname1 TestFamilyName"],
familyName: ["TestFamilyName","Wagner"],
givenName: ["Test1","Test2"],
nickname: ["nicktest"],
nickname: "nicktest",
tel: [{type: ["work"], value: "123456", carrier: "testCarrier"} , {type: ["home", "fax"], value: "+9-876-5432"}],
adr: [adr1],
adr: adr1,
email: [{type: ["work"], value: "x@y.com"}]
};
@ -58,137 +58,102 @@ function onFailure() {
ok(false, "in on Failure!");
next();
}
function checkStr(str1, str2, msg) {
if (str1 ^ str2) {
ok(false, "Expected both strings to be either present or absent");
return;
// comparing /[null(,null)+]/ and undefined should pass
function nonNull(e) {
return e != null;
}
is(str1, str2, msg);
}
function checkStrArray(str1, str2, msg) {
function normalize_falsy(k, v) {
if (!v || v == "null" || v == "undefined") {
return "";
}
return v;
if ((Array.isArray(str1) && str1.filter(nonNull).length == 0 && str2 == undefined)
||(Array.isArray(str2) && str2.filter(nonNull).length == 0 && str1 == undefined)) {
ok(true, msg);
} else if (str1) {
is(JSON.stringify(typeof str1 == "string" ? [str1] : str1), JSON.stringify(typeof str2 == "string" ? [str2] : str2), msg);
}
ise(JSON.stringify(str1, normalize_falsy), JSON.stringify(str2, normalize_falsy), msg);
}
function checkPref(pref1, pref2) {
// If on Android treat one preference as 0 and the other as undefined as matching
if (isAndroid) {
if ((!pref1 && pref2 == undefined) || (pref1 == undefined && !pref2)) {
pref1 = false;
pref2 = false;
}
}
ise(!!pref1, !!pref2, "Same pref");
}
function checkAddress(adr1, adr2) {
if (adr1 ^ adr2) {
ok(false, "Expected both adrs to be either present or absent");
return;
}
checkStrArray(adr1.type, adr2.type, "Same type");
checkStrArray(adr1.streetAddress, adr2.streetAddress, "Same streetAddress");
checkStrArray(adr1.locality, adr2.locality, "Same locality");
checkStrArray(adr1.region, adr2.region, "Same region");
checkStrArray(adr1.postalCode, adr2.postalCode, "Same postalCode");
checkStrArray(adr1.countryName, adr2.countryName, "Same countryName");
checkPref(adr1.pref, adr2.pref);
}
function checkField(field1, field2) {
if (field1 ^ field2) {
ok(false, "Expected both fields to be either present or absent");
return;
}
checkStrArray(field1.type, field2.type, "Same type");
checkStrArray(field1.value, field2.value, "Same value");
checkPref(field1.pref, field2.pref);
checkStr(adr1.type, adr2.type, "Same type");
checkStr(adr1.streetAddress, adr2.streetAddress, "Same streetAddress");
checkStr(adr1.locality, adr2.locality, "Same locality");
checkStr(adr1.region, adr2.region, "Same region");
checkStr(adr1.postalCode, adr2.postalCode, "Same postalCode");
checkStr(adr1.countryName, adr2.countryName, "Same countryName");
}
function checkTel(tel1, tel2) {
if (tel1 ^ tel2) {
ok(false, "Expected both tels to be either present or absent");
return;
}
checkField(tel1, tel2);
checkStrArray(tel1.carrier, tel2.carrier, "Same carrier");
checkStr(tel1.type, tel2.type, "Same type");
checkStr(tel1.value, tel2.value, "Same value");
checkStr(tel1.carrier, tel2.carrier, "Same carrier");
}
function checkCategory(category1, category2) {
// Android adds contacts to the a default category. This should be removed from the
// results before comparing them
if (isAndroid) {
category1 = removeAndroidDefaultCategory(category1);
category2 = removeAndroidDefaultCategory(category2);
}
checkStrArray(category1, category2, "Same Category")
}
function removeAndroidDefaultCategory(category) {
if (!category) {
return category;
}
var result = [];
for (var i of category) {
// Some devices may return the full group name (prefixed with "System Group: ")
if (i != "My Contacts" && i != "System Group: My Contacts") {
result.push(i);
}
}
return result;
}
function checkArrayField(array1, array2, func, msg) {
if (!!array1 ^ !!array2) {
ok(false, "Expected both arrays to be either present or absent");
return;
}
if (!array1 && !array2) {
ok(true, msg);
return;
}
ise(array1.length, array2.length, "Same length");
for (var i = 0; i < array1.length; ++i) {
func(array1[i], array2[i], msg);
}
function checkField(field1, field2) {
checkStr(field1.type, field2.type, "Same type");
checkStr(field1.value, field2.value, "Same value");
}
function checkContacts(contact1, contact2) {
if (!!contact1 ^ !!contact2) {
ok(false, "Expected both contacts to be either present or absent");
return;
}
checkStrArray(contact1.name, contact2.name, "Same name");
checkStrArray(contact1.honorificPrefix, contact2.honorificPrefix, "Same honorificPrefix");
checkStrArray(contact1.givenName, contact2.givenName, "Same givenName");
checkStrArray(contact1.additionalName, contact2.additionalName, "Same additionalName");
checkStrArray(contact1.familyName, contact2.familyName, "Same familyName");
checkStrArray(contact1.honorificSuffix, contact2.honorificSuffix, "Same honorificSuffix");
checkStrArray(contact1.nickname, contact2.nickname, "Same nickname");
checkCategory(contact1.category, contact2.category);
checkStrArray(contact1.org, contact2.org, "Same org");
checkStrArray(contact1.jobTitle, contact2.jobTitle, "Same jobTitle");
checkStr(contact1.name, contact2.name, "Same name");
checkStr(contact1.honorificPrefix, contact2.honorificPrefix, "Same honorificPrefix");
checkStr(contact1.givenName, contact2.givenName, "Same givenName");
checkStr(contact1.additionalName, contact2.additionalName, "Same additionalName");
checkStr(contact1.familyName, contact2.familyName, "Same familyName");
checkStr(contact1.honorificSuffix, contact2.honorificSuffix, "Same honorificSuffix");
checkStr(contact1.nickname, contact2.nickname, "Same nickname");
checkStr(contact1.category, contact2.category, "Same category");
checkStr(contact1.org, contact2.org, "Same org");
checkStr(contact1.jobTitle, contact2.jobTitle, "Same jobTitle");
is(contact1.bday ? contact1.bday.valueOf() : null, contact2.bday ? contact2.bday.valueOf() : null, "Same birthday");
checkStrArray(contact1.note, contact2.note, "Same note");
checkStr(contact1.note, contact2.note, "Same note");
is(contact1.anniversary ? contact1.anniversary.valueOf() : null , contact2.anniversary ? contact2.anniversary.valueOf() : null, "Same anniversary");
checkStr(contact1.sex, contact2.sex, "Same sex");
checkStr(contact1.genderIdentity, contact2.genderIdentity, "Same genderIdentity");
checkStrArray(contact1.key, contact2.key, "Same key");
is(contact1.sex, contact2.sex, "Same sex");
is(contact1.genderIdentity, contact2.genderIdentity, "Same genderIdentity");
checkArrayField(contact1.adr, contact2.adr, checkAddress, "Same adr");
checkArrayField(contact1.tel, contact2.tel, checkTel, "Same tel");
checkArrayField(contact1.email, contact2.email, checkField, "Same email");
checkArrayField(contact1.url, contact2.url, checkField, "Same url");
checkArrayField(contact1.impp, contact2.impp, checkField, "Same impp");
for (let i in contact1.email) {
if (contact1.email) {
ok(contact2.email != null, "conatct2.email exists");
}
if (contact2.email) {
ok(contact1.email != null, "conatct1.email exists");
}
checkField(contact1.email[i], contact2.email[i]);
}
for (let i in contact1.adr) {
if (contact1.adr) {
ok(contact2.adr != null, "conatct2.adr exists");
}
if (contact2.adr) {
ok(contact1.adr != null, "conatct1.adr exists");
}
checkAddress(contact1.adr[i], contact2.adr[i]);
}
for (let i in contact1.tel) {
if (contact1.tel) {
ok(contact2.tel != null, "conatct2.tel exists");
}
if (contact2.tel) {
ok(contact1.tel != null, "conatct1.tel exists");
}
checkTel(contact1.tel[i], contact2.tel[i]);
}
for (let i in contact1.url) {
if (contact1.url) {
ok(contact2.url != null, "conatct2.url exists");
}
if (contact2.url) {
ok(contact1.url != null, "conatct1.url exists");
}
checkField(contact1.url[i], contact2.url[i]);
}
for (let i in contact1.impp) {
if (contact1.impp) {
ok(contact2.impp != null, "conatct2.impp exists");
}
if (contact2.impp) {
ok(contact1.impp != null, "conatct1.impp exists");
}
checkField(contact1.impp[i], contact2.impp[i]);
}
}
function clearDatabase() {
@ -204,22 +169,24 @@ function clearDatabase() {
function addContacts() {
ok(true, "Adding 40 contacts");
for (let i = 0; i < 39; ++i) {
createResult1 = new mozContact();
properties1.familyName[0] = "Testname" + (i < 10 ? "0" + i : i);
properties1.name = [properties1.givenName[0] + " " + properties1.familyName[0]];
createResult1 = new mozContact(properties1);
properties1.name = properties1.givenName[0] + " " + properties1.familyName[0];
createResult1.init(properties1);
req = mozContacts.save(createResult1);
req.onsuccess = function() {
ok(createResult1.id, "The contact now has an ID.");
};
req.onerror = onFailure;
};
createResult1 = new mozContact();
properties1.familyName[0] = "Testname39";
properties1.name = [properties1.givenName[0] + " Testname39"];
createResult1 = new mozContact(properties1);
properties1.name = properties1.givenName[0] + " Testname39";
createResult1.init(properties1);
req = mozContacts.save(createResult1);
req.onsuccess = function() {
ok(createResult1.id, "The contact now has an ID.");
checkStrArray(createResult1.name, properties1.name, "Same Name");
ok(createResult1.name == properties1.name, "Same Name");
next();
};
req.onerror = onFailure;
@ -235,7 +202,6 @@ function getOne(msg) {
return function() {
ok(true, msg || "Retrieving one contact with getAll");
req = mozContacts.getAll({});
let count = 0;
req.onsuccess = function(event) {
ok(true, "on success");
@ -280,14 +246,11 @@ function getAll(msg) {
}
let steps = [
function start() {
SpecialPowers.Cc["@mozilla.org/tools/profiler;1"].getService(SpecialPowers.Ci.nsIProfiler).AddMarker("GETALL_START");
next();
},
clearDatabase,
function() {
// add a contact
createResult1 = new mozContact({});
createResult1 = new mozContact();
createResult1.init({});
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function() {
next();
@ -478,7 +441,6 @@ let steps = [
function() {
ok(true, "all done!\n");
SpecialPowers.Cc["@mozilla.org/tools/profiler;1"].getService(SpecialPowers.Ci.nsIProfiler).AddMarker("GETALL_END");
SimpleTest.finish();
}
];

View File

@ -51,13 +51,13 @@ var number2 = {
};
var properties1 = {
name: ["Testname1"],
name: "Testname1",
tel: [{type: ["work"], value: number1.local, carrier: "testCarrier"} , {type: ["home", "fax"], value: number2.local}],
};
var shortNumber = "888";
var properties2 = {
name: ["Testname2"],
name: "Testname2",
tel: [{type: ["work"], value: shortNumber, carrier: "testCarrier"}]
};
@ -81,7 +81,8 @@ var steps = [
},
function () {
ok(true, "Adding a new contact1");
createResult1 = new mozContact(properties1);
createResult1 = new mozContact();
createResult1.init(properties1);
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
@ -92,7 +93,8 @@ var steps = [
},
function () {
ok(true, "Adding a new contact2");
var createResult2 = new mozContact(properties2);
var createResult2 = new mozContact();
createResult2.init(properties2);
req = navigator.mozContacts.save(createResult2);
req.onsuccess = function () {
ok(createResult2.id, "The contact now has an ID.");

View File

@ -82,7 +82,8 @@ var steps = [
},
function () {
ok(true, "Adding contact");
createResult1 = new mozContact(prop);
createResult1 = new mozContact();
createResult1.init(prop);
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
@ -165,7 +166,8 @@ var steps = [
},
function () {
ok(true, "Adding contact");
createResult1 = new mozContact(prop2);
createResult1 = new mozContact();
createResult1.init(prop2);
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
@ -257,7 +259,8 @@ var steps = [
},
function () {
ok(true, "Adding contact");
createResult1 = new mozContact(prop3);
createResult1 = new mozContact();
createResult1.init(prop3);
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
@ -286,7 +289,8 @@ var steps = [
},
function () {
ok(true, "Adding contact");
createResult1 = new mozContact(prop4);
createResult1 = new mozContact();
createResult1.init(prop4);
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");

View File

@ -73,7 +73,8 @@ var steps = [
},
function () {
ok(true, "Adding contact");
createResult1 = new mozContact(prop);
createResult1 = new mozContact();
createResult1.init(prop);
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
@ -111,7 +112,8 @@ var steps = [
},
function () {
ok(true, "Adding contact");
createResult1 = new mozContact(prop2);
createResult1 = new mozContact();
createResult1.init(prop2);
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");

View File

@ -5,6 +5,7 @@
#include "nsIDOMEventTarget.idl"
#include "SimToolKit.idl"
interface nsIDOMContact;
interface nsIDOMDOMRequest;
interface nsIDOMEventListener;
interface nsIDOMMozIccInfo;
@ -506,7 +507,7 @@ interface nsIDOMMozIccManager : nsIDOMEventTarget
* PIN2 is only required for 'fdn'.
*/
nsIDOMDOMRequest updateContact(in DOMString contactType,
in nsISupports contact,
in nsIDOMContact contact,
[optional] in DOMString pin2);
// End of UICC Phonebook Interfaces.

View File

@ -4,6 +4,7 @@
#include "nsISupports.idl"
interface nsIDOMContact;
interface nsIDOMDOMRequest;
interface nsIDOMMozIccInfo;
interface nsIDOMWindow;
@ -73,7 +74,7 @@ interface nsIIccProvider : nsISupports
nsIDOMDOMRequest updateContact(in nsIDOMWindow window,
in DOMString contactType,
in nsISupports contact,
in nsIDOMContact contact,
in DOMString pin2);
/**

View File

@ -235,7 +235,7 @@ IccManager::ReadContacts(const nsAString& aContactType, nsIDOMDOMRequest** aRequ
NS_IMETHODIMP
IccManager::UpdateContact(const nsAString& aContactType,
nsISupports* aContact,
nsIDOMContact* aContact,
const nsAString& aPin2,
nsIDOMDOMRequest** aRequest)
{

View File

@ -15,19 +15,19 @@ function testReadContacts(type) {
is(Array.isArray(contacts), true);
is(contacts[0].name[0], "Mozilla");
is(contacts[0].name, "Mozilla");
is(contacts[0].tel[0].value, "15555218201");
is(contacts[0].id, "890141032111185107201");
is(contacts[1].name[0], "Saßê黃");
is(contacts[1].name, "Saßê黃");
is(contacts[1].tel[0].value, "15555218202");
is(contacts[1].id, "890141032111185107202");
is(contacts[2].name[0], "Fire 火");
is(contacts[2].name, "Fire 火");
is(contacts[2].tel[0].value, "15555218203");
is(contacts[2].id, "890141032111185107203");
is(contacts[3].name[0], "Huang 黃");
is(contacts[3].name, "Huang 黃");
is(contacts[3].tel[0].value, "15555218204");
is(contacts[3].id, "890141032111185107204");
@ -41,8 +41,10 @@ function testReadContacts(type) {
};
function testAddContact(type, pin2) {
let contact = new mozContact({
name: ["add"],
let contact = new mozContact();
contact.init({
name: "add",
tel: [{value: "0912345678"}],
email:[]
});
@ -60,7 +62,7 @@ function testAddContact(type, pin2) {
// There are 4 SIM contacts which are harded in emulator
is(contacts.length, 5);
is(contacts[4].name[0], "add");
is(contacts[4].name, "add");
is(contacts[4].tel[0].value, "0912345678");
runNextTest();

View File

@ -0,0 +1,16 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
XPIDL_SOURCES += [
'nsIContactProperties.idl',
'nsIDOMContactManager.idl',
'nsIDOMMozContactChangeEvent.idl',
]
XPIDL_MODULE = 'dom_contacts'
MODULE = 'dom'

View File

@ -0,0 +1,74 @@
/* 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/. */
#include "domstubs.idl"
[scriptable, uuid(9cbfa81c-bcab-4ca9-b0d2-f4318f295e33)]
interface nsIContactAddress : nsISupports
{
attribute DOMString type;
attribute boolean pref; // false = no pref, true = preferred (vCard3 TYPE:PREF; vCard4 PREF:1)
attribute DOMString streetAddress;
attribute DOMString locality;
attribute DOMString region;
attribute DOMString postalCode;
attribute DOMString countryName;
};
[scriptable, uuid(ad19a543-69e4-44f0-adfa-37c011556bc1)]
interface nsIContactField : nsISupports
{
attribute jsval type; // DOMString[], "home", "work", etc.
attribute DOMString value;
attribute boolean pref; // false = no pref, true = preferred (vCard3 TYPE:PREF; vCard4 PREF:1)
};
[scriptable, uuid(4d42c5a9-ea5d-4102-80c3-40cc986367ca)]
interface nsIContactTelField : nsIContactField
{
attribute DOMString carrier;
};
[scriptable, uuid(0a5b1fab-70da-46dd-b902-619904d920c2)]
interface nsIContactFindSortOptions : nsISupports
{
attribute DOMString sortBy; // "givenName" or "familyName"
attribute DOMString sortOrder; // e.g. "descending"
};
[scriptable, uuid(28ce07d0-45d9-4b7a-8843-521df4edd8bc)]
interface nsIContactFindOptions : nsIContactFindSortOptions
{
attribute DOMString filterValue; // e.g. "Tom"
attribute DOMString filterOp; // e.g. "startsWith"
attribute jsval filterBy; // DOMString[], e.g. ["givenName", "nickname"]
attribute unsigned long filterLimit;
};
[scriptable, uuid(35ad8a4e-9486-44b6-883d-550f14635e49)]
interface nsIContactProperties : nsISupports
{
attribute jsval name; // DOMString[]
attribute jsval honorificPrefix; // DOMString[]
attribute jsval givenName; // DOMString[]
attribute jsval additionalName; // DOMString[]
attribute jsval familyName; // DOMString[]
attribute jsval honorificSuffix; // DOMString[]
attribute jsval nickname; // DOMString[]
attribute jsval email; // ContactField[]
attribute jsval photo; // nsIDOMBlob[]
attribute jsval url; // ContactField[]
attribute jsval category; // DOMString[]
attribute jsval adr; // ContactAddress[]
attribute jsval tel; // ContactTelField[]
attribute jsval org; // DOMString[]
attribute jsval jobTitle; // DOMString[]
attribute jsval bday; // Date
attribute jsval note; // DOMString[]
attribute jsval impp; // ContactField[]
attribute jsval anniversary; // Date
attribute DOMString sex; // DOMString
attribute DOMString genderIdentity; // DOMString
attribute jsval key; // DOMString[]
};

View File

@ -0,0 +1,41 @@
/* 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/. */
#include "domstubs.idl"
#include "nsIContactProperties.idl"
#include "nsIDOMEventTarget.idl"
interface nsIArray;
interface nsIDOMDOMRequest;
interface nsIDOMDOMCursor;
[scriptable, uuid(72a5ee28-81d8-4af8-90b3-ae935396cc66)]
interface nsIDOMContact : nsIContactProperties
{
attribute DOMString id;
readonly attribute jsval published;
readonly attribute jsval updated;
void init(in nsIContactProperties properties); // Workaround BUG 723206
};
[scriptable, uuid(8beb3a66-d70a-4111-b216-b8e995ad3aff)]
interface nsIDOMContactManager : nsISupports
{
nsIDOMDOMRequest find(in nsIContactFindOptions options);
nsIDOMDOMCursor getAll(in nsIContactFindSortOptions options);
nsIDOMDOMRequest clear();
nsIDOMDOMRequest save(in nsIDOMContact contact);
nsIDOMDOMRequest remove(in nsIDOMContact contact);
attribute nsIDOMEventListener oncontactchange;
nsIDOMDOMRequest getRevision();
nsIDOMDOMRequest getCount();
};

View File

@ -0,0 +1,24 @@
/* 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/. */
#include "nsIDOMEvent.idl"
[scriptable, builtinclass, uuid(7ee758eb-9353-4ade-8715-9953ea512ee2)]
interface nsIDOMMozContactChangeEvent : nsIDOMEvent
{
readonly attribute DOMString contactID;
readonly attribute DOMString reason;
[noscript] void initMozContactChangeEvent(in DOMString aType,
in boolean aCanBubble,
in boolean aCancelable,
in DOMString aContactID,
in DOMString aReason);
};
dictionary MozContactChangeEventInit : EventInit
{
DOMString contactID;
DOMString reason;
};

View File

@ -11,6 +11,7 @@ interfaces = [
'html',
'events',
'devicestorage',
'contacts',
'settings',
'stylesheets',
'sidebar',

View File

@ -1671,6 +1671,7 @@ RILContentHelper.prototype = {
delete this._windowsMap[message.requestId];
let contacts = message.contacts;
let result = contacts.map(function(c) {
let contact = Cc["@mozilla.org/contact;1"].createInstance(Ci.nsIDOMContact);
let prop = {name: [c.alphaId], tel: [{value: c.number}]};
if (c.email) {
@ -1683,7 +1684,7 @@ RILContentHelper.prototype = {
prop.tel.push({value: c.anr[i]});
}
let contact = new window.mozContact(prop);
contact.init(prop);
contact.id = message.iccid + c.recordId;
return contact;
});

View File

@ -1,170 +0,0 @@
/* -*- 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/.
*/
[ChromeOnly, Constructor, JSImplementation="@mozilla.org/contactAddress;1"]
interface ContactAddress {
attribute object? type; // DOMString[]
attribute DOMString? streetAddress;
attribute DOMString? locality;
attribute DOMString? region;
attribute DOMString? postalCode;
attribute DOMString? countryName;
attribute boolean? pref;
[ChromeOnly]
void initialize(optional sequence<DOMString>? type,
optional DOMString streetAddress,
optional DOMString locality,
optional DOMString region,
optional DOMString postalCode,
optional DOMString countryName,
optional boolean pref);
};
dictionary ContactAddressInit {
sequence<DOMString>? type;
DOMString? streetAddress;
DOMString? locality;
DOMString? region;
DOMString? postalCode;
DOMString? countryName;
boolean? pref;
};
[ChromeOnly, Constructor, JSImplementation="@mozilla.org/contactField;1"]
interface ContactField {
attribute object? type; // DOMString[]
attribute DOMString? value;
attribute boolean? pref;
[ChromeOnly]
void initialize(optional sequence<DOMString>? type,
optional DOMString value,
optional boolean pref);
};
dictionary ContactFieldInit {
sequence<DOMString>? type;
DOMString? value;
boolean? pref;
};
[ChromeOnly, Constructor, JSImplementation="@mozilla.org/contactTelField;1"]
interface ContactTelField : ContactField {
attribute DOMString? carrier;
[ChromeOnly]
void initialize(optional sequence<DOMString>? type,
optional DOMString value,
optional DOMString? carrier,
optional boolean pref);
};
dictionary ContactTelFieldInit : ContactFieldInit {
DOMString? carrier;
};
dictionary ContactProperties {
Date? bday;
Date? anniversary;
DOMString? sex;
DOMString? genderIdentity;
sequence<Blob>? photo;
sequence<ContactAddressInit>? adr;
sequence<ContactFieldInit>? email;
sequence<ContactFieldInit>? url;
sequence<ContactFieldInit>? impp;
sequence<ContactTelFieldInit>? tel;
sequence<DOMString>? name;
sequence<DOMString>? honorificPrefix;
sequence<DOMString>? givenName;
sequence<DOMString>? additionalName;
sequence<DOMString>? familyName;
sequence<DOMString>? honorificSuffix;
sequence<DOMString>? nickname;
sequence<DOMString>? category;
sequence<DOMString>? org;
sequence<DOMString>? jobTitle;
sequence<DOMString>? note;
sequence<DOMString>? key;
};
[Constructor(optional ContactProperties properties),
JSImplementation="@mozilla.org/contact;1"]
interface mozContact {
attribute DOMString id;
readonly attribute Date? published;
readonly attribute Date? updated;
attribute Date? bday;
attribute Date? anniversary;
attribute DOMString? sex;
attribute DOMString? genderIdentity;
attribute object? photo;
attribute object? adr;
attribute object? email;
attribute object? url;
attribute object? impp;
attribute object? tel;
attribute object? name;
attribute object? honorificPrefix;
attribute object? givenName;
attribute object? additionalName;
attribute object? familyName;
attribute object? honorificSuffix;
attribute object? nickname;
attribute object? category;
attribute object? org;
attribute object? jobTitle;
attribute object? note;
attribute object? key;
[ChromeOnly]
void setMetadata(DOMString id, Date? published, Date? updated);
jsonifier;
};
dictionary ContactFindSortOptions {
DOMString sortBy; // "givenName" or "familyName"
DOMString sortOrder = "ascending"; // e.g. "descending"
};
dictionary ContactFindOptions : ContactFindSortOptions {
DOMString filterValue; // e.g. "Tom"
DOMString filterOp; // e.g. "startsWith"
any filterBy; // e.g. ["givenName", "nickname"]
unsigned long filterLimit = 0;
};
[NoInterfaceObject, NavigatorProperty="mozContacts",
JSImplementation="@mozilla.org/contactManager;1"]
interface ContactManager : EventTarget {
DOMRequest find(optional ContactFindOptions options);
DOMCursor getAll(optional ContactFindSortOptions options);
DOMRequest clear();
DOMRequest save(mozContact contact);
DOMRequest remove(mozContact contact);
DOMRequest getRevision();
DOMRequest getCount();
attribute EventHandler oncontactchange;
};

View File

@ -4,7 +4,7 @@
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
[Constructor(DOMString type, optional MozContactChangeEventInit eventInitDict)]
[Constructor(DOMString type, optional MozContactChangeEventInit eventInitDict), HeaderFile="GeneratedEventClasses.h"]
interface MozContactChangeEvent : Event
{
readonly attribute DOMString? contactID;

View File

@ -53,7 +53,6 @@ WEBIDL_FILES = [
'CommandEvent.webidl',
'Comment.webidl',
'CompositionEvent.webidl',
'Contacts.webidl',
'ConvolverNode.webidl',
'Coordinates.webidl',
'CSS.webidl',
@ -471,6 +470,7 @@ WEBIDL_FILES += [
'ElementReplaceEvent.webidl',
'HashChangeEvent.webidl',
'MozApplicationEvent.webidl',
'MozContactChangeEvent.webidl',
'MozMmsEvent.webidl',
'MozSettingsEvent.webidl',
'MozSmsEvent.webidl',
@ -538,7 +538,6 @@ GENERATED_EVENTS_WEBIDL_FILES = [
'DeviceLightEvent.webidl',
'DeviceProximityEvent.webidl',
'MediaStreamEvent.webidl',
'MozContactChangeEvent.webidl',
'MozInterAppMessageEvent.webidl',
'RTCDataChannelEvent.webidl',
'RTCPeerConnectionIceEvent.webidl',

View File

@ -17,6 +17,7 @@ simple_events = [
'PopStateEvent',
'HashChangeEvent',
'CloseEvent',
'MozContactChangeEvent',
'DeviceOrientationEvent',
'MozApplicationEvent',
'SmartCardEvent',

View File

@ -214,10 +214,10 @@ public class ContactService implements GeckoEventListener {
sortBy = findOptions.optString("sortBy").toLowerCase();
sortOrder = findOptions.optString("sortOrder").toLowerCase();
if ("".equals(sortBy)) {
if ("undefined".equals(sortBy)) {
sortBy = null;
}
if ("".equals(sortOrder)) {
if ("undefined".equals(sortOrder)) {
sortOrder = "ascending";
}
@ -240,15 +240,15 @@ public class ContactService implements GeckoEventListener {
try {
final JSONObject findOptions = contactOptions.getJSONObject("findOptions");
String filterValue = findOptions.optString("filterValue");
String filterValue = findOptions.getString("filterValue");
JSONArray filterBy = findOptions.optJSONArray("filterBy");
final String filterOp = findOptions.optString("filterOp");
final String filterOp = findOptions.getString("filterOp");
final int filterLimit = findOptions.getInt("filterLimit");
final int substringMatching = findOptions.getInt("substringMatching");
// If filter value is undefined, avoid all the logic below and just return
// all available raw contact IDs
if ("".equals(filterValue) || "".equals(filterOp)) {
if ("undefined".equals(filterValue)) {
long[] allRawContactIds = getAllRawContactIds();
// Truncate the raw contacts IDs array if necessary
@ -513,7 +513,7 @@ public class ContactService implements GeckoEventListener {
String anniversary = null;
String sex = null;
String genderIdentity = null;
JSONArray key = new JSONArray();
String key = null;
// Get all the data columns
final String[] columnsToGet = getAllColumns();
@ -614,7 +614,7 @@ public class ContactService implements GeckoEventListener {
genderIdentity = cursor.getString(cursor.getColumnIndex(CUSTOM_DATA_COLUMN));
} else if (MIMETYPE_KEY.equals(mimeType)) {
key.put(cursor.getString(cursor.getColumnIndex(CUSTOM_DATA_COLUMN)));
key = cursor.getString(cursor.getColumnIndex(CUSTOM_DATA_COLUMN));
}
} catch (JSONException e) {
throw new IllegalArgumentException(e);
@ -640,17 +640,17 @@ public class ContactService implements GeckoEventListener {
contactProperties.put("url", urls);
contactProperties.put("impp", impps);
contactProperties.put("category", categories);
contactProperties.put("key", key);
putPossibleNullValueInJSONObject("bday", bday, contactProperties);
putPossibleNullValueInJSONObject("anniversary", anniversary, contactProperties);
putPossibleNullValueInJSONObject("sex", sex, contactProperties);
putPossibleNullValueInJSONObject("genderIdentity", genderIdentity, contactProperties);
putPossibleNullValueInJSONObject("key", key, contactProperties);
// Add the raw contact ID and the properties to the contact
contact.put("id", String.valueOf(rawContactId));
contact.put("updated", null);
contact.put("published", null);
contact.put("updated", "0000T00:00:00.000Z");
contact.put("published", "0000T00:00:00.000Z");
contact.put("properties", contactProperties);
} catch (JSONException e) {
throw new IllegalArgumentException(e);
@ -665,10 +665,6 @@ public class ContactService implements GeckoEventListener {
return contact;
}
private boolean bool(int integer) {
return integer != 0 ? true : false;
}
private void getGenericDataAsJSONObject(Cursor cursor, JSONArray array, final String dataColumn,
final String typeColumn, final String typeLabelColumn,
final HashMap<String, Integer> typeMap) throws JSONException {
@ -706,7 +702,7 @@ public class ContactService implements GeckoEventListener {
object.put("value", value);
types.put(type);
object.put("type", types);
object.put("pref", bool(cursor.getInt(cursor.getColumnIndex(Data.IS_SUPER_PRIMARY))));
object.put("pref", cursor.getInt(cursor.getColumnIndex(Data.IS_SUPER_PRIMARY)));
array.put(object);
}
@ -749,7 +745,7 @@ public class ContactService implements GeckoEventListener {
types.put(type);
phone.put("type", types);
phone.put("carrier", cursor.getString(cursor.getColumnIndex(CARRIER_COLUMN)));
phone.put("pref", bool(cursor.getInt(cursor.getColumnIndex(Phone.IS_SUPER_PRIMARY))));
phone.put("pref", cursor.getInt(cursor.getColumnIndex(Phone.IS_SUPER_PRIMARY)));
phones.put(phone);
}
@ -802,7 +798,7 @@ public class ContactService implements GeckoEventListener {
address.put("postalCode", postalCode);
types.put(type);
address.put("type", types);
address.put("pref", bool(cursor.getInt(cursor.getColumnIndex(StructuredPostal.IS_SUPER_PRIMARY))));
address.put("pref", cursor.getInt(cursor.getColumnIndex(StructuredPostal.IS_SUPER_PRIMARY)));
addresses.put(address);
}
@ -972,7 +968,7 @@ public class ContactService implements GeckoEventListener {
}
}
private void insertContact(final JSONObject contactProperties, final String requestID) throws JSONException {
private void insertContact(final JSONObject contactProperties, final String requestID) {
ArrayList<ContentProviderOperation> newContactOptions = new ArrayList<ContentProviderOperation>();
// Account to save the contact under
@ -1018,7 +1014,7 @@ public class ContactService implements GeckoEventListener {
new Object[] {newRawContactId, "create"});
}
private void updateContact(final JSONObject contactProperties, final long rawContactId, final String requestID) throws JSONException {
private void updateContact(final JSONObject contactProperties, final long rawContactId, final String requestID) {
// Why is updating a contact so weird and horribly inefficient? Because Android doesn't
// like multiple values for contact fields, but the Mozilla contacts API calls for this.
// This means the Android update function is essentially completely useless. Why not just
@ -1069,61 +1065,65 @@ public class ContactService implements GeckoEventListener {
new Object[] {rawContactId, "update"});
}
private List<ContentValues> getContactValues(final JSONObject contactProperties) throws JSONException {
private List<ContentValues> getContactValues(final JSONObject contactProperties) {
List<ContentValues> contactValues = new ArrayList<ContentValues>();
// Add the contact to the default group so it is shown in other apps
// like the Contacts or People app
ContentValues defaultGroupValues = new ContentValues();
defaultGroupValues.put(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE);
defaultGroupValues.put(GroupMembership.GROUP_ROW_ID, mGroupId);
contactValues.add(defaultGroupValues);
try {
// Add the contact to the default group so it is shown in other apps
// like the Contacts or People app
ContentValues defaultGroupValues = new ContentValues();
defaultGroupValues.put(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE);
defaultGroupValues.put(GroupMembership.GROUP_ROW_ID, mGroupId);
contactValues.add(defaultGroupValues);
// Create all the values that will be inserted into the new contact
getNameValues(contactProperties.optJSONArray("name"),
contactProperties.optJSONArray("givenName"),
contactProperties.optJSONArray("familyName"),
contactProperties.optJSONArray("honorificPrefix"),
contactProperties.optJSONArray("honorificSuffix"),
contactValues);
// Create all the values that will be inserted into the new contact
getNameValues(contactProperties.optJSONArray("name"),
contactProperties.optJSONArray("givenName"),
contactProperties.optJSONArray("familyName"),
contactProperties.optJSONArray("honorificPrefix"),
contactProperties.optJSONArray("honorificSuffix"),
contactValues);
getGenericValues(MIMETYPE_ADDITIONAL_NAME, CUSTOM_DATA_COLUMN,
contactProperties.optJSONArray("additionalName"), contactValues);
getGenericValues(MIMETYPE_ADDITIONAL_NAME, CUSTOM_DATA_COLUMN,
contactProperties.optJSONArray("additionalName"), contactValues);
getNicknamesValues(contactProperties.optJSONArray("nickname"), contactValues);
getNicknamesValues(contactProperties.optJSONArray("nickname"), contactValues);
getAddressesValues(contactProperties.optJSONArray("adr"), contactValues);
getAddressesValues(contactProperties.optJSONArray("adr"), contactValues);
getPhonesValues(contactProperties.optJSONArray("tel"), contactValues);
getPhonesValues(contactProperties.optJSONArray("tel"), contactValues);
getEmailsValues(contactProperties.optJSONArray("email"), contactValues);
getEmailsValues(contactProperties.optJSONArray("email"), contactValues);
//getPhotosValues(contactProperties.optJSONArray("photo"), contactValues);
//getPhotosValues(contactProperties.optJSONArray("photo"), contactValues);
getGenericValues(Organization.CONTENT_ITEM_TYPE, Organization.COMPANY,
contactProperties.optJSONArray("org"), contactValues);
getGenericValues(Organization.CONTENT_ITEM_TYPE, Organization.COMPANY,
contactProperties.optJSONArray("org"), contactValues);
getGenericValues(Organization.CONTENT_ITEM_TYPE, Organization.TITLE,
contactProperties.optJSONArray("jobTitle"), contactValues);
getGenericValues(Organization.CONTENT_ITEM_TYPE, Organization.TITLE,
contactProperties.optJSONArray("jobTitle"), contactValues);
getNotesValues(contactProperties.optJSONArray("note"), contactValues);
getNotesValues(contactProperties.optJSONArray("note"), contactValues);
getWebsitesValues(contactProperties.optJSONArray("url"), contactValues);
getWebsitesValues(contactProperties.optJSONArray("url"), contactValues);
getImsValues(contactProperties.optJSONArray("impp"), contactValues);
getImsValues(contactProperties.optJSONArray("impp"), contactValues);
getCategoriesValues(contactProperties.optJSONArray("category"), contactValues);
getCategoriesValues(contactProperties.optJSONArray("category"), contactValues);
getEventValues(contactProperties.optString("bday"), Event.TYPE_BIRTHDAY, contactValues);
getEventValues(contactProperties.optString("bday"), Event.TYPE_BIRTHDAY, contactValues);
getEventValues(contactProperties.optString("anniversary"), Event.TYPE_ANNIVERSARY, contactValues);
getEventValues(contactProperties.optString("anniversary"), Event.TYPE_ANNIVERSARY, contactValues);
getCustomMimetypeValues(contactProperties.optString("sex"), MIMETYPE_SEX, contactValues);
getCustomMimetypeValues(contactProperties.optString("sex"), MIMETYPE_SEX, contactValues);
getCustomMimetypeValues(contactProperties.optString("genderIdentity"), MIMETYPE_GENDER_IDENTITY, contactValues);
getCustomMimetypeValues(contactProperties.optString("genderIdentity"), MIMETYPE_GENDER_IDENTITY, contactValues);
getGenericValues(MIMETYPE_KEY, CUSTOM_DATA_COLUMN, contactProperties.optJSONArray("key"),
contactValues);
getGenericValues(MIMETYPE_KEY, CUSTOM_DATA_COLUMN, contactProperties.optJSONArray("key"),
contactValues);
} catch (JSONException e) {
throw new IllegalArgumentException("Unexpected or missing JSON data: " + e);
}
return contactValues;
}
@ -1239,7 +1239,7 @@ public class ContactService implements GeckoEventListener {
}
if (address.has("pref")) {
contentValues.put(Data.IS_SUPER_PRIMARY, address.getBoolean("pref") ? 1 : 0);
contentValues.put(Data.IS_SUPER_PRIMARY, address.getInt("pref"));
}
return contentValues;
@ -1263,7 +1263,7 @@ public class ContactService implements GeckoEventListener {
final int typeConstant = getPhoneType(type);
contentValues = createContentValues(Phone.CONTENT_ITEM_TYPE, phone.optString("value"),
typeConstant, type, phone.optBoolean("pref"));
typeConstant, type, phone.optInt("pref"));
if (phone.has("carrier")) {
contentValues.put(CARRIER_COLUMN, phone.optString("carrier"));
}
@ -1271,7 +1271,7 @@ public class ContactService implements GeckoEventListener {
}
} else {
contentValues = createContentValues(Phone.CONTENT_ITEM_TYPE, phone.optString("value"),
-1, null, phone.optBoolean("pref"));
-1, null, phone.optInt("pref"));
if (phone.has("carrier")) {
contentValues.put(CARRIER_COLUMN, phone.optString("carrier"));
}
@ -1299,12 +1299,12 @@ public class ContactService implements GeckoEventListener {
newContactValues.add(createContentValues(Email.CONTENT_ITEM_TYPE,
email.optString("value"),
typeConstant, type,
email.optBoolean("pref")));
email.optInt("pref")));
}
} else {
newContactValues.add(createContentValues(Email.CONTENT_ITEM_TYPE,
email.optString("value"),
-1, null, email.optBoolean("pref")));
-1, null, email.optInt("pref")));
}
}
}
@ -1349,12 +1349,12 @@ public class ContactService implements GeckoEventListener {
newContactValues.add(createContentValues(Website.CONTENT_ITEM_TYPE,
website.optString("value"),
typeConstant, type,
website.optBoolean("pref")));
website.optInt("pref")));
}
} else {
newContactValues.add(createContentValues(Website.CONTENT_ITEM_TYPE,
website.optString("value"),
-1, null, website.optBoolean("pref")));
-1, null, website.optInt("pref")));
}
}
}
@ -1378,12 +1378,12 @@ public class ContactService implements GeckoEventListener {
newContactValues.add(createContentValues(Im.CONTENT_ITEM_TYPE,
im.optString("value"),
typeConstant, type,
im.optBoolean("pref")));
im.optInt("pref")));
}
} else {
newContactValues.add(createContentValues(Im.CONTENT_ITEM_TYPE,
im.optString("value"),
-1, null, im.optBoolean("pref")));
-1, null, im.optInt("pref")));
}
}
}
@ -1463,11 +1463,11 @@ public class ContactService implements GeckoEventListener {
}
private ContentValues createContentValues(final String mimeType, final String value, final int typeConstant,
final String type, final boolean preferredValue) {
final String type, final int preferredValue) {
ContentValues contentValues = new ContentValues();
contentValues.put(Data.MIMETYPE, mimeType);
contentValues.put(Data.DATA1, value);
contentValues.put(Data.IS_SUPER_PRIMARY, preferredValue ? 1 : 0);
contentValues.put(Data.IS_SUPER_PRIMARY, preferredValue);
if (type != null) {
contentValues.put(Data.DATA2, typeConstant);

View File

@ -135,6 +135,7 @@
@BINPATH@/components/dom_camera.xpt
@BINPATH@/components/dom_canvas.xpt
@BINPATH@/components/dom_core.xpt
@BINPATH@/components/dom_contacts.xpt
@BINPATH@/components/dom_css.xpt
@BINPATH@/components/dom_devicestorage.xpt
@BINPATH@/components/dom_events.xpt

View File

@ -64,15 +64,7 @@ let ContactService = {
debug("observe: subject: " + aSubject + " topic: " + aTopic + " data: " + aData);
}
let message = JSON.parse(aData, function date_reviver(k, v) {
// The Java service sends dates as strings, so convert them to Dates before
// sending them back to the child.
if (v != null && v != "null" &&
["updated", "published", "anniversary", "bday"].indexOf(k) != -1) {
return new Date(v);
}
return v;
});
let message = JSON.parse(aData);
let requestID = message.requestID;
// The return message topic is the same as the current topic, but without the "Android:" prefix