sogo/UI/WebServerResources/js/Contacts.services.js.map
2016-02-11 02:25:48 -05:00

1 line
51 KiB
Plaintext

{"version":3,"sources":["Contacts/AddressBook.service.js","Contacts/Card.service.js"],"names":["AddressBook","futureAddressBookData","then","this","init","name","id","newAddressBookData","$$resource","create","$unwrap","acls","objectEditor","objectCreator","objectEraser","$acl","$$Acl","$factory","$q","$timeout","$log","Settings","Resource","Card","Acl","Preferences","angular","extend","activeUser","$Card","$Preferences","$query","search","value","sort","asc","selectedFolder","$refreshTimeout","ready","settings","Contact","SortingState","parseInt","module","e","factory","$filterAll","options","excludedCards","params","isUndefined","$cards","fetch","response","results","card","index","compareIds","data","_","filter","contacts","find","length","splice","each","debug","when","$add","addressbook","list","sibling","i","isSubscription","$subscriptions","$addressbooks","o","localeCompare","indexOf","pluck","$findAll","_this","$remotes","forEach","isRemote","push","union","$find","addressbookId","$subscribe","uid","path","userResource","addressbookData","prototype","$isLoading","cards","isOwned","isSuperUser","owner","login","$id","$futureAddressBookData","isSelectedCard","cardId","selectedCard","$selectedCount","count","selected","$startRefreshTimeout","cancel","refreshViewCheck","defaults","SOGoRefreshViewCheck","f","bind","$reload","timeInterval","$filter","query","dry","copy","isDefined","oldIndex","removedCards","findIndex","$rename","$save","$delete","promise","d","defer","remove","resolve","reject","$deleteCards","uids","map","post","difference","$copyCards","folder","save","$omit","$getCard","fullCard","cachedCard","$futureCardData","isError","isObject","key","futureCardData","partial","pid","newCardData","newguid","isNew","$TEL_TYPES","$EMAIL_TYPES","$URL_TYPES","$ADDRESS_TYPES","Gravatar","$gravatar","SOGoContactsCategories","$categories","SOGoAlternateAvatar","$alternateAvatar","join","$unwrapCollection","filterCategories","re","RegExp","category","collection","refs","categories","$$fullname","$fullname","$$email","$preferredEmail","$$image","image","no_404","empty","action","c_component","birthday","$birthday","$mdDateLocaleProvider","formatDate","$shadowData","attribute","names","fn","c_cn","c_givenname","nickname","c_sn","c_org","emails","$description","description","title","role","orgUnits","unit","email","test","type","$shortFormat","fullname","$isCard","$isList","$addOrgUnit","orgUnit","$addEmail","$addScreenName","screenName","c_screenname","$addPhone","phones","$addUrl","url","urls","$addAddress","postoffice","street","street2","locality","region","country","postalcode","addresses","$addMember","$reset","reference","Date","deep","getTime","toString","desc"],"mappings":"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","file":"Contacts.services.js","sourcesContent":["/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /**\n * @name AddressBook\n * @constructor\n * @param {object} futureAddressBookData - either an object literal or a promise\n */\n function AddressBook(futureAddressBookData) {\n // Data is immediately available\n if (typeof futureAddressBookData.then !== 'function') {\n this.init(futureAddressBookData);\n if (this.name && !this.id) {\n // Create a new addressbook on the server\n var newAddressBookData = AddressBook.$$resource.create('createFolder', this.name);\n this.$unwrap(newAddressBookData);\n this.acls = {'objectEditor': 1, 'objectCreator': 1, 'objectEraser': 1};\n }\n else if (this.id) {\n this.$acl = new AddressBook.$$Acl('Contacts/' + this.id);\n }\n }\n else {\n // The promise will be unwrapped first\n this.$unwrap(futureAddressBookData);\n }\n }\n\n /**\n * @memberof AddressBook\n * @desc The factory we'll use to register with Angular\n * @returns the AddressBook constructor\n */\n AddressBook.$factory = ['$q', '$timeout', '$log', 'sgSettings', 'Resource', 'Card', 'Acl', 'Preferences', function($q, $timeout, $log, Settings, Resource, Card, Acl, Preferences) {\n angular.extend(AddressBook, {\n $q: $q,\n $timeout: $timeout,\n $log: $log,\n $$resource: new Resource(Settings.activeUser('folderURL') + 'Contacts', Settings.activeUser()),\n $Card: Card,\n $$Acl: Acl,\n $Preferences: Preferences,\n $query: {search: 'name_or_address', value: '', sort: 'c_cn', asc: 1},\n activeUser: Settings.activeUser(),\n selectedFolder: null,\n $refreshTimeout: null\n });\n // Initialize sort parameters from user's settings\n Preferences.ready().then(function() {\n if (Preferences.settings.Contact.SortingState) {\n AddressBook.$query.sort = Preferences.settings.Contact.SortingState[0];\n AddressBook.$query.asc = parseInt(Preferences.settings.Contact.SortingState[1]);\n }\n });\n return AddressBook; // return constructor\n }];\n\n /**\n * @module SOGo.ContactsUI\n * @desc Factory registration of AddressBook in Angular module.\n */\n try {\n angular.module('SOGo.ContactsUI');\n }\n catch(e) {\n angular.module('SOGo.ContactsUI', ['SOGo.Common', 'SOGo.PreferencesUI']);\n }\n angular.module('SOGo.ContactsUI')\n .factory('AddressBook', AddressBook.$factory);\n\n /**\n * @memberof AddressBook\n * @desc Search for cards among all addressbooks matching some criterias.\n * @param {string} search - the search string to match\n * @param {object} [options] - additional options to the query (excludeGroups and excludeLists)\n * @param {object[]} excludedCards - a list of Card objects that must be excluded from the results\n * @returns a collection of Cards instances\n */\n AddressBook.$filterAll = function(search, options, excludedCards) {\n var params = { search: search };\n\n if (!search) {\n // No query specified\n AddressBook.$cards = [];\n return AddressBook.$q.when(AddressBook.$cards);\n }\n if (angular.isUndefined(AddressBook.$cards)) {\n // First session query\n AddressBook.$cards = [];\n }\n\n angular.extend(params, options);\n\n return AddressBook.$$resource.fetch(null, 'allContactSearch', params).then(function(response) {\n var results, card, index,\n compareIds = function(data) {\n return this.id == data.id;\n };\n if (excludedCards) {\n // Remove excluded cards from results\n results = _.filter(response.contacts, function(data) {\n return _.isUndefined(_.find(excludedCards, compareIds, data));\n });\n }\n else {\n results = response.contacts;\n }\n // Remove cards that no longer match the search query\n for (index = AddressBook.$cards.length - 1; index >= 0; index--) {\n card = AddressBook.$cards[index];\n if (_.isUndefined(_.find(results, compareIds, card))) {\n AddressBook.$cards.splice(index, 1);\n }\n }\n // Add new cards matching the search query\n _.each(results, function(data, index) {\n if (_.isUndefined(_.find(AddressBook.$cards, compareIds, data))) {\n var card = new AddressBook.$Card(data, search);\n AddressBook.$cards.splice(index, 0, card);\n }\n });\n AddressBook.$log.debug(AddressBook.$cards);\n return AddressBook.$cards;\n });\n };\n\n /**\n * @memberof AddressBook\n * @desc Add a new addressbook to the static list of addressbooks\n * @param {AddressBook} addressbook - an Addressbook object instance\n */\n AddressBook.$add = function(addressbook) {\n // Insert new addressbook at proper index\n var list, sibling, i;\n\n list = addressbook.isSubscription? this.$subscriptions : this.$addressbooks;\n sibling = _.find(list, function(o) {\n return (addressbook.id == 'personal' ||\n (o.id != 'personal' &&\n o.name.localeCompare(addressbook.name) === 1));\n });\n i = sibling ? _.indexOf(_.pluck(list, 'id'), sibling.id) : 1;\n list.splice(i, 0, addressbook);\n };\n\n /**\n * @memberof AddressBook\n * @desc Set or get the list of addressbooks. Will instantiate a new AddressBook object for each item.\n * @param {array} [data] - the metadata of the addressbooks\n * @returns the list of addressbooks\n */\n AddressBook.$findAll = function(data) {\n var _this = this;\n if (data) {\n this.$addressbooks = [];\n this.$subscriptions = [];\n this.$remotes = [];\n // Instanciate AddressBook objects\n angular.forEach(data, function(o, i) {\n var addressbook = new AddressBook(o);\n if (addressbook.isRemote)\n _this.$remotes.push(addressbook);\n else if (addressbook.isSubscription)\n _this.$subscriptions.push(addressbook);\n else\n _this.$addressbooks.push(addressbook);\n });\n }\n return _.union(this.$addressbooks, this.$subscriptions, this.$remotes);\n };\n\n /**\n * @memberOf AddressBook\n * @desc Fetch list of cards and return an AddressBook instance.\n * @param {string} addressbookId - the addressbook identifier\n * @returns an AddressBook object instance\n */\n AddressBook.$find = function(addressbookId) {\n var futureAddressBookData = AddressBook.$Preferences.ready().then(function() {\n return AddressBook.$$resource.fetch(addressbookId, 'view', AddressBook.$query);\n });\n return new AddressBook(futureAddressBookData);\n };\n\n /**\n * @memberOf AddressBook\n * @desc Subscribe to another user's addressbook and add it to the list of addressbooks.\n * @param {string} uid - user id\n * @param {string} path - path of folder for specified user\n * @returns a promise of the HTTP query result\n */\n AddressBook.$subscribe = function(uid, path) {\n var _this = this;\n return AddressBook.$$resource.userResource(uid).fetch(path, 'subscribe').then(function(addressbookData) {\n var addressbook = new AddressBook(addressbookData);\n if (_.isUndefined(_.find(_this.$subscriptions, function(o) {\n return o.id == addressbookData.id;\n }))) {\n // Not already subscribed\n AddressBook.$add(addressbook);\n }\n return addressbook;\n });\n };\n\n /**\n * @function init\n * @memberof AddressBook.prototype\n * @desc Extend instance with new data and compute additional attributes.\n * @param {object} data - attributes of addressbook\n */\n AddressBook.prototype.init = function(data, options) {\n if (!this.$cards) {\n this.$isLoading = true;\n this.$cards = [];\n this.cards = [];\n }\n angular.extend(this, data);\n // Add 'isOwned' and 'isSubscription' attributes based on active user (TODO: add it server-side?)\n this.isOwned = AddressBook.activeUser.isSuperUser || this.owner == AddressBook.activeUser.login;\n this.isSubscription = !this.isRemote && this.owner != AddressBook.activeUser.login;\n };\n\n /**\n * @function $id\n * @memberof AddressBook.prototype\n * @desc Resolve the addressbook id.\n * @returns a promise of the addressbook id\n */\n AddressBook.prototype.$id = function() {\n if (this.id) {\n // Object already unwrapped\n return AddressBook.$q.when(this.id);\n }\n else {\n // Wait until object is unwrapped\n return this.$futureAddressBookData.then(function(addressbook) {\n return addressbook.id;\n });\n }\n };\n\n /**\n * @function isSelectedCard\n * @memberof AddressBook.prototype\n * @desc Check if the specified card is selected.\n * @param {string} CardId\n * @returns true if the specified card is selected\n */\n AddressBook.prototype.isSelectedCard = function(cardId) {\n return this.selectedCard == cardId;\n };\n\n /**\n * @function $selectedCount\n * @memberof AddressBook.prototype\n * @desc Return the number of cards selected by the user.\n * @returns the number of selected cards\n */\n AddressBook.prototype.$selectedCount = function() {\n var count;\n\n count = 0;\n if (this.cards) {\n count = (_.filter(this.cards, function(card) { return card.selected; })).length;\n }\n return count;\n };\n\n /**\n * @function $startRefreshTimeout\n * @memberof AddressBook.prototype\n * @desc Starts the refresh timeout for the current selected address book\n */\n AddressBook.prototype.$startRefreshTimeout = function() {\n var _this = this;\n\n if (AddressBook.$refreshTimeout)\n AddressBook.$timeout.cancel(AddressBook.$refreshTimeout);\n\n AddressBook.$Preferences.ready().then(function() {\n // Restart the refresh timer, if needed\n var refreshViewCheck = AddressBook.$Preferences.defaults.SOGoRefreshViewCheck;\n if (refreshViewCheck && refreshViewCheck != 'manually') {\n var f = angular.bind(_this, AddressBook.prototype.$reload);\n AddressBook.$refreshTimeout = AddressBook.$timeout(f, refreshViewCheck.timeInterval()*1000);\n }\n });\n };\n\n /**\n * @function $reload\n * @memberof AddressBook.prototype\n * @desc Reload list of cards\n * @returns a promise of the Cards instances\n */\n AddressBook.prototype.$reload = function() {\n var _this = this;\n\n this.$startRefreshTimeout();\n return this.$filter();\n };\n\n /**\n * @function $filter\n * @memberof AddressBook.prototype\n * @desc Search for cards matching some criterias\n * @param {string} search - the search string to match\n * @param {object} [options] - additional options to the query (dry, excludeList)\n * @returns a collection of Cards instances\n */\n AddressBook.prototype.$filter = function(search, options, excludedCards) {\n var _this = this, query;\n\n if (!options || !options.dry) {\n this.$isLoading = true;\n query = AddressBook.$query;\n }\n else if (options.dry) {\n // Don't keep a copy of the query in dry mode\n query = angular.copy(AddressBook.$query);\n }\n\n return AddressBook.$Preferences.ready().then(function() {\n if (options) {\n angular.extend(query, options);\n if (options.dry) {\n if (!search) {\n // No query specified\n _this.$cards = [];\n return AddressBook.$q.when(_this.$cards);\n }\n }\n }\n\n if (angular.isDefined(search))\n query.value = search;\n\n return _this.$id().then(function(addressbookId) {\n return AddressBook.$$resource.fetch(addressbookId, 'view', query);\n }).then(function(response) {\n var results, cards, card, index,\n compareIds = function(data) {\n return _this.id == data.id;\n };\n if (options && options.dry) {\n // Don't keep a copy of the resulting cards.\n // This is usefull when doing autocompletion.\n cards = _this.$cards;\n }\n else {\n cards = _this.cards;\n }\n if (excludedCards) {\n // Remove excluded cards from results\n results = _.filter(response.cards, function(card) {\n return _.isUndefined(_.find(excludedCards, compareIds, card));\n });\n }\n else {\n results = response.cards;\n }\n // Remove cards that no longer match the search query\n for (index = cards.length - 1; index >= 0; index--) {\n card = cards[index];\n if (_.isUndefined(_.find(results, compareIds, card))) {\n cards.splice(index, 1);\n }\n }\n // Add new cards matching the search query\n _.each(results, function(data, index) {\n if (_.isUndefined(_.find(cards, compareIds, data))) {\n var card = new AddressBook.$Card(data, search);\n cards.splice(index, 0, card);\n }\n });\n // Respect the order of the results\n _.each(results, function(data, index) {\n var oldIndex, removedCards;\n if (cards[index].id != data.id) {\n oldIndex = _.findIndex(cards, compareIds, data);\n removedCards = cards.splice(oldIndex, 1);\n cards.splice(index, 0, removedCards[0]);\n }\n });\n _this.$isLoading = false;\n return cards;\n });\n });\n };\n\n /**\n * @function $rename\n * @memberof AddressBook.prototype\n * @desc Rename the addressbook and keep the list sorted\n * @param {string} name - the new name\n * @returns a promise of the HTTP operation\n */\n AddressBook.prototype.$rename = function(name) {\n var i = _.indexOf(_.pluck(AddressBook.$addressbooks, 'id'), this.id);\n this.name = name;\n AddressBook.$addressbooks.splice(i, 1);\n AddressBook.$add(this);\n return this.$save();\n };\n\n /**\n * @function $delete\n * @memberof AddressBook.prototype\n * @desc Delete the addressbook from the server and the static list of addressbooks.\n * @returns a promise of the HTTP operation\n */\n AddressBook.prototype.$delete = function() {\n var _this = this,\n d = AddressBook.$q.defer(),\n list,\n promise;\n\n if (this.isSubscription) {\n promise = AddressBook.$$resource.fetch(this.id, 'unsubscribe');\n list = AddressBook.$subscriptions;\n }\n else {\n promise = AddressBook.$$resource.remove(this.id);\n list = AddressBook.$addressbooks;\n }\n\n promise.then(function() {\n var i = _.indexOf(_.pluck(list, 'id'), _this.id);\n list.splice(i, 1);\n d.resolve();\n }, d.reject);\n return d.promise;\n };\n\n /**\n * @function $deleteCards\n * @memberof AddressBook.prototype\n * @desc Delete multiple cards from addressbook.\n * @return a promise of the HTTP operation\n */\n AddressBook.prototype.$deleteCards = function(cards) {\n\n var uids = _.map(cards, function(card) { return card.id; });\n var _this = this;\n \n return AddressBook.$$resource.post(this.id, 'batchDelete', {uids: uids}).then(function() {\n _this.cards = _.difference(_this.cards, cards);\n });\n };\n\n /**\n * @function $copyCards\n * @memberof AddressBook.prototype\n * @desc Copy multiple cards from addressbook to an other one.\n * @return a promise of the HTTP operation\n */\n AddressBook.prototype.$copyCards = function(cards, folder) {\n var uids = _.map(cards, function(card) { return card.id; });\n return AddressBook.$$resource.post(this.id, 'copy', {uids: uids, folder: folder});\n };\n\n /**\n * @function $save\n * @memberof AddressBook.prototype\n * @desc Save the addressbook to the server. This currently can only affect the name of the addressbook.\n * @returns a promise of the HTTP operation\n */\n AddressBook.prototype.$save = function() {\n return AddressBook.$$resource.save(this.id, this.$omit()).then(function(data) {\n return data;\n });\n };\n\n /**\n * @function $getCard\n * @memberof AddressBook.prototype\n * @desc Fetch the card attributes from the server.\n * @returns a promise of the HTTP operation\n */\n AddressBook.prototype.$getCard = function(cardId) {\n var _this = this;\n\n return this.$id().then(function(addressbookId) {\n var fullCard,\n cachedCard = _.find(_this.cards, function(data) {\n return cardId == data.id;\n });\n\n if (cachedCard && cachedCard.$futureCardData)\n // Full card is available\n return cachedCard;\n\n fullCard = AddressBook.$Card.$find(addressbookId, cardId);\n fullCard.$id().then(function(cardId) {\n // Extend the Card object of the addressbook list with the full card description\n if (cachedCard)\n angular.extend(cachedCard, fullCard);\n });\n return fullCard;\n });\n };\n\n /**\n * @function $unwrap\n * @memberof AddressBook.prototype\n * @desc Unwrap a promise and instanciate new Card objects using received data.\n * @param {promise} futureAddressBookData - a promise of the AddressBook's data\n */\n AddressBook.prototype.$unwrap = function(futureAddressBookData) {\n var _this = this;\n\n // Expose and resolve the promise\n this.$futureAddressBookData = futureAddressBookData.then(function(data) {\n return AddressBook.$timeout(function() {\n // Extend AddressBook instance from data of addressbooks list.\n // Will inherit attributes such as isEditable and isRemote.\n angular.forEach(AddressBook.$findAll(), function(o, i) {\n if (o.id == data.id) {\n angular.extend(_this, o);\n }\n });\n // Extend AddressBook instance with received data\n _this.init(data);\n // Instanciate Card objects\n angular.forEach(_this.cards, function(o, i) {\n _this.cards[i] = new AddressBook.$Card(o);\n });\n // Instanciate Acl object\n _this.$acl = new AddressBook.$$Acl('Contacts/' + _this.id);\n\n _this.$startRefreshTimeout();\n\n _this.$isLoading = false;\n\n return _this;\n });\n }, function(data) {\n _this.isError = true;\n if (angular.isObject(data)) {\n AddressBook.$timeout(function() {\n angular.extend(_this, data);\n });\n }\n });\n };\n\n /**\n * @function $omit\n * @memberof AddressBook.prototype\n * @desc Return a sanitized object used to send to the server.\n * @return an object literal copy of the Addressbook instance\n */\n AddressBook.prototype.$omit = function() {\n var addressbook = {};\n angular.forEach(this, function(value, key) {\n if (key != 'constructor' &&\n key != 'cards' &&\n key[0] != '$') {\n addressbook[key] = value;\n }\n });\n return addressbook;\n };\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /**\n * @name Card\n * @constructor\n * @param {object} futureCardData\n * @param {string} [partial]\n */\n function Card(futureCardData, partial) {\n\n // Data is immediately available\n if (typeof futureCardData.then !== 'function') {\n this.init(futureCardData, partial);\n if (this.pid && !this.id) {\n // Prepare for the creation of a new card;\n // Get UID from the server.\n var newCardData = Card.$$resource.newguid(this.pid);\n this.$unwrap(newCardData);\n this.isNew = true;\n }\n }\n else {\n // The promise will be unwrapped first\n this.$unwrap(futureCardData);\n }\n }\n\n Card.$TEL_TYPES = ['work', 'home', 'cell', 'fax', 'pager'];\n Card.$EMAIL_TYPES = ['work', 'home', 'pref'];\n Card.$URL_TYPES = ['work', 'home', 'pref'];\n Card.$ADDRESS_TYPES = ['work', 'home'];\n\n /**\n * @memberof Card\n * @desc The factory we'll use to register with Angular.\n * @returns the Card constructor\n */\n Card.$factory = ['$timeout', 'sgSettings', 'Resource', 'Preferences', 'Gravatar', function($timeout, Settings, Resource, Preferences, Gravatar) {\n angular.extend(Card, {\n $$resource: new Resource(Settings.activeUser('folderURL') + 'Contacts', Settings.activeUser()),\n $timeout: $timeout,\n $gravatar: Gravatar,\n $Preferences: Preferences\n });\n // Initialize categories from user's defaults\n Preferences.ready().then(function() {\n if (Preferences.defaults.SOGoContactsCategories) {\n Card.$categories = Preferences.defaults.SOGoContactsCategories;\n }\n if (Preferences.defaults.SOGoAlternateAvatar)\n Card.$alternateAvatar = Preferences.defaults.SOGoAlternateAvatar;\n });\n\n return Card; // return constructor\n }];\n\n /**\n * @module SOGo.ContactsUI\n * @desc Factory registration of Card in Angular module.\n */\n try {\n angular.module('SOGo.ContactsUI');\n }\n catch(e) {\n angular.module('SOGo.ContactsUI', ['SOGo.Common', 'SOGo.PreferencesUI']);\n }\n angular.module('SOGo.ContactsUI')\n .factory('Card', Card.$factory);\n\n /**\n * @memberof Card\n * @desc Fetch a card from a specific addressbook.\n * @param {string} addressbookId - the addressbook ID\n * @param {string} cardId - the card ID\n * @see {@link AddressBook.$getCard}\n */\n Card.$find = function(addressbookId, cardId) {\n var futureCardData = this.$$resource.fetch([addressbookId, cardId].join('/'), 'view');\n\n if (cardId) return new Card(futureCardData); // a single card\n\n return Card.$unwrapCollection(futureCardData); // a collection of cards\n };\n\n /**\n * @function filterCategories\n * @memberof Card.prototype\n * @desc Search for categories matching some criterias\n * @param {string} search - the search string to match\n * @returns a collection of strings\n */\n Card.filterCategories = function(query) {\n var re = new RegExp(query, 'i');\n return _.map(_.filter(Card.$categories, function(category) {\n return category.search(re) != -1;\n }), function(category) {\n return { value: category };\n });\n };\n\n /**\n * @memberof Card\n * @desc Unwrap to a collection of Card instances.\n * @param {object} futureCardData\n */\n Card.$unwrapCollection = function(futureCardData) {\n var collection = {};\n\n collection.$futureCardData = futureCardData;\n\n futureCardData.then(function(cards) {\n Card.$timeout(function() {\n angular.forEach(cards, function(data, index) {\n collection[data.id] = new Card(data);\n });\n });\n });\n\n return collection;\n };\n\n /**\n * @function init\n * @memberof Card.prototype\n * @desc Extend instance with required attributes and new data.\n * @param {object} data - attributes of card\n */\n Card.prototype.init = function(data, partial) {\n this.refs = [];\n this.categories = [];\n angular.extend(this, data);\n if (!this.$$fullname)\n this.$$fullname = this.$fullname();\n if (!this.$$email)\n this.$$email = this.$preferredEmail(partial);\n if (!this.$$image)\n this.$$image = this.image || Card.$gravatar(this.$preferredEmail(partial), 32, Card.$alternateAvatar, {no_404: true});\n this.selected = false;\n\n // An empty attribute to trick md-autocomplete when adding attendees from the appointment editor\n this.empty = ' ';\n };\n\n /**\n * @function $id\n * @memberof Card.prototype\n * @desc Return the card ID.\n * @returns the card ID\n */\n Card.prototype.$id = function() {\n return this.$futureCardData.then(function(data) {\n return data.id;\n });\n };\n\n /**\n * @function $save\n * @memberof Card.prototype\n * @desc Save the card to the server.\n */\n Card.prototype.$save = function() {\n var _this = this,\n action = 'saveAsContact';\n\n if (this.c_component == 'vlist') action = 'saveAsList';\n\n return Card.$$resource.save([this.pid, this.id || '_new_'].join('/'),\n this.$omit(),\n { action: action })\n .then(function(data) {\n // Format birthdate\n if (_this.birthday)\n _this.$birthday = Card.$Preferences.$mdDateLocaleProvider.formatDate(_this.birthday);\n // Make a copy of the data for an eventual reset\n _this.$shadowData = _this.$omit(true);\n return data;\n });\n };\n\n Card.prototype.$delete = function(attribute, index) {\n if (attribute) {\n if (index > -1 && this[attribute].length > index) {\n this[attribute].splice(index, 1);\n }\n else\n delete this[attribute];\n }\n else {\n // No arguments -- delete card\n return Card.$$resource.remove([this.pid, this.id].join('/'));\n }\n };\n\n Card.prototype.$fullname = function() {\n var fn = this.c_cn || '', names;\n if (fn.length === 0) {\n names = [];\n if (this.c_givenname && this.c_givenname.length > 0)\n names.push(this.c_givenname);\n if (this.nickname && this.nickname.length > 0)\n names.push('<em>' + this.nickname + '</em>');\n if (this.c_sn && this.c_sn.length > 0)\n names.push(this.c_sn);\n if (names.length > 0)\n fn = names.join(' ');\n else if (this.c_org && this.c_org.length > 0) {\n fn = this.c_org;\n }\n else if (this.emails && this.emails.length > 0) {\n fn = _.find(this.emails, function(i) { return i.value !== ''; }).value;\n }\n else if (this.c_cn && this.c_cn.length > 0) {\n fn = this.c_cn;\n }\n }\n\n return fn;\n };\n\n Card.prototype.$description = function() {\n var description = [];\n if (this.title) description.push(this.title);\n if (this.role) description.push(this.role);\n if (this.orgUnits && this.orgUnits.length > 0)\n _.forEach(this.orgUnits, function(unit) {\n if (unit.value !== '')\n description.push(unit.value);\n });\n if (this.c_org) description.push(this.c_org);\n if (this.description) description.push(this.description);\n\n return description.join(', ');\n };\n\n /**\n * @function $preferredEmail\n * @memberof Card.prototype\n * @desc Get the preferred email address.\n * @param {string} [partial] - a partial string that the email must match\n * @returns the first email address of type \"pref\" or the first address if none found\n */\n Card.prototype.$preferredEmail = function(partial) {\n var email, re;\n if (partial) {\n re = new RegExp(partial, 'i');\n email = _.find(this.emails, function(o) {\n return re.test(o.value);\n });\n }\n if (email) {\n email = email.value;\n }\n else {\n email = _.find(this.emails, function(o) {\n return o.type == 'pref';\n });\n if (email) {\n email = email.value;\n }\n else if (this.emails && this.emails.length) {\n email = this.emails[0].value;\n }\n else {\n email = '';\n }\n }\n\n return email;\n };\n\n /**\n * @function $shortFormat\n * @memberof Card.prototype\n * @param {string} [partial] - a partial string that the email must match\n * @returns the fullname along with a matching email address in parentheses\n */\n Card.prototype.$shortFormat = function(partial) {\n var fullname = [this.$$fullname],\n email = this.$preferredEmail(partial);\n if (email && email != this.$$fullname)\n fullname.push(' <' + email + '>');\n return fullname.join(' ');\n };\n\n Card.prototype.$isCard = function() {\n return this.c_component == 'vcard';\n };\n\n Card.prototype.$isList = function() {\n return this.c_component == 'vlist';\n };\n\n Card.prototype.$addOrgUnit = function(orgUnit) {\n if (angular.isUndefined(this.orgUnits)) {\n this.orgUnits = [{value: orgUnit}];\n }\n else {\n for (var i = 0; i < this.orgUnits.length; i++) {\n if (this.orgUnits[i].value == orgUnit) {\n break;\n }\n }\n if (i == this.orgUnits.length)\n this.orgUnits.push({value: orgUnit});\n }\n return this.orgUnits.length - 1;\n };\n\n // Card.prototype.$addCategory = function(category) {\n // if (category) {\n // if (angular.isUndefined(this.categories)) {\n // this.categories = [{value: category}];\n // }\n // else {\n // for (var i = 0; i < this.categories.length; i++) {\n // if (this.categories[i].value == category) {\n // break;\n // }\n // }\n // if (i == this.categories.length)\n // this.categories.push({value: category});\n // }\n // }\n // };\n\n Card.prototype.$addEmail = function(type) {\n if (angular.isUndefined(this.emails)) {\n this.emails = [{type: type, value: ''}];\n }\n else if (_.isUndefined(_.find(this.emails, function(i) { return i.value === ''; }))) {\n this.emails.push({type: type, value: ''});\n }\n return this.emails.length - 1;\n };\n\n Card.prototype.$addScreenName = function(screenName) {\n this.c_screenname = screenName;\n };\n\n Card.prototype.$addPhone = function(type) {\n if (angular.isUndefined(this.phones)) {\n this.phones = [{type: type, value: ''}];\n }\n else if (_.isUndefined(_.find(this.phones, function(i) { return i.value === ''; }))) {\n this.phones.push({type: type, value: ''});\n }\n return this.phones.length - 1;\n };\n\n Card.prototype.$addUrl = function(type, url) {\n if (angular.isUndefined(this.urls)) {\n this.urls = [{type: type, value: url}];\n }\n else if (_.isUndefined(_.find(this.urls, function(i) { return i.value == url; }))) {\n this.urls.push({type: type, value: url});\n }\n return this.urls.length - 1;\n };\n\n Card.prototype.$addAddress = function(type, postoffice, street, street2, locality, region, country, postalcode) {\n if (angular.isUndefined(this.addresses)) {\n this.addresses = [{type: type, postoffice: postoffice, street: street, street2: street2, locality: locality, region: region, country: country, postalcode: postalcode}];\n }\n else if (!_.find(this.addresses, function(i) {\n return i.street == street &&\n i.street2 == street2 &&\n i.locality == locality &&\n i.country == country &&\n i.postalcode == postalcode;\n })) {\n this.addresses.push({type: type, postoffice: postoffice, street: street, street2: street2, locality: locality, region: region, country: country, postalcode: postalcode});\n }\n return this.addresses.length - 1;\n };\n\n Card.prototype.$addMember = function(email) {\n var card = new Card({email: email, emails: [{value: email}]}),\n i;\n if (angular.isUndefined(this.refs)) {\n this.refs = [card];\n }\n else if (email.length === 0) {\n this.refs.push(card);\n }\n else {\n for (i = 0; i < this.refs.length; i++) {\n if (this.refs[i].email == email) {\n break;\n }\n }\n if (i == this.refs.length)\n this.refs.push(card);\n }\n return this.refs.length - 1;\n };\n\n /**\n * @function $reset\n * @memberof Card.prototype\n * @desc Reset the original state the card's data.\n */\n Card.prototype.$reset = function() {\n var _this = this;\n angular.forEach(this, function(value, key) {\n if (key != 'constructor' && key[0] != '$') {\n delete _this[key];\n }\n });\n angular.extend(this, this.$shadowData);\n // Reinstanciate Card objects for list members\n angular.forEach(this.refs, function(o, i) {\n if (o.email) o.emails = [{value: o.email}];\n _this.refs[i] = new Card(o);\n });\n this.$shadowData = this.$omit(true);\n };\n\n /**\n * @function $updateMember\n * @memberof Card.prototype\n * @desc Update an existing list member from a Card instance.\n * A list member has the following attribtues:\n * - email\n * - reference\n * - fn\n * @param {number} index\n * @param {string} email\n * @param {Card} card\n */\n // Card.prototype.$updateMember = function(index, email, card) {\n // var ref = {\n // email: email,\n // emails: [{value: email}],\n // reference: card.c_name,\n // c_cn: card.$fullname()\n // };\n // this.refs[index] = new Card(ref);\n // };\n\n /**\n * @function $unwrap\n * @memberof Card.prototype\n * @desc Unwrap a promise and make a copy of the resolved data.\n * @param {object} futureCardData - a promise of the Card's data\n */\n Card.prototype.$unwrap = function(futureCardData) {\n var _this = this;\n\n // Expose the promise\n this.$futureCardData = futureCardData.then(function(data) {\n _this.init(data);\n // Instanciate Card objects for list members\n angular.forEach(_this.refs, function(o, i) {\n if (o.email) o.emails = [{value: o.email}];\n o.id = o.reference;\n _this.refs[i] = new Card(o);\n });\n if (_this.birthday) {\n _this.birthday = new Date(_this.birthday * 1000);\n _this.$birthday = Card.$Preferences.$mdDateLocaleProvider.formatDate(_this.birthday);\n }\n // Make a copy of the data for an eventual reset\n _this.$shadowData = _this.$omit(true);\n return _this;\n });\n };\n\n /**\n * @function $omit\n * @memberof Card.prototype\n * @desc Return a sanitized object used to send to the server.\n * @param {boolean} [deep] - make a deep copy if true\n * @return an object literal copy of the Card instance\n */\n Card.prototype.$omit = function(deep) {\n var card = {};\n angular.forEach(this, function(value, key) {\n if (key == 'refs') {\n card.refs = _.map(value, function(o) {\n return o.$omit(deep);\n });\n }\n else if (key != 'constructor' && key[0] != '$') {\n if (deep)\n card[key] = angular.copy(value);\n else\n card[key] = value;\n }\n });\n\n // We convert back our birthday object\n if (!deep) {\n if (card.birthday)\n card.birthday = card.birthday.getTime()/1000;\n else\n card.birthday = 0;\n }\n\n return card;\n };\n\n Card.prototype.toString = function() {\n var desc = this.id + ' ' + this.$$fullname;\n\n if (this.$$email)\n desc += ' <' + this.$$email + '>';\n\n return '[' + desc + ']';\n };\n})();\n"]}