fixed update contacts (if id is provided one needs to search for the contact) updateFromCordova moved to prototype of mozContact fields are fixed the right search is used
Project: http://git-wip-us.apache.org/repos/asf/cordova-plugin-contacts/repo Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugin-contacts/commit/f7198066 Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-contacts/tree/f7198066 Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-contacts/diff/f7198066 Branch: refs/heads/master Commit: f71980667f659b73ebcbcb47e91b9cee6a4e3743 Parents: 813d3e9 Author: Piotr Zalewa <[email protected]> Authored: Tue Dec 17 16:27:53 2013 +0100 Committer: Piotr Zalewa <[email protected]> Committed: Tue Dec 17 16:27:53 2013 +0100 ---------------------------------------------------------------------- src/firefoxos/ContactsProxy.js | 331 ++++++++++++++++++++++-------------- 1 file changed, 202 insertions(+), 129 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cordova-plugin-contacts/blob/f7198066/src/firefoxos/ContactsProxy.js ---------------------------------------------------------------------- diff --git a/src/firefoxos/ContactsProxy.js b/src/firefoxos/ContactsProxy.js index a0c57bd..b48cf14 100644 --- a/src/firefoxos/ContactsProxy.js +++ b/src/firefoxos/ContactsProxy.js @@ -29,10 +29,21 @@ var Contact = require('./Contact'); var ContactField = require('./ContactField'); +var ContactAddress = require('./ContactAddress'); var ContactName = require('./ContactName'); +// XXX: a hack to check if id is "empty". Cordova inserts a +// string "this string is supposed to be a unique identifier that will +// never show up on a device" if id is empty +function hasId(id) { + if (!id || id.indexOf(' ') >= 0) { + return false; + } + return true; +} + +mozContact.prototype.updateFromCordova = function(contact) { -function createMozillaFromCordova(contact) { function exportContactFieldArray(contactFieldArray, key) { if (!key) { key = 'value'; @@ -58,52 +69,67 @@ function createMozillaFromCordova(contact) { return arr; } - function exportPhoneNumbers(phoneNumbers) { - var mozNumbers = []; - for (var i=0; i < phoneNumbers.length; i++) { - var number = phoneNumbers[i]; - mozNumbers.push({ - type: number.type, - value: number.value, - pref: number.pref - }); + function exportContactField(data) { + var contactFields = []; + for (var i=0; i < data.length; i++) { + var item = data[i]; + if (item.value) { + var itemData = {value: item.value}; + if (item.type) { + itemData.type = [item.type]; + } + if (item.pref) { + itemData.pref = item.pref; + } + contactFields.push(itemData); + } } - return mozNumbers; - } - - // prepare mozContact object - var moz = new mozContact(); - if (contact.id) { - moz.id = contact.id; + return contactFields; } // adding simple fields [contactField, eventualMozContactField] - var arrayFields = [['givenName'], ['familyName'], ['displayName', 'name']]; - var simpleFields = [['honorificPrefix'], ['honorificSuffix'], ['nickname'], ['birthday', 'bday'], ['note']]; - j = 0; while(field = arrayFields[j++]) { + var nameFields = [['givenName'], ['familyName'], + ['honorificPrefix'], ['honorificSuffix'], + ['middleName', 'additionalName']]; + var baseArrayFields = [['displayName', 'name'], ['nickname']]; + var baseStringFields = []; + var j = 0; while(field = nameFields[j++]) { if (contact.name[field[0]]) { - moz[field[1] || field[0]] = contact.name[field[0]].split(' '); + this[field[1] || field[0]] = contact.name[field[0]].split(' '); + // console.log(field[0], contact.name[field[0]], this[field[1] || field[0]]); } } - j = 0; while(field = simpleFields[j++]) { - if (contact.name[field[0]]) { - moz[field[1] || field[0]] = contact.name[field[0]]; + j = 0; while(field = baseArrayFields[j++]) { + if (contact[field[0]]) { + this[field[1] || field[0]] = contact[field[0]].split(' '); } } + j = 0; while(field = baseStringFields[j++]) { + if (contact[field[0]]) { + this[field[1] || field[0]] = contact[field[0]]; + } + } + if (contact.birthday) { + this.bday = new Date(contact.birthday); + } if (contact.emails) { - moz.email = exportContactFieldArray(contact.emails); + var emails = exportContactField(contact.emails) + this.email = emails; } if (contact.categories) { - moz.category = exportContactFieldArray(contact.categories); + this.category = exportContactFieldArray(contact.categories); } if (contact.addresses) { - moz.adr = exportAddress(contact.addresses); + this.adr = exportAddress(contact.addresses); } if (contact.phoneNumbers) { - moz.tel = exportPhoneNumbers(contact.phoneNumbers); + this.tel = exportContactField(contact.phoneNumbers); } if (contact.organizations) { - moz.org = exportContactFieldArray(contact.organizations, 'name'); - moz.jobTitle = exportContactFieldArray(contact.organizations, 'title'); + this.org = exportContactFieldArray(contact.organizations, 'name'); + this.jobTitle = exportContactFieldArray(contact.organizations, 'title'); + } + if (contact.note) { + this.note = [contact.note]; } /* Find out how to translate these parameters // photo: Blob @@ -114,18 +140,44 @@ function createMozillaFromCordova(contact) { // genderIdentity // key */ - return moz; +} + +function createMozillaFromCordova(successCB, errorCB, contact) { + + var mozC; + // get contact if exists + if (contact.id) { + var search = navigator.mozContacts.find({ + filterBy: ['id'], filterValue: contact.id, filterOp: 'equals'}); + search.onsuccess = function() { + mozC = search.result[0]; + mozC.updateFromCordova(contact); + successCB(mozC); + }; + search.onerror = errorCB; + return; + } + + var mozC = new mozContact(); + if ('init' in mozC) { + // 1.2 and below compatibility + mozC.init(); + } + mozC.updateFromCordova(contact); + + //console.log('cordova2moz ', contact.id, contact.birthday, Date.parse(mozC.bday), mozC.bday.toDateString()); + successCB(mozC); } function createCordovaFromMozilla(moz) { - function exportPhoneNumbers(mozNumbers) { - var phoneNumbers = []; - for (var i=0; i < mozNumbers.length; i++) { - var number = mozNumbers[i]; - phoneNumbers.push( - new ContactField( number.type, number.value, number.pref)); + function exportContactField(data) { + var contactFields = []; + for (var i=0; i < data.length; i++) { + var item = data[i]; + var itemData = new ContactField(item.type, item.value, item.pref); + contactFields.push(itemData); } - return phoneNumbers; + return contactFields; } var contact = new Contact(); @@ -133,31 +185,52 @@ function createCordovaFromMozilla(moz) { if (moz.id) { contact.id = moz.id; } - var arrayFields = [['givenName'], ['familyName'], ['name', 'displayName']]; - var simpleFields = [['honorificPrefix'], ['honorificSuffix'], ['nickname'], ['bday', 'birthday'], ['note']]; + var nameFields = [['givenName'], ['familyName'], + ['honorificPrefix'], ['honorificSuffix'], + ['additionalName', 'middleName']]; + var baseArrayFields = [['name', 'displayName'], 'nickname', ['note']]; + var baseStringFields = []; var name = new ContactName(); - var j = 0; while(field = arrayFields[j++]) { - if (moz[field[0]]) { - name[field[1] || field[0]] = moz[field[0]].join(' '); - } - } - j = 0; while(field = simpleFields[j++]) { - if (moz[field[0]]) { - name[field[1] || field[0]] = moz[field[0]]; - } + var j = 0; while(field = nameFields[j++]) { + if (moz[field[0]]) { + name[field[1] || field[0]] = moz[field[0]].join(' '); + } } contact.name = name; + j = 0; while(field = baseArrayFields[j++]) { + if (moz[field[0]]) { + contact[field[1] || field[0]] = moz[field[0]].join(' '); + } + } + j = 0; while(field = baseStringFields[j++]) { + if (moz[field[0]]) { + contact[field[1] || field[0]] = moz[field[0]]; + } + } // emails + if (moz.email) { + contact.emails = exportContactField(moz.email); + } // categories // addresses if (moz.tel) { - contact.phoneNumbers = exportPhoneNumbers(moz.tel); + contact.phoneNumbers = exportContactField(moz.tel); + } + // birthday + if (moz.bday) { + contact.birthday = Date.parse(moz.bday); } // organizations return contact; } +function _inspect(obj) { + for (var k in obj) { + console.log(k, obj[k]); + } +} + function saveContacts(successCB, errorCB, contacts) { // a closure which is holding the right moz contact function makeSaveSuccessCB(moz) { @@ -172,11 +245,13 @@ function saveContacts(successCB, errorCB, contacts) { var i=0; var contact; while(contact = contacts[i++]){ - var moz = createMozillaFromCordova(contact); - var request = navigator.mozContacts.save(moz); - // success and/or fail will be called every time a contact is saved - request.onsuccess = makeSaveSuccessCB(moz); - request.onerror = errorCB; + var moz = createMozillaFromCordova(function(moz) { + // console.log('before save ', moz.id, moz); + var request = navigator.mozContacts.save(moz); + // success and/or fail will be called every time a contact is saved + request.onsuccess = makeSaveSuccessCB(moz); + request.onerror = function(e) { console.log(e.target); errorCB(e); } + }, function() {}, contact); } } @@ -185,6 +260,10 @@ function remove(successCB, errorCB, ids) { var i=0; var id; for (var i=0; i < ids.length; i++){ + // throw an error if no id provided + if (!hasId(ids[i])) { + errorCB(0); + } var moz = new mozContact(); moz.id = ids[i]; var request = navigator.mozContacts.remove(moz); @@ -194,92 +273,86 @@ function remove(successCB, errorCB, ids) { } -var mozContactSearchFields = ['name', 'givenName', 'additionalName', - 'familyName', 'nickname', 'email', 'tel', 'jobTitle', 'note']; +var mozContactSearchFields = [['name', 'displayName'], ['givenName'], + ['familyName'], ['email'], ['tel'], ['jobTitle'], ['note'], + ['tel', 'phoneNumbers'], ['email', 'emails']]; +// nickname and additionalName are forbidden in 1.3 and below +// name is forbidden in 1.2 and below -// function search(successCB, errorCB, params) { -// var options = params[1] || {}; -// var filter = []; -// // filter out inallowed fields -// for (var i=0; i < params[0].length; i++) { -// if (mozContactSearchFields.indexOf([params[0][i]])) { -// filter.push(params[0][i]); -// } else if (params[0][i] == 'displayName') { -// filter.push('name'); -// } else { -// console.log('FXOS ContactProxy: inallowed field passed to search filtered out: ' + params[0][i]); -// } -// } -// -// var request; -// // TODO find out how to handle searching by numbers -// // filterOp: The filter comparison operator to use. Possible values are -// // equals, startsWith, and match, the latter being specific -// // to telephone numbers. -// var mozOptions = {filterBy: filter, filterOp: 'startsWith'}; -// if (!options.multiple) { -// mozOptions.filterLimit = 1; -// } -// if (!options.filter) { -// // this is returning 0 contacts -// request = navigator.mozContacts.getAll({}); -// } else { -// // XXX This is searching for regardless of the filterValue !!! -// mozOptions.filterValue = options.filter; -// console.log('mozoptions: filterBy: ' + mozOptions.filterBy.join(' ') + '; fiterValue: ' + mozOptions.filterValue); -// request = navigator.mozContacts.find(mozOptions); -// } -// request.onsuccess = function() { -// var contacts = []; -// var mozContacts = request.result; -// for (var i=0; i < mozContacts.length; i++) { -// contacts.push(createCordovaFromMozilla(mozContacts[i])); -// } -// successCB(contacts); -// }; -// request.onerror = errorCB; -// } +// finds if a value is inside array array and returns FFOS if different +function getMozSearchField(arr, value) { + if (arr.indexOf([value]) >= 0) { + return value; + } + for (var i=0; i < arr.length; i++) { + if (arr[i].length > 1) { + if (arr[i][1] === value) { + return arr[i][0]; + } + } + } + return false; +} -/* navigator.mozContacts.find has issues - using getAll - * https://bugzilla.mozilla.org/show_bug.cgi?id=941008 - */ -function hackedSearch(successCB, errorCB, params) { - // [contactField, eventualMozContactField] - var arrayFields = ['givenName', 'familyName', 'name']; +function search(successCB, errorCB, params) { var options = params[1] || {}; - var filter = []; - // filter out inallowed fields + if (!options.filter) { + return getAll(successCB, errorCB, params); + } + var filterBy = []; + // filter and translate fields for (var i=0; i < params[0].length; i++) { - if (mozContactSearchFields.indexOf([params[0][i]])) { - filter.push(params[0][i]); - } else if (params[0][i] == 'displayName') { - filter.push('name'); + var searchField = params[0][i]; + var mozField = getMozSearchField(mozContactSearchFields, searchField); + if (searchField === 'name') { + // Cordova uses name for search by all name fields. + filterBy.push('givenName'); + filterBy.push('familyName'); + continue; + } + if (searchField === 'displayName' && 'init' in new mozContact()) { + // ``init`` in ``mozContact`` indicates FFOS version 1.2 or below + console.log('FFOS ContactProxy: Unable to search by displayName on FFOS 1.2'); + continue; + } + if (mozField) { + filterBy.push(mozField); } else { - console.log('FXOS ContactProxy: inallowed field passed to search filtered out: ' + params[0][i]); + console.log('FXOS ContactProxy: inallowed field passed to search filtered out: ' + searchField); } } + + var mozOptions = {filterBy: filterBy, filterOp: 'startsWith'}; + if (!options.multiple) { + mozOptions.filterLimit = 1; + } + mozOptions.filterValue = options.filter; + var request = navigator.mozContacts.find(mozOptions); + request.onsuccess = function() { + var contacts = []; + var mozContacts = request.result; + var moz = mozContacts[0]; + for (var i=0; i < mozContacts.length; i++) { + contacts.push(createCordovaFromMozilla(mozContacts[i])); + } + successCB(contacts); + }; + request.onerror = errorCB; +} + + +/* navigator.mozContacts.find has issues - using getAll + * https://bugzilla.mozilla.org/show_bug.cgi?id=941008 + */ +function getAll(successCB, errorCB, params) { + // [contactField, eventualMozContactField] var getall = navigator.mozContacts.getAll({}); var contacts = []; - function isValid(mozContact) { - if (!options.filter) { - // get all - return true; - } - for (var j=0; j < filter.length; j++) { - var field = filter[0]; - var value = (arrayFields.indexOf(field) >= 0) ? mozContact[field].join(' ') : mozContact[field]; - if (value.indexOf(options.filter) >= 0) { - return true; - } - } - } getall.onsuccess = function() { if (getall.result) { - if (isValid(getall.result)) { - contacts.push(createCordovaFromMozilla(getall.result)); - } + contacts.push(createCordovaFromMozilla(getall.result)); getall.continue(); } else { successCB(contacts); @@ -291,7 +364,7 @@ function hackedSearch(successCB, errorCB, params) { module.exports = { save: saveContacts, remove: remove, - search: hackedSearch + search: search }; require("cordova/firefoxos/commandProxy").add("Contacts", module.exports);
