From: Rafal Galka Date: Tue, 13 Jan 2015 12:09:27 +0000 (+0100) Subject: [Contact] JS files renamed to match common convention X-Git-Tag: submit/tizen_tv/20150603.064601~1^2~647 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=38e5ce31a1ebf20c752e70d28cbd6d3e90810363;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [Contact] JS files renamed to match common convention Change-Id: I9c82b5be3a09867ebed73ce9d67aff716b42b0e9 Signed-off-by: Rafal Galka --- diff --git a/src/contact/contact_api.js b/src/contact/contact_api.js index fc7ca652..7b198bba 100644 --- a/src/contact/contact_api.js +++ b/src/contact/contact_api.js @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -//= require('tizen.contact.Common.js'); -//= require('tizen.contact.ContactDataStructures.js'); -//= require('tizen.contact.Contact.js'); -//= require('tizen.contact.AddressBook.js'); -//= require('tizen.contact.Person.js'); -//= require('tizen.contact.ContactManager.js'); +//= require('common.js'); +//= require('contact_data_structures.js'); +//= require('contact.js'); +//= require('address_book.js'); +//= require('person.js'); +//= require('contact_manager.js'); diff --git a/src/contact/js/address_book.js b/src/contact/js/address_book.js new file mode 100644 index 00000000..12190abc --- /dev/null +++ b/src/contact/js/address_book.js @@ -0,0 +1,696 @@ +// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var DEFAULT_ADDRESSBOOK_ID = '0'; +var UNIFIED_ADDRESSBOOK_ID = '-1'; + +var _contactListenerRegistered = false; +var _contactCallbackMap = {}; + +var _filterById = function(array, id) { + var ret = []; + for (var i = 0; i < array.length; ++i) { + if (array[i].addressBookId === id) { + ret.push(_promote(array[i], Contact)); + } + } + return ret; +}; + +var _contactChangeListener = function(result) { + var unifiedId = UNIFIED_ADDRESSBOOK_ID; + var watchId; + var i; + + // Unified address book case + if (_contactCallbackMap.hasOwnProperty(unifiedId)) { + for (watchId in _contactCallbackMap[unifiedId]) { + if (_contactCallbackMap[unifiedId].hasOwnProperty(watchId)) { + var callback = _contactCallbackMap[unifiedId][watchId].successCallback; + if (result.added.length) { + native_.callIfPossible(callback.oncontactsadded, _promote(result.added, Contact)); + } + if (result.updated.length) { + native_.callIfPossible(callback.oncontactsupdated, _promote(result.updated, Contact)); + } + if (result.removed.length) { + var allRemoved = []; + for (i = 0; i < result.removed.length; ++i) { + allRemoved.push(result.removed[i].id); + } + native_.callIfPossible(callback.oncontactsremoved, result.allRemoved); + } + } + } + } + + for (var callbackAddressbookId in _contactCallbackMap) { + if (callbackAddressbookId !== UNIFIED_ADDRESSBOOK_ID && + _contactCallbackMap.hasOwnProperty(callbackAddressbookId)) { + + var filteredAdded = []; + var filteredUpdated = []; + var filteredRemoved = []; + + if (result.added.length) { + filteredAdded = _filterById(result.added, callbackAddressbookId); + } + if (result.updated.length) { + filteredUpdated = _filterById(result.updated, callbackAddressbookId); + } + if (result.removed.length) { + for (i = 0; i < result.removed.length; ++i) { + if (result.removed[i].addressBookId === callbackAddressbookId) { + filteredRemoved.push(result.removed[i].id); + } + } + } + + for (watchId in _contactCallbackMap[callbackAddressbookId]) { + if (_contactCallbackMap[callbackAddressbookId].hasOwnProperty(watchId)) { + var callback = _contactCallbackMap[callbackAddressbookId][watchId].successCallback; + if (filteredAdded.length) { + native_.callIfPossible(callback.oncontactsadded, filteredAdded); + } + if (filteredUpdated.length) { + native_.callIfPossible(callback.oncontactsupdated, filteredUpdated); + } + if (filteredRemoved.length) { + native_.callIfPossible(callback.oncontactsremoved, filteredRemoved); + } + } + } + } + } +}; + + +var AddressBook = function(accountId, name) { + AV.isConstructorCall(this, AddressBook); + + var id_ = null; + var name_ = ''; + var readOnly_ = false; + var accountId_ = null; + + if (Type.isNumber(accountId)) { + accountId_ = accountId; + } + if (Type.isString(name)) { + name_ = name; + } + + Object.defineProperties(this, { + id: { + get: function() { + return id_; + }, + set: function(v) { + if (_editGuard.isEditEnabled()) { + id_ = Converter.toString(v, false); + } + }, + enumerable: true + }, + accountId: { + get: function() { + return accountId_; + }, + set: function(v) { + if (_editGuard.isEditEnabled()) { + accountId_ = Converter.toLong(v, true); + } + }, + enumerable: true + }, + name: { + get: function() { + return name_; + }, + set: function(v) { + if (_editGuard.isEditEnabled()) { + name_ = Converter.toString(v, false); + } + }, + enumerable: true + }, + readOnly: { + get: function() { + return readOnly_; + }, + set: function(v) { + if (_editGuard.isEditEnabled()) { + readOnly_ = Converter.toBoolean(v, false); + } + }, + enumerable: true + } + }); +}; + +AddressBook.prototype.get = function() { + var args = AV.validateArgs(arguments, [{ + name: 'id', + type: AV.Types.STRING, + optional: false, + nullable: false + }]); + + if (String(Converter.toLong(args.id)) !== args.id) { + // TCT: AddressBook_get_id_invalid + throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR); + } + + var result = native_.callSync('AddressBook_get', { + // TODO move to only sending the address book id (in all functions) + addressBook: this, + id: args.id + }); + + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } + + return _editGuard.run(function() { + var contact = new Contact(native_.getResultObject(result)); + + if (contact.name instanceof ContactName) { + contact.name.displayName = ''; + if (Type.isString(contact.name.firstName)) { + contact.name.displayName = contact.name.firstName; + if (Type.isString(contact.name.lastName)) { + contact.name.displayName += ' ' + contact.name.lastName; + } + } else if (Type.isArray(contact.name.nicknames) && + Type.isString(contact.name.nicknames[0])) { + contact.name.displayName = contact.name.nicknames[0]; + } else if (Type.isString(contact.name.nicknames)) { + contact.name.displayName = contact.name.nicknames; + } + } + + + + return contact; + }); +}; + +AddressBook.prototype.add = function() { + var args = AV.validateArgs(arguments, [ + { + name: 'contact', + type: AV.Types.PLATFORM_OBJECT, + values: Contact, + optional: false, + nullable: false + } + ]); + + var result = native_.callSync('AddressBook_add', { + // TODO move to only sending the address book id (in all functions) + addressBook: this, + contact: _toJsonObject(args.contact) + }); + + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } + + var _updatedContact = native_.getResultObject(result); + _editGuard.run(function() { + for (var prop in _updatedContact) { + if (args.contact.hasOwnProperty(prop)) { + args.contact[prop] = _updatedContact[prop]; + } + } + + if (args.contact.name instanceof ContactName) { + args.contact.name.displayName = ''; + if (Type.isString(args.contact.name.firstName)) { + args.contact.name.displayName = args.contact.name.firstName; + if (Type.isString(args.contact.name.lastName)) { + args.contact.name.displayName += ' ' + args.contact.name.lastName; + } + } else if (Type.isArray(args.contact.name.nicknames) && + Type.isString(args.contact.name.nicknames[0])) { + args.contact.name.displayName = args.contact.name.nicknames[0]; + } else if (Type.isString(args.contact.name.nicknames)) { + args.contact.name.displayName = args.contact.name.nicknames; + } + } + }); +}; + +AddressBook.prototype.addBatch = function() { + var args = AV.validateArgs(arguments, [ + { + name: 'contacts', + type: AV.Types.ARRAY, + value: Contact, + optional: false, + nullable: false + }, + { + name: 'successCallback', + type: AV.Types.FUNCTION, + optional: true, + nullable: true + }, + { + name: 'errorCallback', + type: AV.Types.FUNCTION, + optional: true, + nullable: true + } + + ]); + + var callback = function(result) { + if (native_.isFailure(result)) { + native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); + return; + } + + _editGuard.run(function() { + var _result = native_.getResultObject(result); + for (var i = 0; i < _result.length; ++i) { + for (var prop in _result[i]) { + if (args.contacts[i].hasOwnProperty(prop)) { + args.contacts[i][prop] = _result[i][prop]; + } + } + } + }); + + native_.callIfPossible(args.successCallback, args.contacts); + }; + + native_.call('AddressBook_addBatch', { + addressBookId: this.id, + batchArgs: _toJsonObject(args.contacts) + }, callback); +}; + +AddressBook.prototype.update = function() { + var args = AV.validateArgs(arguments, [ + { + name: 'contact', + type: AV.Types.PLATFORM_OBJECT, + values: Contact, + optional: false, + nullable: false + } + ]); + + var result = native_.callSync('AddressBook_update', { + addressBook: this, + contact: _toJsonObject(args.contact) + }); + + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } + + var _updatedContact = native_.getResultObject(result); + _editGuard.run(function() { + for (var prop in _updatedContact) { + if (args.contact.hasOwnProperty(prop)) { + args.contact[prop] = _updatedContact[prop]; + } + } + }); +}; + +AddressBook.prototype.updateBatch = function() { + var args = AV.validateArgs(arguments, [ + { + name: 'contacts', + type: AV.Types.ARRAY, + values: Contact, + optional: false, + nullable: false + }, + { + name: 'successCallback', + type: AV.Types.FUNCTION, + optional: true, + nullable: true + }, + { + name: 'errorCallback', + type: AV.Types.FUNCTION, + optional: true, + nullable: true + } + ]); + + var callback = function(result) { + if (native_.isFailure(result)) { + native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); + return; + } + + _editGuard.run(function() { + var _result = native_.getResultObject(result); + for (var i = 0; i < _result.length; ++i) { + for (var prop in _result[i].result) { + if (args.contacts[i].hasOwnProperty(prop)) { + args.contacts[i][prop] = _result[i].result[prop]; + } + } + } + }); + + native_.callIfPossible(args.successCallback); + }; + + native_.call('AddressBook_updateBatch', { + addressBook: this, + batchArgs: _toJsonObject(args.contacts) + }, callback); +}; + +AddressBook.prototype.remove = function() { + var args = AV.validateArgs(arguments, [{ + name: 'id', + type: AV.Types.STRING, + optional: false, + nullable: false + }]); + + if (String(Converter.toLong(args.id)) !== args.id) { + // TCT: AddressBook_remove_id_invalid + throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR); + } + + var result = native_.callSync('AddressBook_remove', { + addressBook: this, + id: args.id + }); + + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } +}; + +AddressBook.prototype.removeBatch = function(ids, successCallback, errorCallback) { + var args = AV.validateArgs(arguments, [ + { + name: 'ids', + type: AV.Types.ARRAY, + values: AV.Types.STRING, + optional: false, + nullable: false + }, + { + name: 'successCallback', + type: AV.Types.FUNCTION, + optional: true, + nullable: true + }, + { + name: 'errorCallback', + type: AV.Types.FUNCTION, + optional: true, + nullable: true + } + ]); + + var callback = function(result) { + if (native_.isFailure(result)) { + native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); + return; + } + + native_.callIfPossible(args.successCallback); + }; + + native_.call('AddressBook_removeBatch', { + addressBook: this, + batchArgs: args.ids + }, callback); +}; + +AddressBook.prototype.find = function(successCallback, errorCallback, filter, sortMode) { + var args = AV.validateArgs(arguments, [ + { + name: 'successCallback', + type: AV.Types.FUNCTION, + optional: false, + nullable: false + }, + { + name: 'errorCallback', + type: AV.Types.FUNCTION, + optional: true, + nullable: true + }, + { + name: 'filter', + type: AV.Types.PLATFORM_OBJECT, + values: [ + tizen.AttributeFilter, + tizen.AttributeRangeFilter, + tizen.CompositeFilter + ], + optional: true, + nullable: true + }, + { + name: 'sortMode', + type: AV.Types.PLATFORM_OBJECT, + values: tizen.SortMode, + optional: true, + nullable: true + } + ]); + + var self = this; + var callback = function(result) { + if (native_.isFailure(result)) { + native_.callIfPossible(errorCallback, native_.getErrorObject(result)); + } + + var _contacts = []; + var _result = native_.getResultObject(result); + _result.forEach(function(data) { + try { + _contacts.push(self.get(String(data))); + } catch (e) {} + }); + + //TODO: Move filtering to native code + try { + _contacts = C.filter(_contacts, args.filter); + } catch (e) { + native_.callIfPossible(errorCallback, e); + return; + } + + //TODO: Move sorting to native code + _contacts = C.sort(_contacts, args.sortMode); + + native_.callIfPossible(successCallback, _contacts); + }; + + native_.call('AddressBook_find', { + addressBook: this, + filter: filter, + sortMode: sortMode + }, callback); +}; + +AddressBook.prototype.addChangeListener = function() { + var args = AV.validateArgs(arguments, [ + { + name: 'successCallback', + type: AV.Types.LISTENER, + values: ['oncontactsadded', 'oncontactsupdated', 'oncontactsremoved'], + optional: false, + nullable: false + }, + { + name: 'errorCallback', + type: AV.Types.FUNCTION, + optional: true, + nullable: true + } + ]); + + if (Type.isEmptyObject(_contactCallbackMap)) { + var result = native_.callSync('AddressBook_startListening', {}); + + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } + } + + if (!_contactListenerRegistered) { + native_.addListener('ContactChangeListener', _contactChangeListener); + _contactListenerRegistered = true; + } + + if (!_contactCallbackMap.hasOwnProperty(this.id)) { + _contactCallbackMap[this.id] = {}; + } + + var currentWatchId = _getNextWatchId(); + + _contactCallbackMap[this.id][currentWatchId] = { + successCallback: args.successCallback, + errorCallback: args.errorCallback + }; + + return currentWatchId; +}; + +AddressBook.prototype.removeChangeListener = function(watchId) { + var args = AV.validateArgs(arguments, [ + { + name: 'watchId', + type: AV.Types.LONG, + optional: false, + nullable: false + } + ]); + + if (args.watchId === 0) { + throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR, + 'id is null or undefined'); + } + + if (args.watchId < 0) { + throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR, + 'Negative watch id'); + } + + if (!_contactCallbackMap.hasOwnProperty(this.id) || + !_contactCallbackMap[this.id].hasOwnProperty(args.watchId)) { + throw new tizen.WebAPIException(tizen.WebAPIException.NOT_FOUND_ERR, + 'watch id not found for this address book'); + } + + delete _contactCallbackMap[this.id][args.watchId]; + + if (Type.isEmptyObject(_contactCallbackMap[this.id])) { + delete _contactCallbackMap[this.id]; + } + + if (Type.isEmptyObject(_contactCallbackMap)) { + native_.removeListener('ContactChangeListener', _contactChangeListener); + _contactListenerRegistered = false; + + var result = native_.callSync('AddressBook_stopListening', {}); + + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } + } +}; + +AddressBook.prototype.getGroup = function() { + var args = AV.validateArgs(arguments, [{ + name: 'groupId', + type: AV.Types.STRING, + optional: false, + nullable: false + }]); + + if (String(Converter.toLong(args.groupId)) !== args.groupId) { + // TCT: AddressBook_getGroup_groupId_invalid + throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR); + } + + var result = native_.callSync('AddressBook_getGroup', { + addressBook: this, + id: args.groupId + }); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } + + return _editGuard.run(function() { + return new ContactGroup(native_.getResultObject(result)); + }); +}; + +AddressBook.prototype.addGroup = function() { + var args = AV.validateArgs(arguments, [ + { + name: 'group', + type: AV.Types.PLATFORM_OBJECT, + values: ContactGroup, + optional: false, + nullable: false + } + ]); + + var result = native_.callSync('AddressBook_addGroup', + {addressBookId: this.id, group: args.group}); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } + + _editGuard.run(function() { + result = native_.getResultObject(result); + args.group.id = result.id; + args.group.addressBookId = result.addressBookId; + }); +}; + +AddressBook.prototype.updateGroup = function() { + var args = AV.validateArgs(arguments, [ + { + name: 'group', + type: AV.Types.PLATFORM_OBJECT, + values: ContactGroup, + optional: false, + nullable: false + } + ]); + + var result = native_.callSync('AddressBook_updateGroup', + {addressBookId: this.id, group: args.group}); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } +}; + +AddressBook.prototype.removeGroup = function() { + var args = AV.validateArgs(arguments, [{ + name: 'groupId', + type: AV.Types.STRING, + optional: false, + nullable: false + }]); + + if (String(Converter.toLong(args.groupId)) !== args.groupId) { + // TCT: AddressBook_removeGroup_groupId_invalid + throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR); + } + + var result = native_.callSync('AddressBook_removeGroup', + {addressBook: this, id: args.groupId}); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } +}; + +AddressBook.prototype.getGroups = function() { + var result = native_.callSync('AddressBook_getGroups', {addressBook: this}); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } + result = native_.getResultObject(result); + var _tab = []; + _editGuard.run(function() { + result.forEach(function(data) { + _tab.push(new ContactGroup(data)); + }); + }); + return _tab; +}; + +// exports ///////////////////////////////////////////////////////////////// +tizen.AddressBook = AddressBook; diff --git a/src/contact/js/common.js b/src/contact/js/common.js new file mode 100644 index 00000000..ce1140da --- /dev/null +++ b/src/contact/js/common.js @@ -0,0 +1,188 @@ +/* global xwalk, extension */ + +// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var _common = xwalk.utils; +var Type = _common.type; +var Converter = _common.converter; +var AV = _common.validator; + +var native_ = new _common.NativeManager(extension); + +var _currentWatchId = 1; + +var _getNextWatchId = function() { + return _currentWatchId++; +}; + +// Adjusts properties to have the correct format expected by the native side. +// Currently only translates JS Date +var _toJsonObject = function(obj) { + var ret; + if (Type.isDate(obj)) { + var year = ('0000' + obj.getFullYear()).slice(-4); + var month = ('00' + (obj.getMonth() + 1)).slice(-2); + var day = ('00' + obj.getDate()).slice(-2); + return Number(year + month + day); + } + if (Type.isArray(obj)) { + ret = []; + for (var i = 0; i < obj.length; ++i) { + ret[i] = _toJsonObject(obj[i]); + } + return ret; + } + if (obj instanceof Object) { + ret = {}; + for (var prop in obj) { + if (obj.hasOwnProperty(prop)) { + ret[prop] = _toJsonObject(obj[prop]); + } + } + return ret; + } + return obj; +}; + +var _fromJsonDate = function(date) { + date = date + ''; + var year = date.substr(0, 4); + var month = date.substr(4, 2); + var day = date.substr(6, 2); + return new Date(year, month - 1, day); +}; + +var _promote = function(val, type) { + return _editGuard.run(function() { + if (Type.isArray(val)) { + var ret = []; + for (var i = 0; i < val.length; ++i) { + ret.push(new type(val[i])); + } + return ret; + } + return new type(val); + }); +}; + +function _checkError(result) { + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } +} + +var TypeEnum = ['VCARD_30']; + +// Edit Guard ////////////////////////////////////////////////////////////// +// This flag is workaround. It is caused by specification +// which tell to edit readonly fields. +var _canEdit = 0; + +var EditGuard = function() { +}; + +EditGuard.prototype.run = function(callback) { + try { + this.enable(); + var result = callback(); + this.disable(); + return result; + } catch (ex) { + this.disable(); + throw ex; + } +}; + +EditGuard.prototype.enable = function() { + _canEdit++; +}; + +EditGuard.prototype.disable = function() { + _canEdit--; +}; + +EditGuard.prototype.isEditEnabled = function() { + return _canEdit > 0; +}; + +var _editGuard = new EditGuard(); + +//TODO: Move sorting and filtering to native code +var Common = function() {}; +Common.prototype.sort = function(arr, sortMode) { + var _getSortProperty = function(obj, props) { + for (var i = 0; i < props.length; ++i) { + if (!obj.hasOwnProperty(props[i])) { + return null; + } + obj = obj[props[i]]; + } + return obj; + }; + + if (sortMode instanceof tizen.SortMode) { + var props = sortMode.attributeName.split('.'); + arr.sort(function(a, b) { + var aValue = _getSortProperty(a, props); + var bValue = _getSortProperty(b, props); + + if (sortMode.order === 'DESC') { + return aValue < bValue; + } + return bValue < aValue; + }); + } + return arr; +}; + +Common.prototype.filter = function(arr, filter) { + if (Type.isNullOrUndefined(arr)) + return arr; + if (filter instanceof tizen.AttributeFilter || + filter instanceof tizen.AttributeRangeFilter || + filter instanceof tizen.CompositeFilter) { + arr = arr.filter(function(element) { + return filter._filter(element); + }); + } + return arr; +}; + +Common.prototype.repackFilter = function (filter) { + if (filter instanceof tizen.AttributeFilter) { + return { + filterType: 'AttributeFilter', + attributeName: filter.attributeName, + matchFlag: filter.matchFlag, + matchValue: filter.matchValue + }; + } + if (filter instanceof tizen.AttributeRangeFilter) { + return { + filterType: 'AttributeRangeFilter', + attributeName: filter.attributeName, + initialValue: Type.isNullOrUndefined(filter.initialValue) ? null : filter.initialValue, + endValue: Type.isNullOrUndefined(filter.endValue) ? null : filter.endValue + }; + } + if (filter instanceof tizen.CompositeFilter) { + var _f = []; + var filters = filter.filters; + + for (var i = 0; i < filters.length; ++i) { + _f.push(this.repackFilter(filters[i])); + } + + return { + filterType: 'CompositeFilter', + type: filter.type, + filters: _f + }; + } + + return null; +}; + +var C = new Common(); diff --git a/src/contact/js/contact.js b/src/contact/js/contact.js new file mode 100644 index 00000000..cecc8433 --- /dev/null +++ b/src/contact/js/contact.js @@ -0,0 +1,585 @@ +// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var Contact = function(data) { + AV.isConstructorCall(this, Contact); + + var _forceEditMode = false; + if (Type.isString(data)) { + var result = native_.callSync('ContactManager_importFromVCard', { + 'contact': data + }); + _checkError(result); + + data = native_.getResultObject(result); + // These need to be forced to null as a contact created from a vcard is not added + // to any address book + data.id = null; + data.personId = null; + data.addressBookId = null; + data.lastUpdate = null; + + // Force edit mode so that anonymous objects can be promoted to their correct types. + _forceEditMode = true; + } else if (Type.isObject(data) || Type.isFunction(data)) { + // It's a dictionary + } else { + // null or invalid types. + data = {}; + } + + var _id = null; + var _personId = null; + var _addressBookId = null; + var _lastUpdate = null; + var _isFavorite = false; + var _name = null; + var _addresses = []; + var _photoURI = null; + var _phoneNumbers = []; + var _emails = []; + var _messengers = []; + var _relationships = []; + var _birthday = null; + var _anniversaries = []; + var _organizations = []; + var _notes = []; + var _urls = []; + var _ringtoneURI = null; + var _messageAlertURI = null; + var _vibrationURI = null; + var _groupIds = []; + + var _sanitizeArray = function(arr, type, previousValue) { + if (!Type.isArray(arr)) { + return previousValue; + } + for (var i = 0; i < arr.length; ++i) { + if (Type.isString(type)) { + if (!Type.isString(arr[i])) { + return previousValue; + } + } else if (_editGuard.isEditEnabled()) { + arr[i] = new type(arr[i]); + } else if (!(arr[i] instanceof type)) { + return previousValue; + } + } + return arr; + }; + + Object.defineProperties(this, { + id: { + get: function() { + return _id; + }, + set: function(v) { + if (_editGuard.isEditEnabled()) { + _id = Converter.toString(v, false); + } + }, + enumerable: true + }, + personId: { + get: function() { + return _personId; + }, + set: function(v) { + if (_editGuard.isEditEnabled()) { + _personId = Converter.toString(v, false); + } + }, + enumerable: true + }, + addressBookId: { + get: function() { + return _addressBookId; + }, + set: function(v) { + if (_editGuard.isEditEnabled()) { + _addressBookId = Converter.toString(v, false); + } + }, + enumerable: true + }, + lastUpdated: { + get: function() { + return _lastUpdate; + }, + set: function(v) { + if (_editGuard.isEditEnabled()) { + if (v instanceof Date || v === null) { + _lastUpdate = v; + } else if (Type.isString(v)) { + _lastUpdate = new Date(v); + } else { + _lastUpdate = _fromJsonDate(v); + } + } + }, + enumerable: true + }, + isFavorite: { + get: function() { + return _isFavorite; + }, + set: function(v) { + if (_editGuard.isEditEnabled()) { + _isFavorite = Converter.toBoolean(v, false); + } + }, + enumerable: true + }, + name: { + get: function() { + return _name; + }, + set: function(v) { + if (_editGuard.isEditEnabled()) { + _name = new ContactName(v); + } else { + _name = (v instanceof ContactName || v === null) ? v : _name; + } + }, + enumerable: true + }, + addresses: { + get: function() { + return _addresses; + }, + set: function(v) { + _addresses = _sanitizeArray(v, ContactAddress, _addresses); + }, + enumerable: true + }, + photoURI: { + get: function() { + return _photoURI; + }, + set: function(v) { + _photoURI = Converter.toString(v, true); + }, + enumerable: true + }, + phoneNumbers: { + get: function() { + return _phoneNumbers; + }, + set: function(v) { + _phoneNumbers = _sanitizeArray(v, ContactPhoneNumber, _phoneNumbers); + }, + enumerable: true + }, + emails: { + get: function() { + return _emails; + }, + set: function(v) { + _emails = _sanitizeArray(v, ContactEmailAddress, _emails); + }, + enumerable: true + }, + messengers: { + get: function() { + return _messengers; + }, + set: function(v) { + _messengers = _sanitizeArray(v, ContactInstantMessenger, _messengers); + }, + enumerable: true + }, + relationships: { + get: function() { + return _relationships; + }, + set: function(v) { + _relationships = _sanitizeArray(v, ContactRelationship, _relationships); + }, + enumerable: true + }, + birthday: { + get: function() { + return _birthday; + }, + set: function(v) { + if (v instanceof Date || v === null) { + _birthday = v; + } else if (Type.isString(v)) { + _birthday = new Date(v); + } else if (_editGuard.isEditEnabled()) { + _birthday = _fromJsonDate(v); + } + }, + enumerable: true + }, + anniversaries: { + get: function() { + return _anniversaries; + }, + set: function(v) { + _anniversaries = _sanitizeArray(v, ContactAnniversary, _anniversaries); + }, + enumerable: true + }, + organizations: { + get: function() { + return _organizations; + }, + set: function(v) { + _organizations = _sanitizeArray(v, ContactOrganization, _organizations); + }, + enumerable: true + }, + notes: { + get: function() { + return _notes; + }, + set: function(v) { + _notes = _sanitizeArray(v, '', _notes); + }, + enumerable: true + }, + urls: { + get: function() { + return _urls; + }, + set: function(v) { + _urls = _sanitizeArray(v, ContactWebSite, _urls); + }, + enumerable: true + }, + ringtoneURI: { + get: function() { + return _ringtoneURI; + }, + set: function(v) { + _ringtoneURI = Converter.toString(v, true); + }, + enumerable: true + }, + messageAlertURI: { + get: function() { + return _messageAlertURI; + }, + set: function(v) { + _messageAlertURI = Converter.toString(v, true); + }, + enumerable: true + }, + vibrationURI: { + get: function() { + return _vibrationURI; + }, + set: function(v) { + _vibrationURI = Converter.toString(v, true); + }, + enumerable: true + }, + groupIds: { + get: function() { + return _groupIds; + }, + set: function(v) { + _groupIds = _sanitizeArray(v, '', _groupIds); + }, + enumerable: true + } + }); + + var _this = this; + var _setProperties = function() { + for (var p in _this) { + if (data.hasOwnProperty(p)) { + _this[p] = data[p]; + } + } + }; + + if (_forceEditMode) { + _editGuard.run(_setProperties); + } else { + _setProperties(); + } + +}; + +// Auxiliary functions ///////////////////////////////////////////////////// + +// Convert address from Contact object to string +var _contactAddressToString = function(obj) { + var str = ''; + if (obj.addresses.length === 0) { + return ''; + } + // Sorry for so many if statements, but the IDE makes me do it + for (var it in obj.addresses) { + if (!it instanceof ContactAddress) { + continue; + } + str += 'ADR;'; + for (var addType in it.types) { + if (Type.isString(addType)) { + str += addType + ','; + } + } + if (str.charAt(str.length - 1) === ',') { + str[str.length - 1] = ':'; + } + str += ';'; // because of we don't keep Post office addres + // which is part of vCard 3.0 standard + str += it.additionalInformation + ';'; + str += it.streetAddress + ';'; + str += it.city + ';'; + str += it.region + ';'; + str += it.postalCode + ';'; + str += it.country + ';'; + str += '\n'; + } + return str; +}; + +// Convert email address from Contact object to string +var _contactEmailToString = function(obj) { + if (!Type.isArray(obj.emails) || obj.emails.length === 0) { + console.log('Empty email list'); + return ''; + } + var str = ''; + for (var mail in obj.emails) { + if (!mail instanceof ContactEmailAddress || !Type.isArray(mail.types) || + mail.types.length === 0) { + console.log('Incorrect email type'); + continue; + } + str += 'EMAIL;'; + // set types + for (var type in mail.types) { + if (Type.isString(type)) { + str += type + ','; + } + } + if (str.charAt(str.length - 1) === ',') { + str[str.length - 1] = ':'; + } + str += '=' + Converter.toString(mail.email) + '\n'; + } + return str; +}; + +// Convert organizations info from Contact object to string +var _contactOrganizationToString = function(obj) { + if (obj.organizations.length === 0 || + !obj.organizations[0] instanceof ContactOrganization) { + return ''; + } + var str = ''; + for (var org in obj.organizations) { + if (!org instanceof ContactOrganization) { + continue; + } + str += 'ORG:'; + str += org.name + ';' + org.department + ';' + org.title + '\n'; + } + return str; +}; + +// Convert organizations roles from Contact object to string +var _contactRoleToString = function(obj) { + if (obj.organizations.length === 0 || + !obj.organizations[0] instanceof ContactOrganization) { + return ''; + } + var str = ''; + for (var org in obj.organizations) { + if (!org instanceof ContactOrganization) { + continue; + } + str += 'ROLE:'; + str += org.name + ';' + org.role + '\n'; + } + return str; +}; + +// Convert phone numbers from Contact object to string +var _contactPhoneNumbersToString = function(obj) { + if (obj.phoneNumbers.length === 0 || !obj.phoneNumbers[0] instanceof ContactPhoneNumber) { + return ''; + } + var str = ''; + for (var phone in obj.phoneNumbers) { + if (!phone instanceof ContactPhoneNumber) { + continue; + } + str += 'TEL'; + for (var type in phone.types) { + if (Type.isString(type)) { + str += ';' + type; + } + } + str += ':'; + str += phone.number + '\n'; + } + return str; +}; + +// Convert urls from Contact object to string +var _contactURLToString = function(obj) { + if (obj.urls.length === 0 || !obj.urls[0] instanceof ContactWebSite) { + return ''; + } + var str = ''; + for (var url in obj.urls) { + if (url instanceof ContactWebSite) { + str += 'URL:' + url.url + '\n'; + } + } + return str; +}; + +// Convert anniversaries to string +var _contactAnniversaryToString = function(obj) { + if (obj.anniversaries.length === 0 || !obj.anniversaries[0] instanceof ContactAnniversary) { + return ''; + } + var str = ''; + for (var ann in obj.anniversaries) { + if (ann instanceof ContactAnniversary) { + str += 'X-ANNIVERSARY;' + ann.label + ':' + ann.date + ';' + '\n'; + } + } + return str; +}; + +// Convert relationships to string +var _contactRelationshipsToString = function(obj) { + if (obj.relationships.length === 0 || + !obj.relationships[0] instanceof ContactRelationship) { + return ''; + } + var str = ''; + for (var rel in obj.relationships) { + if (rel instanceof ContactRelationship) { + str += 'X-RELATIONSHIP;' + rel.relativeName + ':' + rel.type + + ':' + rel.label + ';\n'; + } + } + return str; +}; + +// Convert messengers to string +var _contactInstantMessengeToString = function(obj) { + if (obj.messengers.length === 0 || !obj.messengers[0] instanceof ContactInstantMessenger) { + return ''; + } + var str = ''; + for (var messenger in obj.messengers) { + if (messenger instanceof ContactInstantMessenger) { + str += 'X-MESSANGER;' + messenger.imAddress + ':' + messenger.type + + ':' + messenger.label + ';\n'; + } + } + return str; +}; + +// Auxiliary function, allows to parse JSON to Contact +var _JSONToContactType = function(type, obj) { + var contact = new type(); + + for (var prop in obj) { + if (contact.hasOwnProperty(prop)) { + if (contact[prop] instanceof Date && Type.isNumber(obj[prop])) { + contact[prop] = new Date(1000 * obj[prop]); + } else { + contact[prop] = obj[prop]; + } + } + } + + return contact; +}; + +// Converts the Contact item to a string format. +Contact.prototype.convertToString = function(format) { + format = format || TypeEnum[0]; + + if (!Type.isString(format)) { + throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR, 'Invalid format'); + } + + if (TypeEnum.indexOf(format) < 0) { + throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR, 'Invalid format'); + } + + if (this.id === '') { + throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR, + 'Contact ID is empty.'); + } + + var str = 'BEGIN:VCARD\nVERSION:3.0\n'; + + // set contact name + str += 'N:' + this.name.lastName + ';' + this.name.firstName + ';' + + this.name.middleName + ';' + this.name.prefix + ';' + this.name.suffix + '\n'; + str += 'FN' + this.name.displayName + '\n'; + + // set phonetic names + str += 'X-PHONETIC-FIRST-NAME' + this.name.phoneticFirstName + '\n' + + 'X-PHONETIC-LAST-NAME' + this.name.phoneticLastName + '\n'; + + // set contact address + str += _contactAddressToString(this); + + // set Birthday + if (this.birthday) { + str += 'BDAY:' + this.birthday.getYear() + '-' + this.birthday.getMonth() + + '-' + this.birthday.getDay() + '\n'; + } + + // set anniversary + str += _contactAnniversaryToString(this); + + // set relationship + str += _contactRelationshipsToString(this); + + // set emails + str += _contactEmailToString(this); + + // set organization data + str += _contactOrganizationToString(this); + + // set role + str += _contactRoleToString(this); + + // set phone numbers + str += _contactPhoneNumbersToString(this); + + // set user ID + str += 'UID:' + this.id + '\n'; + + // set isFavorite + str += 'X-IS-FAVORITE' + this.isFavorite + '\n'; + + // set URLs + str += _contactURLToString(this); + + // set messengers + str += _contactInstantMessengeToString(this); + + // set last revision + str += 'REV:' + this.lastUpdated.getYear() + '-' + this.lastUpdated.getMonth() + + '-' + this.lastUpdated.getDay() + 'T' + this.lastUpdated.getHours() + ':' + + this.lastUpdated.getMinutes() + ':' + this.lastUpdated.getSeconds() + 'Z\n'; + + str += 'END:VCARD\n'; + + return str; +}; + +// Creates a clone of the Contact object, detached from any address book +Contact.prototype.clone = function() { + return new Contact(this); +}; + +// exports ///////////////////////////////////////////////////////////////// +tizen.Contact = Contact; diff --git a/src/contact/js/contact_data_structures.js b/src/contact/js/contact_data_structures.js new file mode 100644 index 00000000..eab62563 --- /dev/null +++ b/src/contact/js/contact_data_structures.js @@ -0,0 +1,743 @@ +// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// An enumerator that indicates the types for the relationships. +var ContactRelationshipType = { + ASSISTANT: 'ASSISTANT', + BROTHER: 'BROTHER', + CHILD: 'CHILD', + DOMESTIC_PARTNER: 'DOMESTIC_PARTNER', + FATHER: 'FATHER', + FRIEND: 'FRIEND', + MANAGER: 'MANAGER', + MOTHER: 'MOTHER', + PARENT: 'PARENT', + PARTNER: 'PARTNER', + REFERRED_BY: 'REFERRED_BY', + RELATIVE: 'RELATIVE', + SISTER: 'SISTER', + SPOUSE: 'SPOUSE', + OTHER: 'OTHER', + CUSTOM: 'CUSTOM' +}; + +// An enumerator that indicates the types for instant messenger. +var ContactInstantMessengerType = { + GOOGLE: 'GOOGLE', + WLM: 'WLM', + YAHOO: 'YAHOO', + FACEBOOK: 'FACEBOOK', + ICQ: 'ICQ', + AIM: 'AIM', + QQ: 'QQ', + JABBER: 'JABBER', + SKYPE: 'SKYPE', + IRC: 'IRC', + OTHER: 'OTHER', + CUSTOM: 'CUSTOM' +}; + +// class ContactRef //////////////////////////////////////////////////////// + +var ContactRef = function(data) { + AV.isConstructorCall(this, ContactRef); + var _contactId = ''; + var _addressBookId = ''; + Object.defineProperties(this, { + addressBookId: { + get: function() { + return _addressBookId; + }, + set: function(v) { + _addressBookId = Converter.toString(v, false); + }, + enumerable: true + }, + contactId: { + get: function() { + return _contactId; + }, + set: function(v) { + _contactId = Converter.toString(v, false); + }, + enumerable: true + } + }); + + if (Type.isObject(data)) { + this.addressBookId = data.addressBookId; + this.contactId = data.contactId; + } else { + try { + var args = AV.validateArgs(arguments, [ + { + name: 'addressBookId', + type: AV.Types.STRING, + optional: false, + nullable: false + }, + { + name: 'contactId', + type: AV.Types.STRING, + optional: false, + nullable: false + } + ]); + _addressBookId = args.addressBookId; + _contactId = args.contactId; + } catch (x) { + // Constructors shouldn't throw + } + } +}; + +// class ContactGroup ////////////////////////////////////////////////// + +var ContactGroup = function(name, ringtone, photo) { + AV.isConstructorCall(this, ContactGroup); + + var _id = null; + var _address = null; + var _readOnly = false; + var _name = ''; + var _ringtoneURI = null; + var _photoURI = null; + + if (name && Type.isString(name)) { + _name = name.length ? name : ''; + } + + if (ringtone && Type.isString(ringtone)) { + _ringtoneURI = ringtone.length ? ringtone : null; + } + + if (photo && Type.isString(photo)) { + _photoURI = photo.length ? photo : null; + } + + Object.defineProperties(this, { + id: { + get: function() { + return _id; + }, + set: function(v) { + if (_editGuard.isEditEnabled()) { + _id = Converter.toString(v, true); + } + }, + enumerable: true + }, + addressBookId: { + get: function() { + return _address; + }, + set: function(v) { + if (_editGuard.isEditEnabled()) { + _address = Converter.toString(v, true); + } + }, + enumerable: true + }, + name: { + get: function() { + return _name; + }, + set: function(v) { + _name = Converter.toString(v, false); + }, + enumerable: true + }, + ringtoneURI: { + get: function() { + return _ringtoneURI; + }, + set: function(v) { + _ringtoneURI = Converter.toString(v, true); + }, + enumerable: true + }, + photoURI: { + get: function() { + return _photoURI; + }, + set: function(v) { + _photoURI = Converter.toString(v, true); + }, + enumerable: true + }, + readOnly: { + get: function() { + return _readOnly; + }, + set: function(v) { + if (_editGuard.isEditEnabled()) { + _readOnly = Converter.toBoolean(v, false); + } + }, + enumerable: true + } + }); + + if (_editGuard.isEditEnabled()) { + var data = arguments[0]; + if (Type.isObject(data)) { + for (var prop in data) { + if (this.hasOwnProperty(prop)) { + this[prop] = data[prop]; + } + } + } + } +}; + +// class ContactEmailAddress /////////////////////////////////////////// + +var ContactEmailAddress = function(address, types, isDefault) { + AV.isConstructorCall(this, ContactEmailAddress); + + var _email = ''; + var _label = null; + var _isDefault = false; + var _types = ['WORK']; + + if (Type.isString(address) && address.indexOf('@') > 0 && + address.indexOf('@') !== (address.length - 1)) { + _email = address; + } + + if (Type.isBoolean(isDefault)) { + _isDefault = isDefault; + } + + if (Type.isArray(types)) { + _types = []; + for (var i = 0; i < types.length; ++i) { + if (Type.isString(types[i])) { + _types.push(types[i]); + } + } + } else if (Type.isString(types)) { + _types = []; + _types.push(types); + } + + Object.defineProperties(this, { + email: { + get: function() { + return _email; + }, + set: function(v) { + if (Type.isString(v) && v.indexOf('@') > 0 && + v.indexOf('@') !== (v.length - 1)) { + _email = v; + } + }, + enumerable: true + }, + isDefault: { + get: function() { + return _isDefault; + }, + set: function(v) { + _isDefault = Converter.toBoolean(v, false); + }, + enumerable: true + }, + types: { + get: function() { + return _types; + }, + set: function(v) { + if (Type.isArray(v)) { + _types = []; + for (var i = 0; i < v.length; ++i) { + if (Type.isString(v[i])) { + _types.push(v[i]); + } + } + } else if (Type.isString(v)) { + _types = []; + _types.push(v); + } + }, + enumerable: true + }, + label: { + get: function() { + return _label; + }, + set: function(v) { + _label = Converter.toString(v, true); + }, + enumerable: true + } + }); + + if (_editGuard.isEditEnabled()) { + for (var prop in arguments[0]) { + if (this.hasOwnProperty(prop)) { + this[prop] = arguments[0][prop]; + } + } + } +}; + +// class ContactPhoneNumber //////////////////////////////////////////// + +var ContactPhoneNumber = function(number, type, isDefault) { + AV.isConstructorCall(this, ContactPhoneNumber); + + var _isDefault = false; + var _number = ''; + var _types = ['VOICE']; + + if (Type.isString(number)) { + _number = number; + } + + if (Type.isArray(type)) { + _types = []; + for (var i = 0; i < type.length; ++i) { + _types.push(Converter.toString(type[i], false)); + } + } else if (Type.isString(type)) { + _types = []; + _types.push(type, false); + } + + if (Type.isBoolean(isDefault)) { + _isDefault = isDefault; + } + + Object.defineProperties(this, { + number: { + get: function() { + return _number; + }, + set: function(v) { + _number = Converter.toString(v, false); + }, + enumerable: true + }, + isDefault: { + get: function() { + return _isDefault; + }, + set: function(v) { + _isDefault = Converter.toBoolean(v, false); + }, + enumerable: true + }, + types: { + get: function() { + return _types; + }, + set: function(v) { + if (Type.isArray(v)) { + _types = []; + for (var i = 0; i < v.length; ++i) { + _types.push(Converter.toString(v[i], false)); + } + } else if (Type.isString(v)) { + _types = []; + _types.push(v, false); + } + }, + enumerable: true + }, + label: { + value: null, + writable: true, + enumerable: true + } + }); + + if (_editGuard.isEditEnabled()) { + for (var prop in arguments[0]) { + if (this.hasOwnProperty(prop)) { + this[prop] = arguments[0][prop]; + } + } + } +}; + +// class ContactAddress //////////////////////////////////////////////// + +var ContactAddress = function(data) { + AV.isConstructorCall(this, ContactAddress); + + var _isDefault = false; + var _types = ['HOME']; + + Object.defineProperties(this, { + country: { + value: null, + writable: true, + enumerable: true + }, + region: { + value: null, + writable: true, + enumerable: true + }, + city: { + value: null, + writable: true, + enumerable: true + }, + streetAddress: { + value: null, + writable: true, + enumerable: true + }, + additionalInformation: { + value: null, + writable: true, + enumerable: true + }, + postalCode: { + value: null, + writable: true, + enumerable: true + }, + isDefault: { + get: function() { + return _isDefault; + }, + set: function(v) { + _isDefault = Converter.toBoolean(v, false); + }, + enumerable: true + }, + types: { + get: function() { + return _types; + }, + set: function(v) { + if (Type.isString(v)) { + _types = []; + _types.push(v); + } else if (Type.isArray(v)) { + _types = []; + for (var i = 0; i < v.length; ++i) { + if (Type.isString(v[i])) { + _types.push(v[i]); + } + } + } + }, + enumerable: true + }, + label: { + value: null, + writable: true, + enumerable: true + } + }); + + if (Type.isObject(data)) { + for (var prop in data) { + if (this.hasOwnProperty(prop)) { + this[prop] = data[prop]; + } + } + } +}; + +// class ContactAnniversary //////////////////////////////////////////////// + +var ContactAnniversary = function(anniversary_date, anniversary_label) { + AV.isConstructorCall(this, ContactAnniversary); + + var _anniversary_date = new Date(); + var _anniversary_label = null; + + Object.defineProperties(this, { + date: { + get: function() { + return _anniversary_date; + }, + set: function(v) { + _anniversary_date = v instanceof Date ? v : new Date(); + }, + enumerable: true + }, + label: { + get: function() { + return _anniversary_label; + }, + set: function(v) { + _anniversary_label = Converter.toString(v, true); + }, + enumerable: true + } + }); + + if (_editGuard.isEditEnabled()) { + _anniversary_date = _fromJsonDate(arguments[0].date); + _anniversary_label = arguments[0].label; + } else { + if (Type.isDate(anniversary_date)) { + _anniversary_date = anniversary_date; + } + if (Type.isString(anniversary_label)) { + _anniversary_label = anniversary_label; + } + } +}; + +// class ContactWebSite //////////////////////////////////////////////////// + +var ContactWebSite = function(contact_url, contact_type) { + AV.isConstructorCall(this, ContactWebSite); + + var _url = ''; + var _type = 'HOMEPAGE'; + + if (Type.isString(contact_url)) { + _url = contact_url; + } + if (Type.isString(contact_type)) { + _type = contact_type; + } + + Object.defineProperties(this, { + url: { + get: function() { + return _url; + }, + set: function(v) { + _url = Converter.toString(v, false); + }, + enumerable: true + }, + type: { + get: function() { + return _type; + }, + set: function(v) { + _type = Converter.toString(v, false); + }, + enumerable: true + } + }); +}; + +// class ContactOrganization /////////////////////////////////////////////// + +var ContactOrganization = function(data) { + AV.isConstructorCall(this, ContactOrganization); + Object.defineProperties(this, { + name: { + value: null, + writable: true, + enumerable: true + }, + department: { + value: null, + writable: true, + enumerable: true + }, + title: { + value: null, + writable: true, + enumerable: true + }, + role: { + value: null, + writable: true, + enumerable: true + }, + logoURI: { + value: null, + writable: true, + enumerable: true + } + }); + + if (Type.isObject(data)) { + for (var prop in data) { + if (this.hasOwnProperty(prop)) { + this[prop] = data[prop]; + } + } + } +}; + +// class ContactName /////////////////////////////////////////////////////// + +var ContactName = function(data) { + AV.isConstructorCall(this, ContactName); + + var _displayName = null; + var _nicknames = []; + + Object.defineProperties(this, { + prefix: { + value: null, + writable: true, + enumerable: true + }, + suffix: { + value: null, + writable: true, + enumerable: true + }, + firstName: { + value: null, + writable: true, + enumerable: true + }, + middleName: { + value: null, + writable: true, + enumerable: true + }, + lastName: { + value: null, + writable: true, + enumerable: true + }, + nicknames: { + get: function() { + return _nicknames; + }, + set: function(nicknames) { + if (Type.isArray(nicknames)) { + _nicknames = nicknames; + } + }, + enumerable: true + }, + phoneticFirstName: { + value: null, + writable: true, + enumerable: true + }, + phoneticMiddleName: { + value: null, + writable: true, + enumerable: true + }, + phoneticLastName: { + value: null, + writable: true, + enumerable: true + }, + displayName: { + get: function() { + return _displayName; + }, + set: function(v) { + if (_editGuard.isEditEnabled()) { + _displayName = Converter.toString(v, true); + } + }, + enumerable: true + } + }); + + if (Type.isObject(data)) { + for (var prop in data) { + if (this.hasOwnProperty(prop)) { + this[prop] = data[prop]; + } + } + } +}; + +var ContactRelationship = function(relativeName, type) { + AV.isConstructorCall(this, ContactRelationship); + + var _relativeName = Converter.toString(relativeName, false); + var _type = type ? Converter.toEnum(type, Object.keys(ContactRelationshipType), false) + : ContactRelationshipType.OTHER; + var _label = null; + + Object.defineProperties(this, { + relativeName: { + get: function () { + return _relativeName; + }, + set: function (v) { + _relativeName = Converter.toString(v, false); + }, + enumerable: true + }, + type: { + get: function () { + return _type; + }, + set: function (v) { + _type = v ? Converter.toEnum(v, Object.keys(ContactRelationshipType), false) + : _type; + }, + enumerable: true + }, + label: { + get: function () { + return _label; + }, + set: function (v) { + _label = Converter.toString(v, true); + }, + enumerable: true + } + }); +}; + +var ContactInstantMessenger = function(imAddress, type) { + AV.isConstructorCall(this, ContactInstantMessenger); + + var imAddress_ = ''; + var type_ = 'OTHER'; + + Object.defineProperties(this, { + imAddress: { + get: function() { + return imAddress_; + }, + set: function(v) { + if (Type.isNullOrUndefined(v)) { + return; + } + imAddress_ = Converter.toString(v, false); + }, + enumerable: true + }, + type: { + get: function() { + return type_; + }, + set: function(v) { + if (Type.isNullOrUndefined(v)) { + return; + } + type_ = Converter.toEnum(v, Object.keys(ContactInstantMessengerType), false); + }, + enumerable: true + }, + label: { + value: null, + writable: true, + enumerable: true + } + }); + + this.imAddress = imAddress; + this.type = type; +}; + +// exports ///////////////////////////////////////////////////////////////// +tizen.ContactRef = ContactRef; +tizen.ContactName = ContactName; +tizen.ContactOrganization = ContactOrganization; +tizen.ContactWebSite = ContactWebSite; +tizen.ContactAnniversary = ContactAnniversary; +tizen.ContactAddress = ContactAddress; +tizen.ContactPhoneNumber = ContactPhoneNumber; +tizen.ContactEmailAddress = ContactEmailAddress; +tizen.ContactGroup = ContactGroup; +tizen.ContactRelationship = ContactRelationship; +tizen.ContactInstantMessenger = ContactInstantMessenger; diff --git a/src/contact/js/contact_manager.js b/src/contact/js/contact_manager.js new file mode 100644 index 00000000..c27b5128 --- /dev/null +++ b/src/contact/js/contact_manager.js @@ -0,0 +1,467 @@ +// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + + +var _personListenerRegistered = false; +var _personCallbackMap = {}; +var _personChangeListener = function(result) { + for (var key in _personCallbackMap) { + if (_personCallbackMap.hasOwnProperty(key)) { + if (result.added.length) { + native_.callIfPossible(_personCallbackMap[key].onpersonsadded, + _promote(result.added, Person)); + } + if (result.updated.length) { + native_.callIfPossible(_personCallbackMap[key].onpersonsupdated, + _promote(result.updated, Person)); + } + if (result.removed.length) { + native_.callIfPossible(_personCallbackMap[key].onpersonsremoved, + result.removed); + } + } + } +}; + + +var ContactManager = function() {}; + +// Gets the available address books +ContactManager.prototype.getAddressBooks = function() { + var args = AV.validateArgs(arguments, [ + { + name: 'successCallback', + type: AV.Types.FUNCTION, + optional: false, + nullable: false + }, + { + name: 'errorCallback', + type: AV.Types.FUNCTION, + optional: true, + nullable: true + } + ]); + + var callback = function(result) { + if (native_.isFailure(result)) { + native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); + } else { + var books = native_.getResultObject(result); + var tmp = []; + + books.forEach(function(data) { + return _editGuard.run(function() { + var addressBook = new AddressBook(result.accountId, result.name); + addressBook.id = data.id; + addressBook.readOnly = result.readOnly; + + tmp.push(addressBook); + }); + }); + + native_.callIfPossible(args.successCallback, tmp); + } + }; + + native_.call('ContactManager_getAddressBooks', {}, callback); +}; + +// Gets the aggregation of all address books. +ContactManager.prototype.getUnifiedAddressBook = function() { + // TODO check privileges + //var result = native_.callSync('CheckReadPrivileges', {}); + //if (native_.isFailure(result)) { + // throw new tizen.WebAPIException(WebAPIException.SECURITY_ERR, + // 'You do not have privileges for this operation'); + //} + + return _editGuard.run(function() { + var addressBook = new AddressBook(0, 'Unified address book'); + addressBook.id = UNIFIED_ADDRESSBOOK_ID; + addressBook.readOnly = false; + + return addressBook; + }); +}; + +// Gets the default address book. +ContactManager.prototype.getDefaultAddressBook = function() { + //privileges are checked in getAddressBook function + return this.getAddressBook(DEFAULT_ADDRESSBOOK_ID); +}; + +// Gets the address book with the specified identifier. +ContactManager.prototype.getAddressBook = function() { + var args = AV.validateArgs(arguments, [{ + name: 'addressBookId', + type: AV.Types.STRING, + optional: false, + nullable: false + }]); + + if (String(Converter.toLong(args.addressBookId)) !== args.addressBookId) { + // TCT: ContactManager_getAddressBook_addressBookId_invalid + throw new tizen.WebAPIException(tizen.WebAPIException.NOT_FOUND_ERR); + } + + var result = native_.callSync('ContactManager_getAddressBook', { + addressBookId: args.addressBookId + }); + + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } + + result = native_.getResultObject(result); + + return _editGuard.run(function() { + var addressBook = new AddressBook(result.accountId, result.name); + addressBook.id = args.addressBookId; + addressBook.readOnly = result.readOnly; + + return addressBook; + }); +}; + +ContactManager.prototype.addAddressBook = function() { + var args = AV.validateArgs(arguments, [{ + name: 'addressBook', + type: AV.Types.PLATFORM_OBJECT, + values: tizen.AddressBook, + optional: false, + nullable: false + }]); + + var result = native_.callSync('ContactManager_addAddressBook', { + addressBook: args.addressBook + }); + + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } + + var data = native_.getResultObject(result); + _editGuard.run(function() { + for (var prop in data) { + if (args.addressBook.hasOwnProperty(prop)) { + args.addressBook[prop] = data[prop]; + } + } + }); +}; + +ContactManager.prototype.removeAddressBook = function() { + // TCT: ContactManager_removeAddressBook_misarg + if (Type.isNullOrUndefined(arguments[0])) { + throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR); + } + + var args = AV.validateArgs(arguments, [{ + name: 'addressBookId', + type: AV.Types.STRING, + optional: false, + nullable: false + }]); + + if (args.addressBookId === UNIFIED_ADDRESSBOOK_ID) { + throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR, + 'Unified address book can not be deleted'); + } + + if (args.addressBookId === DEFAULT_ADDRESSBOOK_ID) { + throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR, + 'Default address book can not be deleted'); + } + + var result = native_.callSync('ContactManager_removeAddressBook', { + addressBookId: args.addressBookId + }); + + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } +}; + +// Gets the person with the specified identifier. +ContactManager.prototype.get = function() { + // validation + var args = AV.validateArgs(arguments, [ + { + name: 'personId', + type: AV.Types.STRING, + optional: false, + nullable: false + } + ]); + + if (String(Converter.toLong(args.personId)) !== args.personId) { + // TCT: ContactManager_get_personId_invalid + throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR); + } + + var result = native_.callSync('ContactManager_get', { + personId: args.personId + }); + _checkError(result); + + return _editGuard.run(function() { + return new Person(native_.getResultObject(result)); + }); +}; + +// Updates a person in the address book synchronously. +ContactManager.prototype.update = function() { + // validation + var args = AV.validateArgs(arguments, [{ + name: 'person', + type: AV.Types.PLATFORM_OBJECT, + values: Person, + optional: false, + nullable: false + }]); + var result = native_.callSync('ContactManager_update', { person: args.person }); + _checkError(result); + + result = native_.getResultObject(result); + for (var prop in result) { + if (args.person.hasOwnProperty(prop)) { + args.person[prop] = result[prop]; + } + } +}; + +// Updates several existing persons in the contact DB asynchronously. +ContactManager.prototype.updateBatch = function() { + var args = AV.validateArgs(arguments, [ + { + name: 'persons', + type: AV.Types.ARRAY, + values: Person, + optional: false, + nullable: false + }, + { + name: 'successCallback', + type: AV.Types.FUNCTION, + optional: true, + nullable: true + }, + { + name: 'errorCallback', + type: AV.Types.FUNCTION, + optional: true, + nullable: true + } + ]); + + var callback = function(result) { + if (native_.isFailure(result)) { + native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); + return; + } + + native_.callIfPossible(args.successCallback); + }; + + native_.call('ContactManager_updateBatch', { + addressBook: {}, + batchArgs: _toJsonObject(args.persons) + }, callback); +}; + +// Removes a person from the contact DB synchronously. +ContactManager.prototype.remove = function() { + // validation + var args = AV.validateArgs(arguments, [{ + name: 'personId', + type: AV.Types.STRING, + optional: false, + nullable: false + }]); + + if (String(Converter.toLong(args.personId)) !== args.personId) { + // TCT: ContactManager_remove_personId_invalid + throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR); + } + + var result = native_.callSync('ContactManager_remove', {personId: args.personId}); + _checkError(result); +}; + +// Removes persons from contact DB asynchronously. +ContactManager.prototype.removeBatch = function() { + var args = AV.validateArgs(arguments, [ + { + name: 'personIds', + type: AV.Types.ARRAY, + values: AV.Types.STRING, + optional: false, + nullable: false + }, + { + name: 'successCallback', + type: AV.Types.FUNCTION, + optional: true, + nullable: true + }, + { + name: 'errorCallback', + type: AV.Types.FUNCTION, + optional: true, + nullable: true + } + ]); + + var callback = function(result) { + if (native_.isFailure(result)) { + native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); + return; + } + + native_.callIfPossible(args.successCallback); + }; + + native_.call('ContactManager_removeBatch', { + addressBook: {}, + batchArgs: _toJsonObject(args.personIds) + }, callback); +}; + +// Gets an array of all Person objects from the contact DB or the ones that match the +// optionally supplied filter. +ContactManager.prototype.find = function() { + var args = AV.validateArgs(arguments, [ + { + name: 'successCallback', + type: AV.Types.FUNCTION, + optional: false, + nullable: false + }, + { + name: 'errorCallback', + type: AV.Types.FUNCTION, + optional: true, + nullable: true + }, + { + name: 'filter', + type: AV.Types.PLATFORM_OBJECT, + values: [tizen.AttributeFilter, + tizen.AttributeRangeFilter, + tizen.CompositeFilter], + optional: true, + nullable: true + }, + { + name: 'sortMode', + type: AV.Types.PLATFORM_OBJECT, + values: tizen.SortMode, + optional: true, + nullable: true + } + ]); + + // TODO implement contact filtering/sorting. + var data = { + filter: C.repackFilter(args.filter), + sortMode: args.sortMode + }; + + var self = this; + + var callback = function(result) { + if (native_.isSuccess(result)) { + var _result = native_.getResultObject(result); + var retval = []; + for (var i = 0; i < _result.length; ++i) { + retval.push(self.get(String(_result[i]))); + } + //TODO: Move sorting to native code + retval = C.sort(retval, args.sortMode); + args.successCallback(retval); + } else { + native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); + } + }; + + native_.call('ContactManager_find', data, callback); +}; + +// Subscribes to receive notifications about persons' changes. +ContactManager.prototype.addChangeListener = function() { + var args = AV.validateArgs(arguments, [ + { + name: 'successCallback', + type: AV.Types.LISTENER, + values: ['onpersonsadded', 'onpersonsupdated', 'onpersonsremoved'], + optional: false, + nullable: false + } + ]); + + if (Type.isEmptyObject(_personCallbackMap)) { + var result = native_.callSync('ContactManager_startListening', {}); + + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } + } + + if (!_personListenerRegistered) { + native_.addListener('ContactPersonChangeListener', _personChangeListener); + _personListenerRegistered = true; + } + + var currentWatchId = _getNextWatchId(); + + _personCallbackMap[currentWatchId] = args.successCallback; + + return currentWatchId; +}; + +// Unsubscribes a persons' changes watch operation. +ContactManager.prototype.removeChangeListener = function() { + var args = AV.validateArgs(arguments, [ + { + name: 'watchId', + type: AV.Types.LONG, + optional: false, + nullable: false + } + ]); + + // This makes UTC_contact_removeChangeListenerPerson_N_001 pass. + // watch id's start at 1 + if (args.watchId === 0) { + throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR, + 'id is null or undefined'); + } + + if (args.watchId < 0) { + throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR, + 'Negative watch id'); + } + + if (!_personCallbackMap.hasOwnProperty(args.watchId)) { + throw new tizen.WebAPIException(tizen.WebAPIException.NOT_FOUND_ERR, + 'watch id not found'); + } + + delete _personCallbackMap[args.watchId]; + + if (Type.isEmptyObject(_personCallbackMap)) { + native_.removeListener('ContactPersonChangeListener', _personChangeListener); + _personListenerRegistered = false; + + var result = native_.callSync('ContactManager_stopListening', {}); + + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } + } +}; + +// exports ///////////////////////////////////////////////////////////////// +exports = new ContactManager(); diff --git a/src/contact/js/person.js b/src/contact/js/person.js new file mode 100644 index 00000000..d6c1ef5a --- /dev/null +++ b/src/contact/js/person.js @@ -0,0 +1,182 @@ +// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + + +var Person = function(data) { + AV.isConstructorCall(this, Person); + + var _id = ''; + var _displayName = ''; + var _contactCount = 0; + var _hasPhoneNumber = false; + var _hasEmail = false; + var _isFavorite = false; + var _displayContactId = ''; + + if (data.hasOwnProperty('id') && Type.isString(data.id)) { + _id = data.id; + } + if (data.hasOwnProperty('displayName') && Type.isString(data.displayName)) { + _displayName = data.displayName; + } + if (data.hasOwnProperty('contactCount') && Type.isNumber(data.contactCount)) { + _contactCount = data.contactCount; + } + if (data.hasOwnProperty('hasPhoneNumber') && Type.isBoolean(data.hasPhoneNumber)) { + _hasPhoneNumber = data.hasPhoneNumber; + } + if (data.hasOwnProperty('hasEmail') && Type.isBoolean(data.hasEmail)) { + _hasEmail = data.hasEmail; + } + if (data.hasOwnProperty('displayContactId') && Type.isString(data.displayContactId)) { + _displayContactId = data.displayContactId; + } + if (data.hasOwnProperty('isFavorite') && Type.isBoolean(data.isFavorite)) { + _isFavorite = data.isFavorite; + } + + Object.defineProperties(this, { + id: { + get: function() { + return _id; + }, + set: function(v) { + if (_editGuard.isEditEnabled()) { + _id = Converter.toString(v, false); + } + }, + enumerable: true + }, + displayName: { + get: function() { + return _displayName; + }, + set: function(v) { + if (_editGuard.isEditEnabled()) { + _displayName = Converter.toString(v, false); + } + }, + enumerable: true + }, + contactCount: { + get: function() { + return _contactCount; + }, + set: function(v) { + if (_editGuard.isEditEnabled()) { + _contactCount = Converter.toLong(v, false); + } + }, + enumerable: true + }, + hasPhoneNumber: { + get: function() { + return _hasPhoneNumber; + }, + set: function(v) { + if (_editGuard.isEditEnabled()) { + _hasPhoneNumber = Converter.toBoolean(v, false); + } + }, + enumerable: true + }, + hasEmail: { + get: function() { + return _hasEmail; + }, + set: function(v) { + if (_editGuard.isEditEnabled()) { + _hasEmail = Converter.toBoolean(v, false); + } + }, + enumerable: true + }, + + isFavorite: { + get: function() { + return _isFavorite; + }, + set: function(v) { + _isFavorite = Converter.toBoolean(v, false); + }, + enumerable: true + }, + photoURI: { + value: data.hasOwnProperty('photoURI') ? data.photoURI : null, + writable: true, + enumerable: true + }, + ringtoneURI: { + value: data.hasOwnProperty('ringtoneURI') ? data.ringtoneURI : null, + writable: true, + enumerable: true + }, + displayContactId: { + get: function() { + return _displayContactId; + }, + set: function(v) { + _displayContactId = Converter.toString(v, false); + }, + enumerable: true + } + }); +}; + +// Aggregates another person to this person. +Person.prototype.link = function() { + var args = AV.validateArgs(arguments, [{ + name: 'personId', + type: AV.Types.STRING, + optional: false, + nullable: false + }]); + + if (String(Converter.toLong(args.personId)) !== args.personId) { + // TCT: Person_link_personId_invalid + throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR); + } + + var result = native_.callSync('Person_link', { + // TODO move to only sending the person id (in all functions) + person: this, + id: args.personId + }); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } + var _this = this; + _editGuard.run(function() { + _this.contactCount = _this.contactCount + 1; + }); +}; + +// Separates a contact from this person. +Person.prototype.unlink = function(contactId) { + var args = AV.validateArgs(arguments, [{ + name: 'contactId', + type: AV.Types.STRING, + optional: false, + nullable: false + }]); + + if (String(Converter.toLong(args.contactId)) !== args.contactId) { + // TCT: Person_unlink_contactId_invalid + throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR); + } + + var result = native_.callSync('Person_unlink', { + // TODO move to only sending the person id (in all functions) + person: this, + id: args.contactId + }); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } + var _this = this; + return _editGuard.run(function() { + _this.contactCount = _this.contactCount - 1; + return new Person(native_.getResultObject(result)); + }); +}; diff --git a/src/contact/js/tizen.contact.AddressBook.js b/src/contact/js/tizen.contact.AddressBook.js deleted file mode 100644 index 12190abc..00000000 --- a/src/contact/js/tizen.contact.AddressBook.js +++ /dev/null @@ -1,696 +0,0 @@ -// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -var DEFAULT_ADDRESSBOOK_ID = '0'; -var UNIFIED_ADDRESSBOOK_ID = '-1'; - -var _contactListenerRegistered = false; -var _contactCallbackMap = {}; - -var _filterById = function(array, id) { - var ret = []; - for (var i = 0; i < array.length; ++i) { - if (array[i].addressBookId === id) { - ret.push(_promote(array[i], Contact)); - } - } - return ret; -}; - -var _contactChangeListener = function(result) { - var unifiedId = UNIFIED_ADDRESSBOOK_ID; - var watchId; - var i; - - // Unified address book case - if (_contactCallbackMap.hasOwnProperty(unifiedId)) { - for (watchId in _contactCallbackMap[unifiedId]) { - if (_contactCallbackMap[unifiedId].hasOwnProperty(watchId)) { - var callback = _contactCallbackMap[unifiedId][watchId].successCallback; - if (result.added.length) { - native_.callIfPossible(callback.oncontactsadded, _promote(result.added, Contact)); - } - if (result.updated.length) { - native_.callIfPossible(callback.oncontactsupdated, _promote(result.updated, Contact)); - } - if (result.removed.length) { - var allRemoved = []; - for (i = 0; i < result.removed.length; ++i) { - allRemoved.push(result.removed[i].id); - } - native_.callIfPossible(callback.oncontactsremoved, result.allRemoved); - } - } - } - } - - for (var callbackAddressbookId in _contactCallbackMap) { - if (callbackAddressbookId !== UNIFIED_ADDRESSBOOK_ID && - _contactCallbackMap.hasOwnProperty(callbackAddressbookId)) { - - var filteredAdded = []; - var filteredUpdated = []; - var filteredRemoved = []; - - if (result.added.length) { - filteredAdded = _filterById(result.added, callbackAddressbookId); - } - if (result.updated.length) { - filteredUpdated = _filterById(result.updated, callbackAddressbookId); - } - if (result.removed.length) { - for (i = 0; i < result.removed.length; ++i) { - if (result.removed[i].addressBookId === callbackAddressbookId) { - filteredRemoved.push(result.removed[i].id); - } - } - } - - for (watchId in _contactCallbackMap[callbackAddressbookId]) { - if (_contactCallbackMap[callbackAddressbookId].hasOwnProperty(watchId)) { - var callback = _contactCallbackMap[callbackAddressbookId][watchId].successCallback; - if (filteredAdded.length) { - native_.callIfPossible(callback.oncontactsadded, filteredAdded); - } - if (filteredUpdated.length) { - native_.callIfPossible(callback.oncontactsupdated, filteredUpdated); - } - if (filteredRemoved.length) { - native_.callIfPossible(callback.oncontactsremoved, filteredRemoved); - } - } - } - } - } -}; - - -var AddressBook = function(accountId, name) { - AV.isConstructorCall(this, AddressBook); - - var id_ = null; - var name_ = ''; - var readOnly_ = false; - var accountId_ = null; - - if (Type.isNumber(accountId)) { - accountId_ = accountId; - } - if (Type.isString(name)) { - name_ = name; - } - - Object.defineProperties(this, { - id: { - get: function() { - return id_; - }, - set: function(v) { - if (_editGuard.isEditEnabled()) { - id_ = Converter.toString(v, false); - } - }, - enumerable: true - }, - accountId: { - get: function() { - return accountId_; - }, - set: function(v) { - if (_editGuard.isEditEnabled()) { - accountId_ = Converter.toLong(v, true); - } - }, - enumerable: true - }, - name: { - get: function() { - return name_; - }, - set: function(v) { - if (_editGuard.isEditEnabled()) { - name_ = Converter.toString(v, false); - } - }, - enumerable: true - }, - readOnly: { - get: function() { - return readOnly_; - }, - set: function(v) { - if (_editGuard.isEditEnabled()) { - readOnly_ = Converter.toBoolean(v, false); - } - }, - enumerable: true - } - }); -}; - -AddressBook.prototype.get = function() { - var args = AV.validateArgs(arguments, [{ - name: 'id', - type: AV.Types.STRING, - optional: false, - nullable: false - }]); - - if (String(Converter.toLong(args.id)) !== args.id) { - // TCT: AddressBook_get_id_invalid - throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR); - } - - var result = native_.callSync('AddressBook_get', { - // TODO move to only sending the address book id (in all functions) - addressBook: this, - id: args.id - }); - - if (native_.isFailure(result)) { - throw native_.getErrorObject(result); - } - - return _editGuard.run(function() { - var contact = new Contact(native_.getResultObject(result)); - - if (contact.name instanceof ContactName) { - contact.name.displayName = ''; - if (Type.isString(contact.name.firstName)) { - contact.name.displayName = contact.name.firstName; - if (Type.isString(contact.name.lastName)) { - contact.name.displayName += ' ' + contact.name.lastName; - } - } else if (Type.isArray(contact.name.nicknames) && - Type.isString(contact.name.nicknames[0])) { - contact.name.displayName = contact.name.nicknames[0]; - } else if (Type.isString(contact.name.nicknames)) { - contact.name.displayName = contact.name.nicknames; - } - } - - - - return contact; - }); -}; - -AddressBook.prototype.add = function() { - var args = AV.validateArgs(arguments, [ - { - name: 'contact', - type: AV.Types.PLATFORM_OBJECT, - values: Contact, - optional: false, - nullable: false - } - ]); - - var result = native_.callSync('AddressBook_add', { - // TODO move to only sending the address book id (in all functions) - addressBook: this, - contact: _toJsonObject(args.contact) - }); - - if (native_.isFailure(result)) { - throw native_.getErrorObject(result); - } - - var _updatedContact = native_.getResultObject(result); - _editGuard.run(function() { - for (var prop in _updatedContact) { - if (args.contact.hasOwnProperty(prop)) { - args.contact[prop] = _updatedContact[prop]; - } - } - - if (args.contact.name instanceof ContactName) { - args.contact.name.displayName = ''; - if (Type.isString(args.contact.name.firstName)) { - args.contact.name.displayName = args.contact.name.firstName; - if (Type.isString(args.contact.name.lastName)) { - args.contact.name.displayName += ' ' + args.contact.name.lastName; - } - } else if (Type.isArray(args.contact.name.nicknames) && - Type.isString(args.contact.name.nicknames[0])) { - args.contact.name.displayName = args.contact.name.nicknames[0]; - } else if (Type.isString(args.contact.name.nicknames)) { - args.contact.name.displayName = args.contact.name.nicknames; - } - } - }); -}; - -AddressBook.prototype.addBatch = function() { - var args = AV.validateArgs(arguments, [ - { - name: 'contacts', - type: AV.Types.ARRAY, - value: Contact, - optional: false, - nullable: false - }, - { - name: 'successCallback', - type: AV.Types.FUNCTION, - optional: true, - nullable: true - }, - { - name: 'errorCallback', - type: AV.Types.FUNCTION, - optional: true, - nullable: true - } - - ]); - - var callback = function(result) { - if (native_.isFailure(result)) { - native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); - return; - } - - _editGuard.run(function() { - var _result = native_.getResultObject(result); - for (var i = 0; i < _result.length; ++i) { - for (var prop in _result[i]) { - if (args.contacts[i].hasOwnProperty(prop)) { - args.contacts[i][prop] = _result[i][prop]; - } - } - } - }); - - native_.callIfPossible(args.successCallback, args.contacts); - }; - - native_.call('AddressBook_addBatch', { - addressBookId: this.id, - batchArgs: _toJsonObject(args.contacts) - }, callback); -}; - -AddressBook.prototype.update = function() { - var args = AV.validateArgs(arguments, [ - { - name: 'contact', - type: AV.Types.PLATFORM_OBJECT, - values: Contact, - optional: false, - nullable: false - } - ]); - - var result = native_.callSync('AddressBook_update', { - addressBook: this, - contact: _toJsonObject(args.contact) - }); - - if (native_.isFailure(result)) { - throw native_.getErrorObject(result); - } - - var _updatedContact = native_.getResultObject(result); - _editGuard.run(function() { - for (var prop in _updatedContact) { - if (args.contact.hasOwnProperty(prop)) { - args.contact[prop] = _updatedContact[prop]; - } - } - }); -}; - -AddressBook.prototype.updateBatch = function() { - var args = AV.validateArgs(arguments, [ - { - name: 'contacts', - type: AV.Types.ARRAY, - values: Contact, - optional: false, - nullable: false - }, - { - name: 'successCallback', - type: AV.Types.FUNCTION, - optional: true, - nullable: true - }, - { - name: 'errorCallback', - type: AV.Types.FUNCTION, - optional: true, - nullable: true - } - ]); - - var callback = function(result) { - if (native_.isFailure(result)) { - native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); - return; - } - - _editGuard.run(function() { - var _result = native_.getResultObject(result); - for (var i = 0; i < _result.length; ++i) { - for (var prop in _result[i].result) { - if (args.contacts[i].hasOwnProperty(prop)) { - args.contacts[i][prop] = _result[i].result[prop]; - } - } - } - }); - - native_.callIfPossible(args.successCallback); - }; - - native_.call('AddressBook_updateBatch', { - addressBook: this, - batchArgs: _toJsonObject(args.contacts) - }, callback); -}; - -AddressBook.prototype.remove = function() { - var args = AV.validateArgs(arguments, [{ - name: 'id', - type: AV.Types.STRING, - optional: false, - nullable: false - }]); - - if (String(Converter.toLong(args.id)) !== args.id) { - // TCT: AddressBook_remove_id_invalid - throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR); - } - - var result = native_.callSync('AddressBook_remove', { - addressBook: this, - id: args.id - }); - - if (native_.isFailure(result)) { - throw native_.getErrorObject(result); - } -}; - -AddressBook.prototype.removeBatch = function(ids, successCallback, errorCallback) { - var args = AV.validateArgs(arguments, [ - { - name: 'ids', - type: AV.Types.ARRAY, - values: AV.Types.STRING, - optional: false, - nullable: false - }, - { - name: 'successCallback', - type: AV.Types.FUNCTION, - optional: true, - nullable: true - }, - { - name: 'errorCallback', - type: AV.Types.FUNCTION, - optional: true, - nullable: true - } - ]); - - var callback = function(result) { - if (native_.isFailure(result)) { - native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); - return; - } - - native_.callIfPossible(args.successCallback); - }; - - native_.call('AddressBook_removeBatch', { - addressBook: this, - batchArgs: args.ids - }, callback); -}; - -AddressBook.prototype.find = function(successCallback, errorCallback, filter, sortMode) { - var args = AV.validateArgs(arguments, [ - { - name: 'successCallback', - type: AV.Types.FUNCTION, - optional: false, - nullable: false - }, - { - name: 'errorCallback', - type: AV.Types.FUNCTION, - optional: true, - nullable: true - }, - { - name: 'filter', - type: AV.Types.PLATFORM_OBJECT, - values: [ - tizen.AttributeFilter, - tizen.AttributeRangeFilter, - tizen.CompositeFilter - ], - optional: true, - nullable: true - }, - { - name: 'sortMode', - type: AV.Types.PLATFORM_OBJECT, - values: tizen.SortMode, - optional: true, - nullable: true - } - ]); - - var self = this; - var callback = function(result) { - if (native_.isFailure(result)) { - native_.callIfPossible(errorCallback, native_.getErrorObject(result)); - } - - var _contacts = []; - var _result = native_.getResultObject(result); - _result.forEach(function(data) { - try { - _contacts.push(self.get(String(data))); - } catch (e) {} - }); - - //TODO: Move filtering to native code - try { - _contacts = C.filter(_contacts, args.filter); - } catch (e) { - native_.callIfPossible(errorCallback, e); - return; - } - - //TODO: Move sorting to native code - _contacts = C.sort(_contacts, args.sortMode); - - native_.callIfPossible(successCallback, _contacts); - }; - - native_.call('AddressBook_find', { - addressBook: this, - filter: filter, - sortMode: sortMode - }, callback); -}; - -AddressBook.prototype.addChangeListener = function() { - var args = AV.validateArgs(arguments, [ - { - name: 'successCallback', - type: AV.Types.LISTENER, - values: ['oncontactsadded', 'oncontactsupdated', 'oncontactsremoved'], - optional: false, - nullable: false - }, - { - name: 'errorCallback', - type: AV.Types.FUNCTION, - optional: true, - nullable: true - } - ]); - - if (Type.isEmptyObject(_contactCallbackMap)) { - var result = native_.callSync('AddressBook_startListening', {}); - - if (native_.isFailure(result)) { - throw native_.getErrorObject(result); - } - } - - if (!_contactListenerRegistered) { - native_.addListener('ContactChangeListener', _contactChangeListener); - _contactListenerRegistered = true; - } - - if (!_contactCallbackMap.hasOwnProperty(this.id)) { - _contactCallbackMap[this.id] = {}; - } - - var currentWatchId = _getNextWatchId(); - - _contactCallbackMap[this.id][currentWatchId] = { - successCallback: args.successCallback, - errorCallback: args.errorCallback - }; - - return currentWatchId; -}; - -AddressBook.prototype.removeChangeListener = function(watchId) { - var args = AV.validateArgs(arguments, [ - { - name: 'watchId', - type: AV.Types.LONG, - optional: false, - nullable: false - } - ]); - - if (args.watchId === 0) { - throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR, - 'id is null or undefined'); - } - - if (args.watchId < 0) { - throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR, - 'Negative watch id'); - } - - if (!_contactCallbackMap.hasOwnProperty(this.id) || - !_contactCallbackMap[this.id].hasOwnProperty(args.watchId)) { - throw new tizen.WebAPIException(tizen.WebAPIException.NOT_FOUND_ERR, - 'watch id not found for this address book'); - } - - delete _contactCallbackMap[this.id][args.watchId]; - - if (Type.isEmptyObject(_contactCallbackMap[this.id])) { - delete _contactCallbackMap[this.id]; - } - - if (Type.isEmptyObject(_contactCallbackMap)) { - native_.removeListener('ContactChangeListener', _contactChangeListener); - _contactListenerRegistered = false; - - var result = native_.callSync('AddressBook_stopListening', {}); - - if (native_.isFailure(result)) { - throw native_.getErrorObject(result); - } - } -}; - -AddressBook.prototype.getGroup = function() { - var args = AV.validateArgs(arguments, [{ - name: 'groupId', - type: AV.Types.STRING, - optional: false, - nullable: false - }]); - - if (String(Converter.toLong(args.groupId)) !== args.groupId) { - // TCT: AddressBook_getGroup_groupId_invalid - throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR); - } - - var result = native_.callSync('AddressBook_getGroup', { - addressBook: this, - id: args.groupId - }); - if (native_.isFailure(result)) { - throw native_.getErrorObject(result); - } - - return _editGuard.run(function() { - return new ContactGroup(native_.getResultObject(result)); - }); -}; - -AddressBook.prototype.addGroup = function() { - var args = AV.validateArgs(arguments, [ - { - name: 'group', - type: AV.Types.PLATFORM_OBJECT, - values: ContactGroup, - optional: false, - nullable: false - } - ]); - - var result = native_.callSync('AddressBook_addGroup', - {addressBookId: this.id, group: args.group}); - if (native_.isFailure(result)) { - throw native_.getErrorObject(result); - } - - _editGuard.run(function() { - result = native_.getResultObject(result); - args.group.id = result.id; - args.group.addressBookId = result.addressBookId; - }); -}; - -AddressBook.prototype.updateGroup = function() { - var args = AV.validateArgs(arguments, [ - { - name: 'group', - type: AV.Types.PLATFORM_OBJECT, - values: ContactGroup, - optional: false, - nullable: false - } - ]); - - var result = native_.callSync('AddressBook_updateGroup', - {addressBookId: this.id, group: args.group}); - if (native_.isFailure(result)) { - throw native_.getErrorObject(result); - } -}; - -AddressBook.prototype.removeGroup = function() { - var args = AV.validateArgs(arguments, [{ - name: 'groupId', - type: AV.Types.STRING, - optional: false, - nullable: false - }]); - - if (String(Converter.toLong(args.groupId)) !== args.groupId) { - // TCT: AddressBook_removeGroup_groupId_invalid - throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR); - } - - var result = native_.callSync('AddressBook_removeGroup', - {addressBook: this, id: args.groupId}); - if (native_.isFailure(result)) { - throw native_.getErrorObject(result); - } -}; - -AddressBook.prototype.getGroups = function() { - var result = native_.callSync('AddressBook_getGroups', {addressBook: this}); - if (native_.isFailure(result)) { - throw native_.getErrorObject(result); - } - result = native_.getResultObject(result); - var _tab = []; - _editGuard.run(function() { - result.forEach(function(data) { - _tab.push(new ContactGroup(data)); - }); - }); - return _tab; -}; - -// exports ///////////////////////////////////////////////////////////////// -tizen.AddressBook = AddressBook; diff --git a/src/contact/js/tizen.contact.Common.js b/src/contact/js/tizen.contact.Common.js deleted file mode 100644 index ce1140da..00000000 --- a/src/contact/js/tizen.contact.Common.js +++ /dev/null @@ -1,188 +0,0 @@ -/* global xwalk, extension */ - -// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -var _common = xwalk.utils; -var Type = _common.type; -var Converter = _common.converter; -var AV = _common.validator; - -var native_ = new _common.NativeManager(extension); - -var _currentWatchId = 1; - -var _getNextWatchId = function() { - return _currentWatchId++; -}; - -// Adjusts properties to have the correct format expected by the native side. -// Currently only translates JS Date -var _toJsonObject = function(obj) { - var ret; - if (Type.isDate(obj)) { - var year = ('0000' + obj.getFullYear()).slice(-4); - var month = ('00' + (obj.getMonth() + 1)).slice(-2); - var day = ('00' + obj.getDate()).slice(-2); - return Number(year + month + day); - } - if (Type.isArray(obj)) { - ret = []; - for (var i = 0; i < obj.length; ++i) { - ret[i] = _toJsonObject(obj[i]); - } - return ret; - } - if (obj instanceof Object) { - ret = {}; - for (var prop in obj) { - if (obj.hasOwnProperty(prop)) { - ret[prop] = _toJsonObject(obj[prop]); - } - } - return ret; - } - return obj; -}; - -var _fromJsonDate = function(date) { - date = date + ''; - var year = date.substr(0, 4); - var month = date.substr(4, 2); - var day = date.substr(6, 2); - return new Date(year, month - 1, day); -}; - -var _promote = function(val, type) { - return _editGuard.run(function() { - if (Type.isArray(val)) { - var ret = []; - for (var i = 0; i < val.length; ++i) { - ret.push(new type(val[i])); - } - return ret; - } - return new type(val); - }); -}; - -function _checkError(result) { - if (native_.isFailure(result)) { - throw native_.getErrorObject(result); - } -} - -var TypeEnum = ['VCARD_30']; - -// Edit Guard ////////////////////////////////////////////////////////////// -// This flag is workaround. It is caused by specification -// which tell to edit readonly fields. -var _canEdit = 0; - -var EditGuard = function() { -}; - -EditGuard.prototype.run = function(callback) { - try { - this.enable(); - var result = callback(); - this.disable(); - return result; - } catch (ex) { - this.disable(); - throw ex; - } -}; - -EditGuard.prototype.enable = function() { - _canEdit++; -}; - -EditGuard.prototype.disable = function() { - _canEdit--; -}; - -EditGuard.prototype.isEditEnabled = function() { - return _canEdit > 0; -}; - -var _editGuard = new EditGuard(); - -//TODO: Move sorting and filtering to native code -var Common = function() {}; -Common.prototype.sort = function(arr, sortMode) { - var _getSortProperty = function(obj, props) { - for (var i = 0; i < props.length; ++i) { - if (!obj.hasOwnProperty(props[i])) { - return null; - } - obj = obj[props[i]]; - } - return obj; - }; - - if (sortMode instanceof tizen.SortMode) { - var props = sortMode.attributeName.split('.'); - arr.sort(function(a, b) { - var aValue = _getSortProperty(a, props); - var bValue = _getSortProperty(b, props); - - if (sortMode.order === 'DESC') { - return aValue < bValue; - } - return bValue < aValue; - }); - } - return arr; -}; - -Common.prototype.filter = function(arr, filter) { - if (Type.isNullOrUndefined(arr)) - return arr; - if (filter instanceof tizen.AttributeFilter || - filter instanceof tizen.AttributeRangeFilter || - filter instanceof tizen.CompositeFilter) { - arr = arr.filter(function(element) { - return filter._filter(element); - }); - } - return arr; -}; - -Common.prototype.repackFilter = function (filter) { - if (filter instanceof tizen.AttributeFilter) { - return { - filterType: 'AttributeFilter', - attributeName: filter.attributeName, - matchFlag: filter.matchFlag, - matchValue: filter.matchValue - }; - } - if (filter instanceof tizen.AttributeRangeFilter) { - return { - filterType: 'AttributeRangeFilter', - attributeName: filter.attributeName, - initialValue: Type.isNullOrUndefined(filter.initialValue) ? null : filter.initialValue, - endValue: Type.isNullOrUndefined(filter.endValue) ? null : filter.endValue - }; - } - if (filter instanceof tizen.CompositeFilter) { - var _f = []; - var filters = filter.filters; - - for (var i = 0; i < filters.length; ++i) { - _f.push(this.repackFilter(filters[i])); - } - - return { - filterType: 'CompositeFilter', - type: filter.type, - filters: _f - }; - } - - return null; -}; - -var C = new Common(); diff --git a/src/contact/js/tizen.contact.Contact.js b/src/contact/js/tizen.contact.Contact.js deleted file mode 100644 index cecc8433..00000000 --- a/src/contact/js/tizen.contact.Contact.js +++ /dev/null @@ -1,585 +0,0 @@ -// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -var Contact = function(data) { - AV.isConstructorCall(this, Contact); - - var _forceEditMode = false; - if (Type.isString(data)) { - var result = native_.callSync('ContactManager_importFromVCard', { - 'contact': data - }); - _checkError(result); - - data = native_.getResultObject(result); - // These need to be forced to null as a contact created from a vcard is not added - // to any address book - data.id = null; - data.personId = null; - data.addressBookId = null; - data.lastUpdate = null; - - // Force edit mode so that anonymous objects can be promoted to their correct types. - _forceEditMode = true; - } else if (Type.isObject(data) || Type.isFunction(data)) { - // It's a dictionary - } else { - // null or invalid types. - data = {}; - } - - var _id = null; - var _personId = null; - var _addressBookId = null; - var _lastUpdate = null; - var _isFavorite = false; - var _name = null; - var _addresses = []; - var _photoURI = null; - var _phoneNumbers = []; - var _emails = []; - var _messengers = []; - var _relationships = []; - var _birthday = null; - var _anniversaries = []; - var _organizations = []; - var _notes = []; - var _urls = []; - var _ringtoneURI = null; - var _messageAlertURI = null; - var _vibrationURI = null; - var _groupIds = []; - - var _sanitizeArray = function(arr, type, previousValue) { - if (!Type.isArray(arr)) { - return previousValue; - } - for (var i = 0; i < arr.length; ++i) { - if (Type.isString(type)) { - if (!Type.isString(arr[i])) { - return previousValue; - } - } else if (_editGuard.isEditEnabled()) { - arr[i] = new type(arr[i]); - } else if (!(arr[i] instanceof type)) { - return previousValue; - } - } - return arr; - }; - - Object.defineProperties(this, { - id: { - get: function() { - return _id; - }, - set: function(v) { - if (_editGuard.isEditEnabled()) { - _id = Converter.toString(v, false); - } - }, - enumerable: true - }, - personId: { - get: function() { - return _personId; - }, - set: function(v) { - if (_editGuard.isEditEnabled()) { - _personId = Converter.toString(v, false); - } - }, - enumerable: true - }, - addressBookId: { - get: function() { - return _addressBookId; - }, - set: function(v) { - if (_editGuard.isEditEnabled()) { - _addressBookId = Converter.toString(v, false); - } - }, - enumerable: true - }, - lastUpdated: { - get: function() { - return _lastUpdate; - }, - set: function(v) { - if (_editGuard.isEditEnabled()) { - if (v instanceof Date || v === null) { - _lastUpdate = v; - } else if (Type.isString(v)) { - _lastUpdate = new Date(v); - } else { - _lastUpdate = _fromJsonDate(v); - } - } - }, - enumerable: true - }, - isFavorite: { - get: function() { - return _isFavorite; - }, - set: function(v) { - if (_editGuard.isEditEnabled()) { - _isFavorite = Converter.toBoolean(v, false); - } - }, - enumerable: true - }, - name: { - get: function() { - return _name; - }, - set: function(v) { - if (_editGuard.isEditEnabled()) { - _name = new ContactName(v); - } else { - _name = (v instanceof ContactName || v === null) ? v : _name; - } - }, - enumerable: true - }, - addresses: { - get: function() { - return _addresses; - }, - set: function(v) { - _addresses = _sanitizeArray(v, ContactAddress, _addresses); - }, - enumerable: true - }, - photoURI: { - get: function() { - return _photoURI; - }, - set: function(v) { - _photoURI = Converter.toString(v, true); - }, - enumerable: true - }, - phoneNumbers: { - get: function() { - return _phoneNumbers; - }, - set: function(v) { - _phoneNumbers = _sanitizeArray(v, ContactPhoneNumber, _phoneNumbers); - }, - enumerable: true - }, - emails: { - get: function() { - return _emails; - }, - set: function(v) { - _emails = _sanitizeArray(v, ContactEmailAddress, _emails); - }, - enumerable: true - }, - messengers: { - get: function() { - return _messengers; - }, - set: function(v) { - _messengers = _sanitizeArray(v, ContactInstantMessenger, _messengers); - }, - enumerable: true - }, - relationships: { - get: function() { - return _relationships; - }, - set: function(v) { - _relationships = _sanitizeArray(v, ContactRelationship, _relationships); - }, - enumerable: true - }, - birthday: { - get: function() { - return _birthday; - }, - set: function(v) { - if (v instanceof Date || v === null) { - _birthday = v; - } else if (Type.isString(v)) { - _birthday = new Date(v); - } else if (_editGuard.isEditEnabled()) { - _birthday = _fromJsonDate(v); - } - }, - enumerable: true - }, - anniversaries: { - get: function() { - return _anniversaries; - }, - set: function(v) { - _anniversaries = _sanitizeArray(v, ContactAnniversary, _anniversaries); - }, - enumerable: true - }, - organizations: { - get: function() { - return _organizations; - }, - set: function(v) { - _organizations = _sanitizeArray(v, ContactOrganization, _organizations); - }, - enumerable: true - }, - notes: { - get: function() { - return _notes; - }, - set: function(v) { - _notes = _sanitizeArray(v, '', _notes); - }, - enumerable: true - }, - urls: { - get: function() { - return _urls; - }, - set: function(v) { - _urls = _sanitizeArray(v, ContactWebSite, _urls); - }, - enumerable: true - }, - ringtoneURI: { - get: function() { - return _ringtoneURI; - }, - set: function(v) { - _ringtoneURI = Converter.toString(v, true); - }, - enumerable: true - }, - messageAlertURI: { - get: function() { - return _messageAlertURI; - }, - set: function(v) { - _messageAlertURI = Converter.toString(v, true); - }, - enumerable: true - }, - vibrationURI: { - get: function() { - return _vibrationURI; - }, - set: function(v) { - _vibrationURI = Converter.toString(v, true); - }, - enumerable: true - }, - groupIds: { - get: function() { - return _groupIds; - }, - set: function(v) { - _groupIds = _sanitizeArray(v, '', _groupIds); - }, - enumerable: true - } - }); - - var _this = this; - var _setProperties = function() { - for (var p in _this) { - if (data.hasOwnProperty(p)) { - _this[p] = data[p]; - } - } - }; - - if (_forceEditMode) { - _editGuard.run(_setProperties); - } else { - _setProperties(); - } - -}; - -// Auxiliary functions ///////////////////////////////////////////////////// - -// Convert address from Contact object to string -var _contactAddressToString = function(obj) { - var str = ''; - if (obj.addresses.length === 0) { - return ''; - } - // Sorry for so many if statements, but the IDE makes me do it - for (var it in obj.addresses) { - if (!it instanceof ContactAddress) { - continue; - } - str += 'ADR;'; - for (var addType in it.types) { - if (Type.isString(addType)) { - str += addType + ','; - } - } - if (str.charAt(str.length - 1) === ',') { - str[str.length - 1] = ':'; - } - str += ';'; // because of we don't keep Post office addres - // which is part of vCard 3.0 standard - str += it.additionalInformation + ';'; - str += it.streetAddress + ';'; - str += it.city + ';'; - str += it.region + ';'; - str += it.postalCode + ';'; - str += it.country + ';'; - str += '\n'; - } - return str; -}; - -// Convert email address from Contact object to string -var _contactEmailToString = function(obj) { - if (!Type.isArray(obj.emails) || obj.emails.length === 0) { - console.log('Empty email list'); - return ''; - } - var str = ''; - for (var mail in obj.emails) { - if (!mail instanceof ContactEmailAddress || !Type.isArray(mail.types) || - mail.types.length === 0) { - console.log('Incorrect email type'); - continue; - } - str += 'EMAIL;'; - // set types - for (var type in mail.types) { - if (Type.isString(type)) { - str += type + ','; - } - } - if (str.charAt(str.length - 1) === ',') { - str[str.length - 1] = ':'; - } - str += '=' + Converter.toString(mail.email) + '\n'; - } - return str; -}; - -// Convert organizations info from Contact object to string -var _contactOrganizationToString = function(obj) { - if (obj.organizations.length === 0 || - !obj.organizations[0] instanceof ContactOrganization) { - return ''; - } - var str = ''; - for (var org in obj.organizations) { - if (!org instanceof ContactOrganization) { - continue; - } - str += 'ORG:'; - str += org.name + ';' + org.department + ';' + org.title + '\n'; - } - return str; -}; - -// Convert organizations roles from Contact object to string -var _contactRoleToString = function(obj) { - if (obj.organizations.length === 0 || - !obj.organizations[0] instanceof ContactOrganization) { - return ''; - } - var str = ''; - for (var org in obj.organizations) { - if (!org instanceof ContactOrganization) { - continue; - } - str += 'ROLE:'; - str += org.name + ';' + org.role + '\n'; - } - return str; -}; - -// Convert phone numbers from Contact object to string -var _contactPhoneNumbersToString = function(obj) { - if (obj.phoneNumbers.length === 0 || !obj.phoneNumbers[0] instanceof ContactPhoneNumber) { - return ''; - } - var str = ''; - for (var phone in obj.phoneNumbers) { - if (!phone instanceof ContactPhoneNumber) { - continue; - } - str += 'TEL'; - for (var type in phone.types) { - if (Type.isString(type)) { - str += ';' + type; - } - } - str += ':'; - str += phone.number + '\n'; - } - return str; -}; - -// Convert urls from Contact object to string -var _contactURLToString = function(obj) { - if (obj.urls.length === 0 || !obj.urls[0] instanceof ContactWebSite) { - return ''; - } - var str = ''; - for (var url in obj.urls) { - if (url instanceof ContactWebSite) { - str += 'URL:' + url.url + '\n'; - } - } - return str; -}; - -// Convert anniversaries to string -var _contactAnniversaryToString = function(obj) { - if (obj.anniversaries.length === 0 || !obj.anniversaries[0] instanceof ContactAnniversary) { - return ''; - } - var str = ''; - for (var ann in obj.anniversaries) { - if (ann instanceof ContactAnniversary) { - str += 'X-ANNIVERSARY;' + ann.label + ':' + ann.date + ';' + '\n'; - } - } - return str; -}; - -// Convert relationships to string -var _contactRelationshipsToString = function(obj) { - if (obj.relationships.length === 0 || - !obj.relationships[0] instanceof ContactRelationship) { - return ''; - } - var str = ''; - for (var rel in obj.relationships) { - if (rel instanceof ContactRelationship) { - str += 'X-RELATIONSHIP;' + rel.relativeName + ':' + rel.type + - ':' + rel.label + ';\n'; - } - } - return str; -}; - -// Convert messengers to string -var _contactInstantMessengeToString = function(obj) { - if (obj.messengers.length === 0 || !obj.messengers[0] instanceof ContactInstantMessenger) { - return ''; - } - var str = ''; - for (var messenger in obj.messengers) { - if (messenger instanceof ContactInstantMessenger) { - str += 'X-MESSANGER;' + messenger.imAddress + ':' + messenger.type + - ':' + messenger.label + ';\n'; - } - } - return str; -}; - -// Auxiliary function, allows to parse JSON to Contact -var _JSONToContactType = function(type, obj) { - var contact = new type(); - - for (var prop in obj) { - if (contact.hasOwnProperty(prop)) { - if (contact[prop] instanceof Date && Type.isNumber(obj[prop])) { - contact[prop] = new Date(1000 * obj[prop]); - } else { - contact[prop] = obj[prop]; - } - } - } - - return contact; -}; - -// Converts the Contact item to a string format. -Contact.prototype.convertToString = function(format) { - format = format || TypeEnum[0]; - - if (!Type.isString(format)) { - throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR, 'Invalid format'); - } - - if (TypeEnum.indexOf(format) < 0) { - throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR, 'Invalid format'); - } - - if (this.id === '') { - throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR, - 'Contact ID is empty.'); - } - - var str = 'BEGIN:VCARD\nVERSION:3.0\n'; - - // set contact name - str += 'N:' + this.name.lastName + ';' + this.name.firstName + ';' + - this.name.middleName + ';' + this.name.prefix + ';' + this.name.suffix + '\n'; - str += 'FN' + this.name.displayName + '\n'; - - // set phonetic names - str += 'X-PHONETIC-FIRST-NAME' + this.name.phoneticFirstName + '\n' + - 'X-PHONETIC-LAST-NAME' + this.name.phoneticLastName + '\n'; - - // set contact address - str += _contactAddressToString(this); - - // set Birthday - if (this.birthday) { - str += 'BDAY:' + this.birthday.getYear() + '-' + this.birthday.getMonth() + - '-' + this.birthday.getDay() + '\n'; - } - - // set anniversary - str += _contactAnniversaryToString(this); - - // set relationship - str += _contactRelationshipsToString(this); - - // set emails - str += _contactEmailToString(this); - - // set organization data - str += _contactOrganizationToString(this); - - // set role - str += _contactRoleToString(this); - - // set phone numbers - str += _contactPhoneNumbersToString(this); - - // set user ID - str += 'UID:' + this.id + '\n'; - - // set isFavorite - str += 'X-IS-FAVORITE' + this.isFavorite + '\n'; - - // set URLs - str += _contactURLToString(this); - - // set messengers - str += _contactInstantMessengeToString(this); - - // set last revision - str += 'REV:' + this.lastUpdated.getYear() + '-' + this.lastUpdated.getMonth() + - '-' + this.lastUpdated.getDay() + 'T' + this.lastUpdated.getHours() + ':' + - this.lastUpdated.getMinutes() + ':' + this.lastUpdated.getSeconds() + 'Z\n'; - - str += 'END:VCARD\n'; - - return str; -}; - -// Creates a clone of the Contact object, detached from any address book -Contact.prototype.clone = function() { - return new Contact(this); -}; - -// exports ///////////////////////////////////////////////////////////////// -tizen.Contact = Contact; diff --git a/src/contact/js/tizen.contact.ContactDataStructures.js b/src/contact/js/tizen.contact.ContactDataStructures.js deleted file mode 100644 index eab62563..00000000 --- a/src/contact/js/tizen.contact.ContactDataStructures.js +++ /dev/null @@ -1,743 +0,0 @@ -// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// An enumerator that indicates the types for the relationships. -var ContactRelationshipType = { - ASSISTANT: 'ASSISTANT', - BROTHER: 'BROTHER', - CHILD: 'CHILD', - DOMESTIC_PARTNER: 'DOMESTIC_PARTNER', - FATHER: 'FATHER', - FRIEND: 'FRIEND', - MANAGER: 'MANAGER', - MOTHER: 'MOTHER', - PARENT: 'PARENT', - PARTNER: 'PARTNER', - REFERRED_BY: 'REFERRED_BY', - RELATIVE: 'RELATIVE', - SISTER: 'SISTER', - SPOUSE: 'SPOUSE', - OTHER: 'OTHER', - CUSTOM: 'CUSTOM' -}; - -// An enumerator that indicates the types for instant messenger. -var ContactInstantMessengerType = { - GOOGLE: 'GOOGLE', - WLM: 'WLM', - YAHOO: 'YAHOO', - FACEBOOK: 'FACEBOOK', - ICQ: 'ICQ', - AIM: 'AIM', - QQ: 'QQ', - JABBER: 'JABBER', - SKYPE: 'SKYPE', - IRC: 'IRC', - OTHER: 'OTHER', - CUSTOM: 'CUSTOM' -}; - -// class ContactRef //////////////////////////////////////////////////////// - -var ContactRef = function(data) { - AV.isConstructorCall(this, ContactRef); - var _contactId = ''; - var _addressBookId = ''; - Object.defineProperties(this, { - addressBookId: { - get: function() { - return _addressBookId; - }, - set: function(v) { - _addressBookId = Converter.toString(v, false); - }, - enumerable: true - }, - contactId: { - get: function() { - return _contactId; - }, - set: function(v) { - _contactId = Converter.toString(v, false); - }, - enumerable: true - } - }); - - if (Type.isObject(data)) { - this.addressBookId = data.addressBookId; - this.contactId = data.contactId; - } else { - try { - var args = AV.validateArgs(arguments, [ - { - name: 'addressBookId', - type: AV.Types.STRING, - optional: false, - nullable: false - }, - { - name: 'contactId', - type: AV.Types.STRING, - optional: false, - nullable: false - } - ]); - _addressBookId = args.addressBookId; - _contactId = args.contactId; - } catch (x) { - // Constructors shouldn't throw - } - } -}; - -// class ContactGroup ////////////////////////////////////////////////// - -var ContactGroup = function(name, ringtone, photo) { - AV.isConstructorCall(this, ContactGroup); - - var _id = null; - var _address = null; - var _readOnly = false; - var _name = ''; - var _ringtoneURI = null; - var _photoURI = null; - - if (name && Type.isString(name)) { - _name = name.length ? name : ''; - } - - if (ringtone && Type.isString(ringtone)) { - _ringtoneURI = ringtone.length ? ringtone : null; - } - - if (photo && Type.isString(photo)) { - _photoURI = photo.length ? photo : null; - } - - Object.defineProperties(this, { - id: { - get: function() { - return _id; - }, - set: function(v) { - if (_editGuard.isEditEnabled()) { - _id = Converter.toString(v, true); - } - }, - enumerable: true - }, - addressBookId: { - get: function() { - return _address; - }, - set: function(v) { - if (_editGuard.isEditEnabled()) { - _address = Converter.toString(v, true); - } - }, - enumerable: true - }, - name: { - get: function() { - return _name; - }, - set: function(v) { - _name = Converter.toString(v, false); - }, - enumerable: true - }, - ringtoneURI: { - get: function() { - return _ringtoneURI; - }, - set: function(v) { - _ringtoneURI = Converter.toString(v, true); - }, - enumerable: true - }, - photoURI: { - get: function() { - return _photoURI; - }, - set: function(v) { - _photoURI = Converter.toString(v, true); - }, - enumerable: true - }, - readOnly: { - get: function() { - return _readOnly; - }, - set: function(v) { - if (_editGuard.isEditEnabled()) { - _readOnly = Converter.toBoolean(v, false); - } - }, - enumerable: true - } - }); - - if (_editGuard.isEditEnabled()) { - var data = arguments[0]; - if (Type.isObject(data)) { - for (var prop in data) { - if (this.hasOwnProperty(prop)) { - this[prop] = data[prop]; - } - } - } - } -}; - -// class ContactEmailAddress /////////////////////////////////////////// - -var ContactEmailAddress = function(address, types, isDefault) { - AV.isConstructorCall(this, ContactEmailAddress); - - var _email = ''; - var _label = null; - var _isDefault = false; - var _types = ['WORK']; - - if (Type.isString(address) && address.indexOf('@') > 0 && - address.indexOf('@') !== (address.length - 1)) { - _email = address; - } - - if (Type.isBoolean(isDefault)) { - _isDefault = isDefault; - } - - if (Type.isArray(types)) { - _types = []; - for (var i = 0; i < types.length; ++i) { - if (Type.isString(types[i])) { - _types.push(types[i]); - } - } - } else if (Type.isString(types)) { - _types = []; - _types.push(types); - } - - Object.defineProperties(this, { - email: { - get: function() { - return _email; - }, - set: function(v) { - if (Type.isString(v) && v.indexOf('@') > 0 && - v.indexOf('@') !== (v.length - 1)) { - _email = v; - } - }, - enumerable: true - }, - isDefault: { - get: function() { - return _isDefault; - }, - set: function(v) { - _isDefault = Converter.toBoolean(v, false); - }, - enumerable: true - }, - types: { - get: function() { - return _types; - }, - set: function(v) { - if (Type.isArray(v)) { - _types = []; - for (var i = 0; i < v.length; ++i) { - if (Type.isString(v[i])) { - _types.push(v[i]); - } - } - } else if (Type.isString(v)) { - _types = []; - _types.push(v); - } - }, - enumerable: true - }, - label: { - get: function() { - return _label; - }, - set: function(v) { - _label = Converter.toString(v, true); - }, - enumerable: true - } - }); - - if (_editGuard.isEditEnabled()) { - for (var prop in arguments[0]) { - if (this.hasOwnProperty(prop)) { - this[prop] = arguments[0][prop]; - } - } - } -}; - -// class ContactPhoneNumber //////////////////////////////////////////// - -var ContactPhoneNumber = function(number, type, isDefault) { - AV.isConstructorCall(this, ContactPhoneNumber); - - var _isDefault = false; - var _number = ''; - var _types = ['VOICE']; - - if (Type.isString(number)) { - _number = number; - } - - if (Type.isArray(type)) { - _types = []; - for (var i = 0; i < type.length; ++i) { - _types.push(Converter.toString(type[i], false)); - } - } else if (Type.isString(type)) { - _types = []; - _types.push(type, false); - } - - if (Type.isBoolean(isDefault)) { - _isDefault = isDefault; - } - - Object.defineProperties(this, { - number: { - get: function() { - return _number; - }, - set: function(v) { - _number = Converter.toString(v, false); - }, - enumerable: true - }, - isDefault: { - get: function() { - return _isDefault; - }, - set: function(v) { - _isDefault = Converter.toBoolean(v, false); - }, - enumerable: true - }, - types: { - get: function() { - return _types; - }, - set: function(v) { - if (Type.isArray(v)) { - _types = []; - for (var i = 0; i < v.length; ++i) { - _types.push(Converter.toString(v[i], false)); - } - } else if (Type.isString(v)) { - _types = []; - _types.push(v, false); - } - }, - enumerable: true - }, - label: { - value: null, - writable: true, - enumerable: true - } - }); - - if (_editGuard.isEditEnabled()) { - for (var prop in arguments[0]) { - if (this.hasOwnProperty(prop)) { - this[prop] = arguments[0][prop]; - } - } - } -}; - -// class ContactAddress //////////////////////////////////////////////// - -var ContactAddress = function(data) { - AV.isConstructorCall(this, ContactAddress); - - var _isDefault = false; - var _types = ['HOME']; - - Object.defineProperties(this, { - country: { - value: null, - writable: true, - enumerable: true - }, - region: { - value: null, - writable: true, - enumerable: true - }, - city: { - value: null, - writable: true, - enumerable: true - }, - streetAddress: { - value: null, - writable: true, - enumerable: true - }, - additionalInformation: { - value: null, - writable: true, - enumerable: true - }, - postalCode: { - value: null, - writable: true, - enumerable: true - }, - isDefault: { - get: function() { - return _isDefault; - }, - set: function(v) { - _isDefault = Converter.toBoolean(v, false); - }, - enumerable: true - }, - types: { - get: function() { - return _types; - }, - set: function(v) { - if (Type.isString(v)) { - _types = []; - _types.push(v); - } else if (Type.isArray(v)) { - _types = []; - for (var i = 0; i < v.length; ++i) { - if (Type.isString(v[i])) { - _types.push(v[i]); - } - } - } - }, - enumerable: true - }, - label: { - value: null, - writable: true, - enumerable: true - } - }); - - if (Type.isObject(data)) { - for (var prop in data) { - if (this.hasOwnProperty(prop)) { - this[prop] = data[prop]; - } - } - } -}; - -// class ContactAnniversary //////////////////////////////////////////////// - -var ContactAnniversary = function(anniversary_date, anniversary_label) { - AV.isConstructorCall(this, ContactAnniversary); - - var _anniversary_date = new Date(); - var _anniversary_label = null; - - Object.defineProperties(this, { - date: { - get: function() { - return _anniversary_date; - }, - set: function(v) { - _anniversary_date = v instanceof Date ? v : new Date(); - }, - enumerable: true - }, - label: { - get: function() { - return _anniversary_label; - }, - set: function(v) { - _anniversary_label = Converter.toString(v, true); - }, - enumerable: true - } - }); - - if (_editGuard.isEditEnabled()) { - _anniversary_date = _fromJsonDate(arguments[0].date); - _anniversary_label = arguments[0].label; - } else { - if (Type.isDate(anniversary_date)) { - _anniversary_date = anniversary_date; - } - if (Type.isString(anniversary_label)) { - _anniversary_label = anniversary_label; - } - } -}; - -// class ContactWebSite //////////////////////////////////////////////////// - -var ContactWebSite = function(contact_url, contact_type) { - AV.isConstructorCall(this, ContactWebSite); - - var _url = ''; - var _type = 'HOMEPAGE'; - - if (Type.isString(contact_url)) { - _url = contact_url; - } - if (Type.isString(contact_type)) { - _type = contact_type; - } - - Object.defineProperties(this, { - url: { - get: function() { - return _url; - }, - set: function(v) { - _url = Converter.toString(v, false); - }, - enumerable: true - }, - type: { - get: function() { - return _type; - }, - set: function(v) { - _type = Converter.toString(v, false); - }, - enumerable: true - } - }); -}; - -// class ContactOrganization /////////////////////////////////////////////// - -var ContactOrganization = function(data) { - AV.isConstructorCall(this, ContactOrganization); - Object.defineProperties(this, { - name: { - value: null, - writable: true, - enumerable: true - }, - department: { - value: null, - writable: true, - enumerable: true - }, - title: { - value: null, - writable: true, - enumerable: true - }, - role: { - value: null, - writable: true, - enumerable: true - }, - logoURI: { - value: null, - writable: true, - enumerable: true - } - }); - - if (Type.isObject(data)) { - for (var prop in data) { - if (this.hasOwnProperty(prop)) { - this[prop] = data[prop]; - } - } - } -}; - -// class ContactName /////////////////////////////////////////////////////// - -var ContactName = function(data) { - AV.isConstructorCall(this, ContactName); - - var _displayName = null; - var _nicknames = []; - - Object.defineProperties(this, { - prefix: { - value: null, - writable: true, - enumerable: true - }, - suffix: { - value: null, - writable: true, - enumerable: true - }, - firstName: { - value: null, - writable: true, - enumerable: true - }, - middleName: { - value: null, - writable: true, - enumerable: true - }, - lastName: { - value: null, - writable: true, - enumerable: true - }, - nicknames: { - get: function() { - return _nicknames; - }, - set: function(nicknames) { - if (Type.isArray(nicknames)) { - _nicknames = nicknames; - } - }, - enumerable: true - }, - phoneticFirstName: { - value: null, - writable: true, - enumerable: true - }, - phoneticMiddleName: { - value: null, - writable: true, - enumerable: true - }, - phoneticLastName: { - value: null, - writable: true, - enumerable: true - }, - displayName: { - get: function() { - return _displayName; - }, - set: function(v) { - if (_editGuard.isEditEnabled()) { - _displayName = Converter.toString(v, true); - } - }, - enumerable: true - } - }); - - if (Type.isObject(data)) { - for (var prop in data) { - if (this.hasOwnProperty(prop)) { - this[prop] = data[prop]; - } - } - } -}; - -var ContactRelationship = function(relativeName, type) { - AV.isConstructorCall(this, ContactRelationship); - - var _relativeName = Converter.toString(relativeName, false); - var _type = type ? Converter.toEnum(type, Object.keys(ContactRelationshipType), false) - : ContactRelationshipType.OTHER; - var _label = null; - - Object.defineProperties(this, { - relativeName: { - get: function () { - return _relativeName; - }, - set: function (v) { - _relativeName = Converter.toString(v, false); - }, - enumerable: true - }, - type: { - get: function () { - return _type; - }, - set: function (v) { - _type = v ? Converter.toEnum(v, Object.keys(ContactRelationshipType), false) - : _type; - }, - enumerable: true - }, - label: { - get: function () { - return _label; - }, - set: function (v) { - _label = Converter.toString(v, true); - }, - enumerable: true - } - }); -}; - -var ContactInstantMessenger = function(imAddress, type) { - AV.isConstructorCall(this, ContactInstantMessenger); - - var imAddress_ = ''; - var type_ = 'OTHER'; - - Object.defineProperties(this, { - imAddress: { - get: function() { - return imAddress_; - }, - set: function(v) { - if (Type.isNullOrUndefined(v)) { - return; - } - imAddress_ = Converter.toString(v, false); - }, - enumerable: true - }, - type: { - get: function() { - return type_; - }, - set: function(v) { - if (Type.isNullOrUndefined(v)) { - return; - } - type_ = Converter.toEnum(v, Object.keys(ContactInstantMessengerType), false); - }, - enumerable: true - }, - label: { - value: null, - writable: true, - enumerable: true - } - }); - - this.imAddress = imAddress; - this.type = type; -}; - -// exports ///////////////////////////////////////////////////////////////// -tizen.ContactRef = ContactRef; -tizen.ContactName = ContactName; -tizen.ContactOrganization = ContactOrganization; -tizen.ContactWebSite = ContactWebSite; -tizen.ContactAnniversary = ContactAnniversary; -tizen.ContactAddress = ContactAddress; -tizen.ContactPhoneNumber = ContactPhoneNumber; -tizen.ContactEmailAddress = ContactEmailAddress; -tizen.ContactGroup = ContactGroup; -tizen.ContactRelationship = ContactRelationship; -tizen.ContactInstantMessenger = ContactInstantMessenger; diff --git a/src/contact/js/tizen.contact.ContactManager.js b/src/contact/js/tizen.contact.ContactManager.js deleted file mode 100644 index c27b5128..00000000 --- a/src/contact/js/tizen.contact.ContactManager.js +++ /dev/null @@ -1,467 +0,0 @@ -// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - - -var _personListenerRegistered = false; -var _personCallbackMap = {}; -var _personChangeListener = function(result) { - for (var key in _personCallbackMap) { - if (_personCallbackMap.hasOwnProperty(key)) { - if (result.added.length) { - native_.callIfPossible(_personCallbackMap[key].onpersonsadded, - _promote(result.added, Person)); - } - if (result.updated.length) { - native_.callIfPossible(_personCallbackMap[key].onpersonsupdated, - _promote(result.updated, Person)); - } - if (result.removed.length) { - native_.callIfPossible(_personCallbackMap[key].onpersonsremoved, - result.removed); - } - } - } -}; - - -var ContactManager = function() {}; - -// Gets the available address books -ContactManager.prototype.getAddressBooks = function() { - var args = AV.validateArgs(arguments, [ - { - name: 'successCallback', - type: AV.Types.FUNCTION, - optional: false, - nullable: false - }, - { - name: 'errorCallback', - type: AV.Types.FUNCTION, - optional: true, - nullable: true - } - ]); - - var callback = function(result) { - if (native_.isFailure(result)) { - native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); - } else { - var books = native_.getResultObject(result); - var tmp = []; - - books.forEach(function(data) { - return _editGuard.run(function() { - var addressBook = new AddressBook(result.accountId, result.name); - addressBook.id = data.id; - addressBook.readOnly = result.readOnly; - - tmp.push(addressBook); - }); - }); - - native_.callIfPossible(args.successCallback, tmp); - } - }; - - native_.call('ContactManager_getAddressBooks', {}, callback); -}; - -// Gets the aggregation of all address books. -ContactManager.prototype.getUnifiedAddressBook = function() { - // TODO check privileges - //var result = native_.callSync('CheckReadPrivileges', {}); - //if (native_.isFailure(result)) { - // throw new tizen.WebAPIException(WebAPIException.SECURITY_ERR, - // 'You do not have privileges for this operation'); - //} - - return _editGuard.run(function() { - var addressBook = new AddressBook(0, 'Unified address book'); - addressBook.id = UNIFIED_ADDRESSBOOK_ID; - addressBook.readOnly = false; - - return addressBook; - }); -}; - -// Gets the default address book. -ContactManager.prototype.getDefaultAddressBook = function() { - //privileges are checked in getAddressBook function - return this.getAddressBook(DEFAULT_ADDRESSBOOK_ID); -}; - -// Gets the address book with the specified identifier. -ContactManager.prototype.getAddressBook = function() { - var args = AV.validateArgs(arguments, [{ - name: 'addressBookId', - type: AV.Types.STRING, - optional: false, - nullable: false - }]); - - if (String(Converter.toLong(args.addressBookId)) !== args.addressBookId) { - // TCT: ContactManager_getAddressBook_addressBookId_invalid - throw new tizen.WebAPIException(tizen.WebAPIException.NOT_FOUND_ERR); - } - - var result = native_.callSync('ContactManager_getAddressBook', { - addressBookId: args.addressBookId - }); - - if (native_.isFailure(result)) { - throw native_.getErrorObject(result); - } - - result = native_.getResultObject(result); - - return _editGuard.run(function() { - var addressBook = new AddressBook(result.accountId, result.name); - addressBook.id = args.addressBookId; - addressBook.readOnly = result.readOnly; - - return addressBook; - }); -}; - -ContactManager.prototype.addAddressBook = function() { - var args = AV.validateArgs(arguments, [{ - name: 'addressBook', - type: AV.Types.PLATFORM_OBJECT, - values: tizen.AddressBook, - optional: false, - nullable: false - }]); - - var result = native_.callSync('ContactManager_addAddressBook', { - addressBook: args.addressBook - }); - - if (native_.isFailure(result)) { - throw native_.getErrorObject(result); - } - - var data = native_.getResultObject(result); - _editGuard.run(function() { - for (var prop in data) { - if (args.addressBook.hasOwnProperty(prop)) { - args.addressBook[prop] = data[prop]; - } - } - }); -}; - -ContactManager.prototype.removeAddressBook = function() { - // TCT: ContactManager_removeAddressBook_misarg - if (Type.isNullOrUndefined(arguments[0])) { - throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR); - } - - var args = AV.validateArgs(arguments, [{ - name: 'addressBookId', - type: AV.Types.STRING, - optional: false, - nullable: false - }]); - - if (args.addressBookId === UNIFIED_ADDRESSBOOK_ID) { - throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR, - 'Unified address book can not be deleted'); - } - - if (args.addressBookId === DEFAULT_ADDRESSBOOK_ID) { - throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR, - 'Default address book can not be deleted'); - } - - var result = native_.callSync('ContactManager_removeAddressBook', { - addressBookId: args.addressBookId - }); - - if (native_.isFailure(result)) { - throw native_.getErrorObject(result); - } -}; - -// Gets the person with the specified identifier. -ContactManager.prototype.get = function() { - // validation - var args = AV.validateArgs(arguments, [ - { - name: 'personId', - type: AV.Types.STRING, - optional: false, - nullable: false - } - ]); - - if (String(Converter.toLong(args.personId)) !== args.personId) { - // TCT: ContactManager_get_personId_invalid - throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR); - } - - var result = native_.callSync('ContactManager_get', { - personId: args.personId - }); - _checkError(result); - - return _editGuard.run(function() { - return new Person(native_.getResultObject(result)); - }); -}; - -// Updates a person in the address book synchronously. -ContactManager.prototype.update = function() { - // validation - var args = AV.validateArgs(arguments, [{ - name: 'person', - type: AV.Types.PLATFORM_OBJECT, - values: Person, - optional: false, - nullable: false - }]); - var result = native_.callSync('ContactManager_update', { person: args.person }); - _checkError(result); - - result = native_.getResultObject(result); - for (var prop in result) { - if (args.person.hasOwnProperty(prop)) { - args.person[prop] = result[prop]; - } - } -}; - -// Updates several existing persons in the contact DB asynchronously. -ContactManager.prototype.updateBatch = function() { - var args = AV.validateArgs(arguments, [ - { - name: 'persons', - type: AV.Types.ARRAY, - values: Person, - optional: false, - nullable: false - }, - { - name: 'successCallback', - type: AV.Types.FUNCTION, - optional: true, - nullable: true - }, - { - name: 'errorCallback', - type: AV.Types.FUNCTION, - optional: true, - nullable: true - } - ]); - - var callback = function(result) { - if (native_.isFailure(result)) { - native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); - return; - } - - native_.callIfPossible(args.successCallback); - }; - - native_.call('ContactManager_updateBatch', { - addressBook: {}, - batchArgs: _toJsonObject(args.persons) - }, callback); -}; - -// Removes a person from the contact DB synchronously. -ContactManager.prototype.remove = function() { - // validation - var args = AV.validateArgs(arguments, [{ - name: 'personId', - type: AV.Types.STRING, - optional: false, - nullable: false - }]); - - if (String(Converter.toLong(args.personId)) !== args.personId) { - // TCT: ContactManager_remove_personId_invalid - throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR); - } - - var result = native_.callSync('ContactManager_remove', {personId: args.personId}); - _checkError(result); -}; - -// Removes persons from contact DB asynchronously. -ContactManager.prototype.removeBatch = function() { - var args = AV.validateArgs(arguments, [ - { - name: 'personIds', - type: AV.Types.ARRAY, - values: AV.Types.STRING, - optional: false, - nullable: false - }, - { - name: 'successCallback', - type: AV.Types.FUNCTION, - optional: true, - nullable: true - }, - { - name: 'errorCallback', - type: AV.Types.FUNCTION, - optional: true, - nullable: true - } - ]); - - var callback = function(result) { - if (native_.isFailure(result)) { - native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); - return; - } - - native_.callIfPossible(args.successCallback); - }; - - native_.call('ContactManager_removeBatch', { - addressBook: {}, - batchArgs: _toJsonObject(args.personIds) - }, callback); -}; - -// Gets an array of all Person objects from the contact DB or the ones that match the -// optionally supplied filter. -ContactManager.prototype.find = function() { - var args = AV.validateArgs(arguments, [ - { - name: 'successCallback', - type: AV.Types.FUNCTION, - optional: false, - nullable: false - }, - { - name: 'errorCallback', - type: AV.Types.FUNCTION, - optional: true, - nullable: true - }, - { - name: 'filter', - type: AV.Types.PLATFORM_OBJECT, - values: [tizen.AttributeFilter, - tizen.AttributeRangeFilter, - tizen.CompositeFilter], - optional: true, - nullable: true - }, - { - name: 'sortMode', - type: AV.Types.PLATFORM_OBJECT, - values: tizen.SortMode, - optional: true, - nullable: true - } - ]); - - // TODO implement contact filtering/sorting. - var data = { - filter: C.repackFilter(args.filter), - sortMode: args.sortMode - }; - - var self = this; - - var callback = function(result) { - if (native_.isSuccess(result)) { - var _result = native_.getResultObject(result); - var retval = []; - for (var i = 0; i < _result.length; ++i) { - retval.push(self.get(String(_result[i]))); - } - //TODO: Move sorting to native code - retval = C.sort(retval, args.sortMode); - args.successCallback(retval); - } else { - native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); - } - }; - - native_.call('ContactManager_find', data, callback); -}; - -// Subscribes to receive notifications about persons' changes. -ContactManager.prototype.addChangeListener = function() { - var args = AV.validateArgs(arguments, [ - { - name: 'successCallback', - type: AV.Types.LISTENER, - values: ['onpersonsadded', 'onpersonsupdated', 'onpersonsremoved'], - optional: false, - nullable: false - } - ]); - - if (Type.isEmptyObject(_personCallbackMap)) { - var result = native_.callSync('ContactManager_startListening', {}); - - if (native_.isFailure(result)) { - throw native_.getErrorObject(result); - } - } - - if (!_personListenerRegistered) { - native_.addListener('ContactPersonChangeListener', _personChangeListener); - _personListenerRegistered = true; - } - - var currentWatchId = _getNextWatchId(); - - _personCallbackMap[currentWatchId] = args.successCallback; - - return currentWatchId; -}; - -// Unsubscribes a persons' changes watch operation. -ContactManager.prototype.removeChangeListener = function() { - var args = AV.validateArgs(arguments, [ - { - name: 'watchId', - type: AV.Types.LONG, - optional: false, - nullable: false - } - ]); - - // This makes UTC_contact_removeChangeListenerPerson_N_001 pass. - // watch id's start at 1 - if (args.watchId === 0) { - throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR, - 'id is null or undefined'); - } - - if (args.watchId < 0) { - throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR, - 'Negative watch id'); - } - - if (!_personCallbackMap.hasOwnProperty(args.watchId)) { - throw new tizen.WebAPIException(tizen.WebAPIException.NOT_FOUND_ERR, - 'watch id not found'); - } - - delete _personCallbackMap[args.watchId]; - - if (Type.isEmptyObject(_personCallbackMap)) { - native_.removeListener('ContactPersonChangeListener', _personChangeListener); - _personListenerRegistered = false; - - var result = native_.callSync('ContactManager_stopListening', {}); - - if (native_.isFailure(result)) { - throw native_.getErrorObject(result); - } - } -}; - -// exports ///////////////////////////////////////////////////////////////// -exports = new ContactManager(); diff --git a/src/contact/js/tizen.contact.Person.js b/src/contact/js/tizen.contact.Person.js deleted file mode 100644 index d6c1ef5a..00000000 --- a/src/contact/js/tizen.contact.Person.js +++ /dev/null @@ -1,182 +0,0 @@ -// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - - -var Person = function(data) { - AV.isConstructorCall(this, Person); - - var _id = ''; - var _displayName = ''; - var _contactCount = 0; - var _hasPhoneNumber = false; - var _hasEmail = false; - var _isFavorite = false; - var _displayContactId = ''; - - if (data.hasOwnProperty('id') && Type.isString(data.id)) { - _id = data.id; - } - if (data.hasOwnProperty('displayName') && Type.isString(data.displayName)) { - _displayName = data.displayName; - } - if (data.hasOwnProperty('contactCount') && Type.isNumber(data.contactCount)) { - _contactCount = data.contactCount; - } - if (data.hasOwnProperty('hasPhoneNumber') && Type.isBoolean(data.hasPhoneNumber)) { - _hasPhoneNumber = data.hasPhoneNumber; - } - if (data.hasOwnProperty('hasEmail') && Type.isBoolean(data.hasEmail)) { - _hasEmail = data.hasEmail; - } - if (data.hasOwnProperty('displayContactId') && Type.isString(data.displayContactId)) { - _displayContactId = data.displayContactId; - } - if (data.hasOwnProperty('isFavorite') && Type.isBoolean(data.isFavorite)) { - _isFavorite = data.isFavorite; - } - - Object.defineProperties(this, { - id: { - get: function() { - return _id; - }, - set: function(v) { - if (_editGuard.isEditEnabled()) { - _id = Converter.toString(v, false); - } - }, - enumerable: true - }, - displayName: { - get: function() { - return _displayName; - }, - set: function(v) { - if (_editGuard.isEditEnabled()) { - _displayName = Converter.toString(v, false); - } - }, - enumerable: true - }, - contactCount: { - get: function() { - return _contactCount; - }, - set: function(v) { - if (_editGuard.isEditEnabled()) { - _contactCount = Converter.toLong(v, false); - } - }, - enumerable: true - }, - hasPhoneNumber: { - get: function() { - return _hasPhoneNumber; - }, - set: function(v) { - if (_editGuard.isEditEnabled()) { - _hasPhoneNumber = Converter.toBoolean(v, false); - } - }, - enumerable: true - }, - hasEmail: { - get: function() { - return _hasEmail; - }, - set: function(v) { - if (_editGuard.isEditEnabled()) { - _hasEmail = Converter.toBoolean(v, false); - } - }, - enumerable: true - }, - - isFavorite: { - get: function() { - return _isFavorite; - }, - set: function(v) { - _isFavorite = Converter.toBoolean(v, false); - }, - enumerable: true - }, - photoURI: { - value: data.hasOwnProperty('photoURI') ? data.photoURI : null, - writable: true, - enumerable: true - }, - ringtoneURI: { - value: data.hasOwnProperty('ringtoneURI') ? data.ringtoneURI : null, - writable: true, - enumerable: true - }, - displayContactId: { - get: function() { - return _displayContactId; - }, - set: function(v) { - _displayContactId = Converter.toString(v, false); - }, - enumerable: true - } - }); -}; - -// Aggregates another person to this person. -Person.prototype.link = function() { - var args = AV.validateArgs(arguments, [{ - name: 'personId', - type: AV.Types.STRING, - optional: false, - nullable: false - }]); - - if (String(Converter.toLong(args.personId)) !== args.personId) { - // TCT: Person_link_personId_invalid - throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR); - } - - var result = native_.callSync('Person_link', { - // TODO move to only sending the person id (in all functions) - person: this, - id: args.personId - }); - if (native_.isFailure(result)) { - throw native_.getErrorObject(result); - } - var _this = this; - _editGuard.run(function() { - _this.contactCount = _this.contactCount + 1; - }); -}; - -// Separates a contact from this person. -Person.prototype.unlink = function(contactId) { - var args = AV.validateArgs(arguments, [{ - name: 'contactId', - type: AV.Types.STRING, - optional: false, - nullable: false - }]); - - if (String(Converter.toLong(args.contactId)) !== args.contactId) { - // TCT: Person_unlink_contactId_invalid - throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR); - } - - var result = native_.callSync('Person_unlink', { - // TODO move to only sending the person id (in all functions) - person: this, - id: args.contactId - }); - if (native_.isFailure(result)) { - throw native_.getErrorObject(result); - } - var _this = this; - return _editGuard.run(function() { - _this.contactCount = _this.contactCount - 1; - return new Person(native_.getResultObject(result)); - }); -};