cordova-plugin-contacts
Advanced tools
Comparing version 1.0.0 to 1.1.0
{ | ||
"name": "cordova-plugin-contacts", | ||
"version": "1.0.0", | ||
"version": "1.1.0", | ||
"description": "Cordova Contacts Plugin", | ||
@@ -22,3 +22,3 @@ "cordova": { | ||
"type": "git", | ||
"url": "https://git-wip-us.apache.org/repos/asf/cordova-plugin-contacts.git" | ||
"url": "https://github.com/apache/cordova-plugin-contacts" | ||
}, | ||
@@ -25,0 +25,0 @@ "keywords": [ |
<!--- | ||
license: Licensed to the Apache Software Foundation (ASF) under one | ||
or more contributor license agreements. See the NOTICE file | ||
distributed with this work for additional information | ||
regarding copyright ownership. The ASF licenses this file | ||
to you under the Apache License, Version 2.0 (the | ||
"License"); you may not use this file except in compliance | ||
with the License. You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, | ||
software distributed under the License is distributed on an | ||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
KIND, either express or implied. See the License for the | ||
specific language governing permissions and limitations | ||
under the License. | ||
# license: Licensed to the Apache Software Foundation (ASF) under one | ||
# or more contributor license agreements. See the NOTICE file | ||
# distributed with this work for additional information | ||
# regarding copyright ownership. The ASF licenses this file | ||
# to you under the Apache License, Version 2.0 (the | ||
# "License"); you may not use this file except in compliance | ||
# with the License. You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, | ||
# software distributed under the License is distributed on an | ||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
# KIND, either express or implied. See the License for the | ||
# specific language governing permissions and limitations | ||
# under the License. | ||
--> | ||
@@ -52,4 +52,13 @@ | ||
This requires cordova 5.0+ ( current stable v1.0.0 ) | ||
cordova plugin add cordova-plugin-contacts | ||
Older versions of cordova can still install via the __deprecated__ id ( stale v0.2.16 ) | ||
cordova plugin add org.apache.cordova.contacts | ||
It is also possible to install via repo url directly ( unstable ) | ||
cordova plugin add https://github.com/apache/cordova-plugin-contacts.git | ||
### Firefox OS Quirks | ||
@@ -73,5 +82,7 @@ | ||
Any contacts returned from `find` and `pickContact` methods are readonly, so your application cannot modify them. | ||
**Prior to Windows 10:** Any contacts returned from `find` and `pickContact` methods are readonly, so your application cannot modify them. | ||
`find` method available only on Windows Phone 8.1 devices. | ||
**Windows 10 and above:** Contacts may be saved and will be saved to app-local contacts storage. Contacts may also be deleted. | ||
### Windows 8 Quirks | ||
@@ -164,3 +175,3 @@ | ||
- Windows Phone 7 and 8 | ||
- Windows (Windows Phone 8.1 devices only) | ||
- Windows (Windows Phone 8.1 and Windows 10) | ||
@@ -383,3 +394,3 @@ ### Example | ||
- __remove__: Method is not supported | ||
- __remove__: Method is only supported in Windows 10 or above. | ||
@@ -386,0 +397,0 @@ ## ContactAddress |
@@ -164,1 +164,9 @@ <!-- | ||
* CB-8395 marked unsupported tests pending on wp8 | ||
### 1.1.0 (Jun 17, 2015) | ||
* CB-9128 cordova-plugin-contacts documentation translation: cordova-plugin-contacts | ||
* fix npm md issue | ||
* Add more install text for legacy versions of cordova tools. This closes #60 | ||
* CB-9056 Increased timeout of failing tests | ||
* CB-8987: Support for save and remove for Windows 10 | ||
* CB-5278: We must close the cursor or we take down the whole app, and the debugger doesn't catch it. |
@@ -34,4 +34,5 @@ /* | ||
// displayName & nickname | ||
contact.displayName = windowsContact.name || windowsContact.displayName; | ||
contact.displayName = windowsContact.displayName || windowsContact.name; | ||
contact.nickname = windowsContact.name; | ||
contact.id = windowsContact.id; | ||
@@ -41,7 +42,8 @@ // name | ||
contact.name = new ContactName( | ||
windowsContact.name || windowsContact.displayName, | ||
windowsContact.displayName || windowsContact.name, | ||
windowsContact.lastName, | ||
windowsContact.firstName || windowsContact.name, | ||
windowsContact.middleName, | ||
windowsContact.honorificPrefix, | ||
windowsContact.honorificSuffix); | ||
windowsContact.honorificNamePrefix || windowsContact.honorificPrefix, | ||
windowsContact.honorificNameSuffix || windowsContact.honorificSuffix); | ||
@@ -121,2 +123,101 @@ // phoneNumbers | ||
function cdvContactToWindowsContact(contact) { | ||
var result = new contactsNS.Contact(); | ||
// name first | ||
if (contact.name) { | ||
result.displayNameOverride = contact.name.formatted; | ||
result.firstName = contact.name.givenName; | ||
result.middleName = contact.name.middleName; | ||
result.lastName = contact.name.familyName; | ||
result.honorificNamePrefix = contact.name.honorificPrefix; | ||
result.honorificNameSuffix = contact.name.honorificSuffix; | ||
} | ||
result.nickname = contact.nickname; | ||
// phone numbers | ||
if (contact.phoneNumbers) { | ||
contact.phoneNumbers.forEach(function(contactPhone) { | ||
var resultPhone = new contactsNS.ContactPhone(); | ||
resultPhone.description = contactPhone.type; | ||
resultPhone.number = contactPhone.value; | ||
result.phones.push(resultPhone); | ||
}); | ||
} | ||
// emails | ||
if (contact.emails) { | ||
contact.emails.forEach(function(contactEmail) { | ||
var resultEmail = new contactsNS.ContactEmail(); | ||
resultEmail.description = contactEmail.type; | ||
resultEmail.address = contactEmail.value; | ||
result.emails.push(resultEmail); | ||
}); | ||
} | ||
// Addresses | ||
if (contact.addresses) { | ||
contact.addresses.forEach(function(contactAddress) { | ||
var address = new contactsNS.ContactAddress(); | ||
address.description = contactAddress.type; | ||
address.streetAddress = contactAddress.streetAddress; | ||
address.locality = contactAddress.locality; | ||
address.region = contactAddress.region; | ||
address.postalCode = contactAddress.postalCode; | ||
address.country = contactAddress.country; | ||
result.addresses.push(address); | ||
}); | ||
} | ||
// IMs | ||
if (contact.ims) { | ||
contact.ims.forEach(function(contactIM) { | ||
var acct = new contactsNS.ContactConnectedServiceAccount(); | ||
acct.serviceName = contactIM.type; | ||
acct.id = contactIM.value; | ||
result.connectedServiceAccounts.push(acct); | ||
}); | ||
} | ||
// JobInfo | ||
if (contact.organizations) { | ||
contact.organizations.forEach(function(contactOrg) { | ||
var job = new contactsNS.ContactJobInfo(); | ||
job.companyName = contactOrg.name; | ||
job.department = contactOrg.department; | ||
job.description = contactOrg.type; | ||
job.title = contactOrg.title; | ||
result.jobInfo.push(job); | ||
}); | ||
} | ||
result.notes = contact.note; | ||
if (contact.photos) { | ||
var eligiblePhotos = contact.photos.filter(function(photo) { | ||
return typeof photo.value !== 'undefined'; | ||
}); | ||
if (eligiblePhotos.length > 0) { | ||
var supportedPhoto = eligiblePhotos[0]; | ||
var path = supportedPhoto.value; | ||
try { | ||
var streamRef; | ||
if (/^([a-z][a-z0-9+\-.]*):\/\//i.test(path)) { | ||
streamRef = Windows.Storage.Streams.RandomAccessStreamReference.createFromUri(new Windows.Foundation.Uri(path)); | ||
} else { | ||
streamRef = Windows.Storage.Streams.RandomAccessStreamReference.createFromFile(path); | ||
} | ||
result.thumbnail = streamRef; | ||
} | ||
catch (e) { | ||
// incompatible reference to the photo | ||
} | ||
} | ||
} | ||
return result; | ||
} | ||
module.exports = { | ||
@@ -170,10 +271,109 @@ | ||
save: function (win, fail, args) { | ||
// Not supported yet since WinJS API do not provide methods to manage contactStore | ||
// On Windows Phone 8.1 this can be implemented using native class library | ||
// See Windows.Phone.PersonalInformation namespace | ||
// http://msdn.microsoft.com/en-us/library/windows/apps/xaml/windows.phone.personalinformation.aspx | ||
//We don't need to create Error object here since it will be created at navigator.contacts.find() method | ||
fail && fail(ContactError.NOT_SUPPORTED_ERROR); | ||
if (typeof contactsNS.ContactList === 'undefined') { | ||
// Not supported yet since WinJS API do not provide methods to manage contactStore | ||
// On Windows Phone 8.1 this can be implemented using native class library | ||
// See Windows.Phone.PersonalInformation namespace | ||
// http://msdn.microsoft.com/en-us/library/windows/apps/xaml/windows.phone.personalinformation.aspx | ||
//We don't need to create Error object here since it will be created at navigator.contacts.find() method | ||
fail && fail(ContactError.NOT_SUPPORTED_ERROR); | ||
return; | ||
} | ||
var winContact = cdvContactToWindowsContact(args[0]); | ||
contactsNS.ContactManager.requestStoreAsync(contactsNS.ContactStoreAccessType.appContactsReadWrite).then(function(store) { | ||
return store.findContactListsAsync().then(function(lists) { | ||
if (lists.length > 0) { | ||
return lists[0]; | ||
} else { | ||
return store.createContactListAsync(''); | ||
} | ||
}, function(error) { | ||
return store.createContactListAsync(''); | ||
}); | ||
}).then(function(list) { | ||
return list.saveContactAsync(winContact); | ||
}).done(function(result) { | ||
win(convertToContact(winContact)); | ||
}, function(error) { | ||
fail(error); | ||
}); | ||
}, | ||
remove: function(win, fail, args) { | ||
if (typeof contactsNS.ContactList === 'undefined') { | ||
// Not supported yet since WinJS API do not provide methods to manage contactStore | ||
// On Windows Phone 8.1 this can be implemented using native class library | ||
// See Windows.Phone.PersonalInformation namespace | ||
// http://msdn.microsoft.com/en-us/library/windows/apps/xaml/windows.phone.personalinformation.aspx | ||
//We don't need to create Error object here since it will be created at navigator.contacts.find() method | ||
fail && fail(ContactError.NOT_SUPPORTED_ERROR); | ||
return; | ||
} | ||
// This is a complicated scenario because in Win10, there is a notion of 'app contacts' vs 'global contacts'. | ||
// search() returns all global contacts, which are "aggregate contacts", so the IDs of contacts that Cordova | ||
// creates never match the IDs of the contacts returned from search(). | ||
// In order to work around this, we need to: | ||
// - Get two Stores: one that is read-write to the app-contacts list, one which is read-only for global contacts | ||
// - Read the app-local store to see if a contact with the passed-in ID matches | ||
// - Grab the global aggregate contact manager, then ask it for raw contacts (app-local ACM returns access denied) | ||
// - Find my app-list of contacts | ||
// - Enumerate the raw contacts and see if there is a raw contact whose parent list matches the app-list | ||
// - If so, remove the raw contact from the app-list | ||
// - If any of this fails, the operation fails | ||
WinJS.Promise.join([contactsNS.ContactManager.requestStoreAsync(contactsNS.ContactStoreAccessType.appContactsReadWrite), | ||
contactsNS.ContactManager.requestStoreAsync(contactsNS.ContactStoreAccessType.allContactsReadOnly)]).then(function(stores) { | ||
var readOnlyStore = stores[1]; | ||
var writableStore = stores[0]; | ||
var storeReader = writableStore.getContactReader(); | ||
return storeReader.readBatchAsync().then(function(batch) { | ||
if (batch.status !== contactsNS.ContactBatchStatus.success) { | ||
// Couldn't read contacts store | ||
throw new ContactError(ContactError.IO_ERROR); | ||
} | ||
var candidates = batch.contacts.filter(function(testContact) { | ||
return testContact.id === args[0]; | ||
}); | ||
if (candidates.length === 0) { | ||
// No matching contact from aggregate store | ||
throw new ContactError(ContactError.IO_ERROR); | ||
} | ||
return candidates[0]; | ||
}).then(function(contactToDelete) { | ||
return readOnlyStore.aggregateContactManager.findRawContactsAsync(contactToDelete); | ||
}).then(function(rawContacts) { | ||
return writableStore.findContactListsAsync().then(function(lists) { | ||
var deleteList = null; | ||
var deleteContact = null; | ||
var matched = lists.some(function(list) { | ||
for (var i = 0; i < rawContacts.length; i++) { | ||
if (rawContacts[i].contactListId === list.id) { | ||
deleteList = list; | ||
deleteContact = rawContacts[i]; | ||
return true; | ||
} | ||
} | ||
return false; | ||
}); | ||
if (!matched) { | ||
throw new ContactError(ContactError.IO_ERROR); | ||
} | ||
return deleteList.deleteContactAsync(deleteContact); | ||
}); | ||
}); | ||
}).done(function() { | ||
win(); | ||
}, function(error) { | ||
fail(error); | ||
}); | ||
}, | ||
@@ -180,0 +380,0 @@ search: function (win, fail, options) { |
@@ -34,4 +34,5 @@ /* | ||
}; | ||
var MEDIUM_TIMEOUT = 30000; | ||
var removeContact = function(){ | ||
@@ -348,3 +349,3 @@ if (gContactObj) { | ||
gContactObj.save(win, fail); | ||
}); | ||
}, MEDIUM_TIMEOUT); | ||
}); | ||
@@ -379,3 +380,3 @@ describe('Contact.remove method', function (done) { | ||
contact.remove(rmWin, rmFail); | ||
}); | ||
}, MEDIUM_TIMEOUT); | ||
}); | ||
@@ -426,3 +427,3 @@ describe("Round trip Contact tests (creating + save + delete + find).", function () { | ||
}, fail); | ||
}); | ||
}, MEDIUM_TIMEOUT); | ||
}); | ||
@@ -522,2 +523,46 @@ describe('ContactError interface', function () { | ||
} | ||
function removeDooneyEvans() { | ||
var results = document.getElementById('contact_results'); | ||
navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails", "urls", "note"], function(contacts) { | ||
var removes = []; | ||
contacts.forEach(function(contact) { | ||
if (contact.name.formatted.indexOf('Dooney Evans') > -1) { | ||
removes.push(contact); | ||
} | ||
}); | ||
var nextToRemove = undefined; | ||
if (removes.length > 0) { | ||
nextToRemove = removes.shift(); | ||
} | ||
function removeNext(item) { | ||
if (typeof item === 'undefined') | ||
return; | ||
if (removes.length > 0) { | ||
nextToRemove = removes.shift(); | ||
} else { | ||
nextToRemove = undefined; | ||
} | ||
item.remove(function removeSucceeded() { | ||
results.innerHTML += '<br>Removed contact with ID ' + item.id; | ||
removeNext(nextToRemove); | ||
}, function removeFailed(e) { | ||
results.innerHTML += '<br>Remove failed contact with ID ' + item.id; | ||
removeNext(nextToRemove); | ||
}); | ||
} | ||
removeNext(nextToRemove); | ||
}, function (e) { | ||
if (e.code === ContactError.NOT_SUPPORTED_ERROR) { | ||
results.innerHTML = 'Searching for contacts is not supported.'; | ||
} | ||
else { | ||
results.innerHTML = 'Search failed: error ' + e.code; | ||
} | ||
}) | ||
} | ||
@@ -533,3 +578,5 @@ /******************************************************************************/ | ||
'</p> <div id="add_contact"></div>' + | ||
'Expected result: Will add a new contact. Log will say "Contact saved." or "Saving contacts not supported." if not supported on current platform. Verify by running Get phone contacts again'; | ||
'Expected result: Will add a new contact. Log will say "Contact saved." or "Saving contacts not supported." if not supported on current platform. Verify by running Get phone contacts again' + | ||
'<div id="remove_dooney_evans"></div>' + | ||
'<p>Expected result: Will remove any contacts named "Dooney Evans". Log will output success or failure, plus ID, or fail like getting contacts will fail.</p>'; | ||
@@ -543,2 +590,6 @@ createActionButton("Get phone's contacts", function () { | ||
}, 'add_contact'); | ||
createActionButton("Delete all 'Dooney Evans'", function() { | ||
removeDooneyEvans(); | ||
}, 'remove_dooney_evans'); | ||
}; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
989397
69
3112
787