diff options
author | Unrud <unrud@openaliasbox.org> | 2017-06-04 17:16:11 +0200 |
---|---|---|
committer | Unrud <unrud@openaliasbox.org> | 2017-06-04 17:16:36 +0200 |
commit | 10eef51a0f086ad148928ba965c330599b4765cb (patch) | |
tree | d0283e55f1b4e66c49bf17461b5fee211b78768a /radicale_web/web/infcloud/addressbook.js | |
parent | Update license (diff) | |
download | radicaleinfcloud-10eef51a0f086ad148928ba965c330599b4765cb.tar.gz radicaleinfcloud-10eef51a0f086ad148928ba965c330599b4765cb.tar.bz2 radicaleinfcloud-10eef51a0f086ad148928ba965c330599b4765cb.zip |
Update package for new web plugin interface
Diffstat (limited to 'radicale_web/web/infcloud/addressbook.js')
-rw-r--r-- | radicale_web/web/infcloud/addressbook.js | 1714 |
1 files changed, 0 insertions, 1714 deletions
diff --git a/radicale_web/web/infcloud/addressbook.js b/radicale_web/web/infcloud/addressbook.js deleted file mode 100644 index fcde7ef..0000000 --- a/radicale_web/web/infcloud/addressbook.js +++ /dev/null @@ -1,1714 +0,0 @@ -/* -InfCloud - the open source CalDAV/CardDAV Web Client -Copyright (C) 2011-2015 - Jan Mate <jan.mate@inf-it.com> - Andrej Lezo <andrej.lezo@inf-it.com> - Matej Mihalik <matej.mihalik@inf-it.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -// AddressbookList Class -function AddressbookList() -{ - this.contacts=new Array(); - this.contacts_hash=new Object(); - this.contacts_hash_uidattr=new Object(); - this.companies=new Array(); - this.companies_hash=new Object(); - this.companies_hash_uidattr=new Object(); - this.vcard_groups=new Object(); - this.contact_categories=new Object(); - this.contact_companies=new Object(); - this.contactLoaded=null; - this.contactToReload=null; - this.vcardGroupLoaded=null; - - this.reset=function() - { - this.contacts.splice(0,this.contacts.length); - this.contacts_hash=new Object(); - this.contacts_hash_uidattr=new Object(); - this.companies.splice(0,this.companies.length); - this.companies_hash=new Object(); - this.companies_hash_uidattr=new Object(); - this.vcard_groups=new Object(); // these are not removed from the interface (it's OK) - this.contact_categories=new Object(); - this.contact_companies=new Object(); - this.contactLoaded=null; - this.contactToReload=null; - this.vcardGroupLoaded=null; - }; - - this.getNewUID=function() - { - // we count with uniqueness of generated hash string - var newUID=null; - newUID=generateUID(); - return newUID; - }; - - this.getLoadedContactUID=function() - { - if(this.contactLoaded!=null) - return this.contactLoaded.uid; - else - return ''; - }; - - this.getSortKey=function(inputContact, inputSettings, inputMode) // inputMode (0=sort, 1=display) - { - var vcard_element=('\r\n'+inputContact.vcard).match(vCard.pre['contentline_N']); - if(vcard_element===null || vcard_element.length!==1) // if the N attribute is not present exactly once, vCard is considered invalid - return false; - - var sortKeyCompanyPart=''; - if(typeof (getCRMSortKey)== 'function' && inputMode==0) - { - sortKeyCompanyPart=getCRMSortKey(inputContact); - if(inputContact.isCompany!=undefined && inputContact.isCompany) - return sortKeyCompanyPart; // for company contact we can return here - } - else if(typeof globalGroupContactsByCompanies!='undefined' && globalGroupContactsByCompanies==true) - { - var sortKeyCompanyPart='\u0009'; - var vcard_orgname=('\r\n'+inputContact.vcard).match(vCard.pre['contentline_ORG']); - if(vcard_orgname!=null && vcard_orgname.length>0) // if more than one ORG is present, use the first one - { - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - var parsed=vcard_orgname[0].match(vCard.pre['contentline_parse']); - var parsed_value=vcardSplitValue(parsed[4], ';'); - - sortKeyCompanyPart=parsed_value[0]+'\u0009'+(parsed_value[1]!=undefined ? parsed_value[1] : '')+'\u0009'; - - if(inputMode==0 && inputContact.isCompany!=undefined && inputContact.isCompany) - return sortKeyCompanyPart; // for company contact we can return here - } - } - - var tmp = []; - var isGroup = this.isContactGroup(inputContact.vcard); - /* backward compatibility for stupid users (remove it in future) */ - if(typeof inputSettings==='string') - tmp = inputSettings.replace(RegExp(',','g'), ', ').split(','); - else if($.isArray(inputSettings)) /* new configuration options (arrays) */ - tmp = inputSettings.slice(); // copy the configuration array - - // display settings for non-group contacts need some flattening - if(inputMode===1 && !isGroup) { - tmp = $.map(tmp, function(el) { - if($.isPlainObject(el.value)) { - return el.value; - } - else { - return [el.value]; - } - - }); - } - - // now flatten the array completely to a company / personal version - tmp = $.map(tmp, function(el) { - if($.isPlainObject(el)) { - if(inputContact.isCompany && el.hasOwnProperty('company')) { - return [el.company]; - } - else if(!inputContact.isCompany && el.hasOwnProperty('personal')) { - return [el.personal]; - } - - return []; - } - - return [el]; - }); - - for(var i=0; i<tmp.length; i++) { - tmp[i] = getContactDataColumn(inputContact, tmp[i]); - } - - sort_value = tmp.join(' ').trim(); - - if(sort_value==='' && isGroup) // if we didn't get a proper sort value for group contacts, use FN - { - var vcard_element2=('\r\n'+inputContact.vcard).match(vCard.pre['contentline_FN']); - if(vcard_element2!=null && vcard_element2.length==1) // if the FN attribute is not present exactly once, vCard is considered invalid - { - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - var parsed=vcard_element2[0].match(vCard.pre['contentline_parse']); - var sort_value=parsed[4]; - } - } - - return (inputMode===0 ? sortKeyCompanyPart+sort_value : sort_value); - }; - - this.isContactGroup=function(inputVcard) - { - var vcard_element=null; - if((vcard_element=('\r\n'+inputVcard).match(vCard.pre['X-ADDRESSBOOKSERVER-KIND']))!=null) - { - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - var parsed=vcard_element[0].match(vCard.pre['contentline_parse']); - if(parsed[4].toLowerCase()=='group') - return true; - } - return false; - }; - - this.getMyContactGroups=function(inputUid) - { - if(this.contacts_hash[inputUid]!=undefined) - { - var myContactGroups=new Array(); - - if((vcard_element=this.contacts_hash[inputUid].vcard.match(vCard.pre['contentline_UID']))!=null) - { - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - parsed=vcard_element[0].match(vCard.pre['contentline_parse']); - - for(var j=0;j<this.vcard_groups[inputUid.replace(RegExp('/[^/]*$',''),'/')].length;j++) - { - if(this.vcard_groups[inputUid.replace(RegExp('/[^/]*$',''),'/')][j].vcard.match(RegExp('\r\nX-ADDRESSBOOKSERVER-MEMBER:urn:uuid:'+parsed[4]+'\r\n','mi'))) - myContactGroups[myContactGroups.length]=this.vcard_groups[inputUid.replace(RegExp('/[^/]*$',''),'/')][j].uid; - } - } - return myContactGroups; - } - else - return null; - }; - - this.getRemoveMeFromContactGroups=function(inputUid, inputContactGroupsUidArr) - { - if(this.contacts_hash[inputUid]!=undefined) - { - var changedContactGroups=new Array(); - - if((vcard_element=this.contacts_hash[inputUid].vcard.match(vCard.pre['contentline_UID']))!=null) - { - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - parsed=vcard_element[0].match(vCard.pre['contentline_parse']); - - for(var j=0;j<this.vcard_groups[inputUid.replace(RegExp('/[^/]*$',''),'/')].length;j++) - { - if(inputContactGroupsUidArr!=null) - { - var skipThis=true; - for(var k=0;k<inputContactGroupsUidArr.length;k++) - if(inputContactGroupsUidArr[k]==this.vcard_groups[inputUid.replace(RegExp('/[^/]*$',''),'/')][j].uid) - { - skipThis=false; - break; - } - - if(skipThis==true) - continue; - } - - var vcard=this.vcard_groups[inputUid.replace(RegExp('/[^/]*$',''),'/')][j].vcard; - - var changedVcard=null; - if(vcard!=(changedVcard=vcard.replaceAll('\r\nX-ADDRESSBOOKSERVER-MEMBER:urn:uuid:'+parsed[4]+'\r\n','\r\n'))) - { - // update the revision in the group vcard - var d = new Date(); - utc=d.getUTCFullYear()+(d.getUTCMonth()+1<10 ? '0':'')+(d.getUTCMonth()+1)+(d.getUTCDate()<10 ? '0':'')+d.getUTCDate()+'T'+(d.getUTCHours()<10 ? '0':'')+d.getUTCHours()+(d.getUTCMinutes()<10 ? '0':'')+d.getUTCMinutes()+(d.getUTCSeconds()<10 ? '0':'')+d.getUTCSeconds()+'Z'; - changedVcard=changedVcard.replace(RegExp('\r\nREV:.*\r\n','mi'),'\r\nREV:'+utc+'\r\n'); - - // "copy" of the original object - changedContactGroups[changedContactGroups.length]=$.extend({},this.vcard_groups[inputUid.replace(RegExp('/[^/]*$',''),'/')][j]); - // new modified vcard group - changedContactGroups[changedContactGroups.length-1].vcard=changedVcard; - } - } - } - return changedContactGroups; - } - else - return null; - }; - - this.getAddMeToContactGroups=function(inputContactObj, inputContactGroupsUidArr) - { - if(!(inputContactGroupsUidArr instanceof Array)) - inputContactGroupsUidArr=[inputContactGroupsUidArr]; - - vcard_element=inputContactObj.vcard.match(vCard.pre['contentline_UID']); - - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - parsed=vcard_element[0].match(vCard.pre['contentline_parse']); - - var changedContactGroups=new Array(); - - for(var j=0;j<this.vcard_groups[inputContactObj.uid.replace(RegExp('/[^/]*$',''),'/')].length;j++) - for(var k=0;k<inputContactGroupsUidArr.length;k++) - if(this.vcard_groups[inputContactObj.uid.replace(RegExp('/[^/]*$',''),'/')][j].uid==inputContactGroupsUidArr[k]) - { - // if the uuid is already a member we remove it from contact-group to avoid duplicate membership - var vcard=this.vcard_groups[inputContactObj.uid.replace(RegExp('/[^/]*$',''),'/')][j].vcard.replaceAll('\r\nX-ADDRESSBOOKSERVER-MEMBER:urn:uuid:'+parsed[4]+'\r\n','\r\n'); - var tmp=vcard.split('\r\n'); - tmp.splice(tmp.length-2,0,'X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:'+parsed[4]); - var changedVcard=tmp.join('\r\n'); - - var d = new Date(); - utc=d.getUTCFullYear()+(d.getUTCMonth()+1<10 ? '0':'')+(d.getUTCMonth()+1)+(d.getUTCDate()<10 ? '0':'')+d.getUTCDate()+'T'+(d.getUTCHours()<10 ? '0':'')+d.getUTCHours()+(d.getUTCMinutes()<10 ? '0':'')+d.getUTCMinutes()+(d.getUTCSeconds()<10 ? '0':'')+d.getUTCSeconds()+'Z'; - changedVcard=changedVcard.replace(RegExp('\r\nREV:.*\r\n','mi'),'\r\nREV:'+utc+'\r\n'); - - // "copy" of the original object - changedContactGroups[changedContactGroups.length]=$.extend({},this.vcard_groups[inputContactObj.uid.replace(RegExp('/[^/]*$',''),'/')][j]); - // new modified vcard group (normalisation is added to fix basic errors in invalid vCard) - changedContactGroups[changedContactGroups.length-1].vcard=normalizeVcard(changedVcard); - } - return changedContactGroups; - }; - - // Contact group list is not sorted, instead "insert sort" is performed - this.insertContactGroup=function(inputContact, forceReload, forceReinsert) - { - if((inputContact.sortkey=this.getSortKey(inputContact, [['{LastName}']], 0))===false || (inputContact.displayvalue=this.getSortKey(inputContact, [['{LastName}']], 1))===false) - return false; //invalid vcard - - var makeActive=null; - var makeChecked=null; - - // do not insert entry with duplicate UID - for(var i=0;i<this.vcard_groups[inputContact.uid.replace(RegExp('/[^/]*$',''),'/')].length;i++) - if(this.vcard_groups[inputContact.uid.replace(RegExp('/[^/]*$',''),'/')][i].uid==inputContact.uid) - { - if(forceReinsert==false && this.vcard_groups[inputContact.uid.replace(RegExp('/[^/]*$',''),'/')][i].displayvalue==inputContact.displayvalue) - { - this.vcard_groups[inputContact.uid.replace(RegExp('/[^/]*$',''),'/')][i]=inputContact; - return 0; - } - else - { - if($('#ResourceCardDAVList').find('[data-id='+jqueryEscapeSelector(inputContact.uid)+']').hasClass('resourceCardDAV_selected')) - makeActive=inputContact.uid; - - if(dataGetChecked('#ResourceCardDAVList').indexOf(inputContact.uid)!=-1 || dataGetChecked('#ResourceCardDAVList').indexOf(inputContact.uid.replace(RegExp('/[^/]*$',''),'/'))!=-1) - makeChecked=inputContact.uid; - - // the contact group name is changed and must be moved to correct place (we first remove it and then reinsert) - this.removeContactGroup(inputContact.uid, false); - break; - } - } - - // find the index where to insert the new contact group - - var insertIndex=this.vcard_groups[inputContact.uid.replace(RegExp('/[^/]*$',''),'/')].length; - for(var i=0;i<this.vcard_groups[inputContact.uid.replace(RegExp('/[^/]*$',''),'/')].length;i++) - if(this.vcard_groups[inputContact.uid.replace(RegExp('/[^/]*$',''),'/')][i].sortkey.customCompare(inputContact.sortkey,globalSortAlphabet,1,false)==1) - { - insertIndex=i; - break; - } - - // insert the contact group - this.vcard_groups[inputContact.uid.replace(RegExp('/[^/]*$',''),'/')].splice(insertIndex, 0, inputContact); - - // insert the contact group to interface - var newElement=globalTranslCardDAVListItem.find('.contact_group').find('.group').clone(); - // the onclick event is disabled until the last drag&drop operation is completed - newElement.click(function(e){ - if(globalAddressbookCollectionsLoading) - return true; - if(e.shiftKey) { - var uid = $(this).attr('data-id'); - $('#ResourceCardDAVList').find('.resourceCardDAV:visible').children('input[type="checkbox"]').each(function(){ - var currentUid = $(this).attr('data-id'); - $(this).prop({'checked':false, 'indeterminate':false}).attr('data-ind', 'true'); - collectionChBoxClick(this, '#ResourceCardDAVList', '.resourceCardDAV_header', '.resourceCardDAV', '.contact_group', false); - }); - var checkbox = $(this).children('input[type="checkbox"]'); - checkbox.prop({'checked':true, 'indeterminate':false}); - groupChBoxClick(checkbox.get(0), '#ResourceCardDAVList', '.resourceCardDAV_header', '.resourceCardDAV', '.contact_group', false); - globalAddressbookList.applyABFilter([uid], false); - } - globalResourceCardDAVList.resourceOrGroupClick(this.getAttribute('data-id')); - }); - newElement.attr('data-id',inputContact.uid); - newElement.find('.resourceCardDAVGroupColor').css('background-color', inputContact.color); - - // note: we need to check the group if the parent collection is checked (and we need to use .attr() instead of .prop() because the element is not in the DOM) - var tmp_check=false; - if($('#ResourceCardDAVList').find('[data-id='+jqueryEscapeSelector(inputContact.uid.replace(RegExp('[^/]*$',''),''))+']').find('input[type=checkbox]').prop('checked')==true && $('#ResourceCardDAVList').find('[data-id='+jqueryEscapeSelector(inputContact.uid.replace(RegExp('[^/]*$',''),''))+']').find('input[type=checkbox]').prop('indeterminate')==false) - tmp_check=true; - newElement.find('input[type=checkbox]').attr('checked', tmp_check).attr({'data-id': inputContact.uid, 'onclick': 'var evt=arguments[0]; evt.stopPropagation(); if($(this).parents(\':eq(2)\').find(\'[class^="r_"]\').length>0) return false; else globalAddressbookList.applyABFilter(groupChBoxClick(this, \'#ResourceCardDAVList\', \'.resourceCardDAV_header\', \'.resourceCardDAV\', \'.contact_group\', true), false);'}); - - newElement.append(vcardUnescapeValue(inputContact.displayvalue)); - newElement.css('display',''); - if($('#ResourceCardDAVList').find('[data-id="'+jqueryEscapeSelector(inputContact.uid.replace(RegExp('/[^/]*$',''),'/'))+'"]').next('.contact_group').find('[data-id="'+jqueryEscapeSelector(inputContact.uid)+'"]').length==0) - $('#ResourceCardDAVList').find('[data-id="'+jqueryEscapeSelector(inputContact.uid.replace(RegExp('/[^/]*$',''),'/'))+'"]').next('.contact_group').children().eq(insertIndex).after(newElement); - - // make the area droppable if the collection is not read-only - if(globalResourceCardDAVList.getCollectionPrivByUID(inputContact.uid.replace(RegExp('[^/]*$',''),''))==false && (typeof globalDisableDragAndDrop=='undefined' || globalDisableDragAndDrop!=true)) - $('#ResourceCardDAVList').find('[data-id="'+jqueryEscapeSelector(inputContact.uid.replace(RegExp('[^/]*$',''),''))+'"]').parent().find('.contact_group').children().eq(insertIndex+1).droppable({ - accept: '.ablist_item', - tolerance: 'pointer', - hoverClass: 'group_dropped_to', - drop: function(event, ui){ - // animate the clone of the dropped (draggable) element - var tmp=ui.helper.clone(); - tmp.appendTo('body') - .animate({opacity: 0, color: 'transparent', height: 0, width: 0, fontSize: 0, lineHeight: 0, paddingLeft: 0, paddingRight: 0},750,function(){tmp.remove()}); - - // disallow to drag the original dropped element until the processing is finished - ui.draggable.draggable('option', 'disabled', true); - - // animate the original dropped element - ui.draggable.animate({opacity: 0.3}, 750); - - // disallow to drop any new element until the processing is finished - $(this).droppable('option', 'disabled', true); - - // show the loader icon - $(this).addClass('r_operate'); - - var tmp2=globalAddressbookList.getContactByUID(ui.draggable.attr('data-id')); - tmp2.addToContactGroupUID=''; - tmp2.removeToContactGroupUID=new Array(); - tmp2.addToContactGroupUID=$(this).attr('data-id'); - tmp2.uiObjects={contact: ui.draggable, resource: $(this).attr('data-id')}; - - lockAndPerformToCollection(tmp2, globalRefAddContact.attr('data-filter-url'), 'ADD_TO_GROUP'); - } - }); - - // if no new makeActive but forceReload is true then reload the current contact group - if(makeActive==null && forceReload==true) - makeActive=globalRefAddContact.attr('data-filter-url'); - - // load the contact group if it was selected - if(makeActive!=null) - { - $('#ResourceCardDAVList').find('.resourceCardDAV_item').find('.resourceCardDAV_selected').removeClass('resourceCardDAV_selected'); - $('#ResourceCardDAVList').find('[data-id='+jqueryEscapeSelector(makeActive.replace(RegExp('[^/]*$',''),''))+']').addClass('resourceCardDAV_selected'); - $('#ResourceCardDAVList').find('[data-id='+jqueryEscapeSelector(makeActive)+']').addClass('resourceCardDAV_selected'); - } - if(makeChecked!=null) - { - $('#ResourceCardDAVList').find('[data-id='+jqueryEscapeSelector(makeChecked)+']').find('input[type=checkbox]').prop('checked',true); - this.applyABFilter(dataGetChecked('#ResourceCardDAVList'), false); - } - }; - - this.removeContactGroup=function(inputUid, loadNext) - { - for(var i=this.vcard_groups[inputUid.replace(RegExp('/[^/]*$',''),'/')].length-1;i>=0;i--) - if(this.vcard_groups[inputUid.replace(RegExp('/[^/]*$',''),'/')][i].uid==inputUid) - { - var uidRemoved=this.vcard_groups[inputUid.replace(RegExp('/[^/]*$',''),'/')][i].uid; - var item=$('#ResourceCardDAVList').find('[data-id^="'+jqueryEscapeSelector(this.vcard_groups[inputUid.replace(RegExp('/[^/]*$',''),'/')][i].uid)+'"]'); - - // remove the item - item.remove(); - this.vcard_groups[inputUid.replace(RegExp('/[^/]*$',''),'/')].splice(i,1); - -// vcardGroupLoaded bolo zrusene, pozriet co s tym - if(loadNext && this.vcardGroupLoaded!=null && this.vcardGroupLoaded.uid==inputUid) - { - this.vcardGroupLoaded=null; - - // set the whole collection as active - var tmp=uidRemoved.match(RegExp('(^.*/)'),''); -// XXX it is no longer needed -// globalResourceCardDAVList.loadAddressbookByUID(tmp[1]); - } - break; - } - }; - - // hide/show contacts in the interface according to contactGroupOrResourceUid or search filter in the interface (contactGroupOrResourceUid==false) - this.applyABFilter=function(contactGroupOrResourceUid, inputForceLoadNext) - { - if(globalCardDAVInitLoad) - return false; - -// XXX docasne, potom dame prec - if(!(contactGroupOrResourceUid instanceof Array)) - return false; - - var vcardGroupOrCollection=[]; - for(var i=0;i<contactGroupOrResourceUid.length;i++) - { - if(contactGroupOrResourceUid[i][contactGroupOrResourceUid[i].length-1]=='/') - vcardGroupOrCollection.push({uid: contactGroupOrResourceUid[i]}); - else // remember the loaded contact group - { - // required only if we want so support collection unloading - - for(var j=0;j<this.vcard_groups[contactGroupOrResourceUid[i].replace(RegExp('/[^/]*$',''),'/')].length;j++) - if(this.vcard_groups[contactGroupOrResourceUid[i].replace(RegExp('/[^/]*$',''),'/')][j].uid==contactGroupOrResourceUid[i]) - { -// vcardGroupLoaded bolo zrusene, pozriet co s tym -// vcardGroupOrCollection=this.vcardGroupLoaded=this.vcard_groups[contactGroupOrResourceUid.replace(RegExp('/[^/]*$',''),'/')][j]; - vcardGroupOrCollection.push(this.vcard_groups[contactGroupOrResourceUid[i].replace(RegExp('/[^/]*$',''),'/')][j]); - } - } - } - - var previousActiveIndex=null; // used to find the nearest contact and set it as selected - - if(this.contactLoaded!=null) - var previousActiveUID=this.contactLoaded.uid; - - // set all contacts as inactive - for(var i=0;i<this.contacts.length;i++) - if(this.contacts[i].headerOnly==undefined) - { - if(this.contacts[i].uid==previousActiveUID) - previousActiveIndex=i; - - this.contacts_hash[this.contacts[i].uid].show=false - this.contacts[i].show=false; // XXX zmenit s5 na false - } - - for(var i=0;i<vcardGroupOrCollection.length;i++) - { - if((vcard=vcardGroupOrCollection[i].vcard)==undefined) // collection - { - for(var j=0;j<this.contacts.length;j++) - if(this.contacts[j].headerOnly==undefined) - { - if(this.contacts[j].uid.indexOf(vcardGroupOrCollection[i].uid)==0 && this.contacts[j].search_hide==false) - { - this.contacts[j].show=true; - this.contacts_hash[this.contacts[j].uid].show=true - } - } - } - else // vcard group - { - var vcardUIDList=new Array(); - // get the members of the array group - while((vcard_element=vcard.match(vCard.pre['X-ADDRESSBOOKSERVER-MEMBER']))!=null) - { - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - parsed=vcard_element[0].match(vCard.pre['contentline_parse']); - vcardUIDList[vcardUIDList.length]=parsed[4].replace('urn:uuid:',''); - // remove the processed parameter - vcard=vcard.replace(vcard_element[0],'\r\n'); - } - - // update the contacts' "show" attribute - for(var j=0;j<vcardUIDList.length;j++) - for(var k=0;k<this.contacts.length;k++) - if(this.contacts[k].headerOnly==undefined) - { - vcard_element=this.contacts[k].vcard.match(vCard.pre['contentline_UID']); - - if(vcard_element!=null) // only for contacts with UID (non-RFC contacts not contains UID) - { - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - parsed=vcard_element[0].match(vCard.pre['contentline_parse']); - - if(vcardUIDList[j]==parsed[4] && this.contacts[k].search_hide==false) - { - this.contacts[k].show=true; - this.contacts_hash[this.contacts[k].uid].show=true - } - } - } - } - } - - var lastActive=null; - var prevHeader=null; - var lastContactForHeader=this.contacts.length-1; - // performance - var tmpListRefChildren=globalRefABListTable.children(); - // init displayed columns text length cache - var columnLengths = []; - for(var i=0; i<getDataColumnCount(); i++) { - columnLengths.push([]); - } - - // the show attribute is now set, we can make changes in the interface - for(var i=this.contacts.length-1;i>=0;i--) - { - if(this.contacts[i].headerOnly==undefined) - { - // find the previous header index - for(var j=i-1;j>=0;j--) - if(this.contacts[j].headerOnly!=undefined && this.contacts[j].headerOnly==true) - { - prevHeader=j; - break; - } - - // performance - var tmpListRefChildren_i=tmpListRefChildren.eq(i); - var tmpListRefChildren_prev=tmpListRefChildren.eq(prevHeader); - - var coll_tmp=this.contacts[i].uid.match(RegExp('^(https?://)([^@/]+(?:@[^@/]+)?)@([^/]+)(.*/)([^/]+/)([^/]*)','i')); - var collection_uid=coll_tmp[1]+coll_tmp[2]+'@'+coll_tmp[3]+coll_tmp[4]+coll_tmp[5]; - var coll_color=globalResourceCardDAVList.getCollectionByUID(collection_uid).color; - this.contacts[i].color = coll_color; - tmpListRefChildren_i.find('.ablist_item_color').css('background-color', coll_color); - switch(this.contacts[i].show) - { - case false: - tmpListRefChildren_i.css('display','none'); - if(tmpListRefChildren_i.hasClass('ablist_item_selected')) - lastActive=i; - - var hideHeader=true; - for(j=prevHeader+1;j<=lastContactForHeader;j++) - if(this.contacts[j].show==true) - { - hideHeader=false; - break; - } - - if(hideHeader) - tmpListRefChildren_prev.css('display','none'); - - break; - case true: - // set the contact header to visible - tmpListRefChildren_prev.css('display',''); - - // set the contact to visible - tmpListRefChildren_i.css('display',''); - - // save column text length into cache - tmpListRefChildren_i.children().slice(globalFixedContactDataColumnsCount).each(function(ind) { - columnLengths[ind].push($(this).text().length); - }); - - break; - default: - break; - } - } - else - lastContactForHeader=i-1; - } - - setDataColumnsWidth(columnLengths); - - // the previously loaded contact is hidden or not exists we need to select a new one - if(inputForceLoadNext==true || $('#vCardEditor').attr('data-editor-state')!='edit' && (lastActive!=null || globalRefABListTable.children('.ablist_item_selected').length==0)) - { - var nextCandidateToLoad=null; - // get the nearest candidate to load - // if we can go forward - if(this.contactToReload!=null) - nextCandidateToLoad=this.contactToReload; - else - { - for(j=(previousActiveIndex==null ? 0 : previousActiveIndex);j<this.contacts.length;j++) - if((this.contacts[j].headerOnly==undefined || this.contacts[j].headerOnly==false) && (this.contacts[j].show==true)) - { - nextCandidateToLoad=this.contacts[j]; - break; - } - // we must go backwards - if(nextCandidateToLoad==null && previousActiveIndex!=null) - { - for(j=previousActiveIndex-1;j>=0;j--) - if((this.contacts[j].headerOnly==undefined || this.contacts[j].headerOnly==false) && (this.contacts[j].show==true)) - { - nextCandidateToLoad=this.contacts[j]; - break; - } - } - } - // make the contact active - globalRefABListTable.children('.ablist_item.ablist_item_selected').removeClass('ablist_item_selected'); - if(nextCandidateToLoad!=null) - { - // prevent re-loading the contact if it is already loaded - if((this.contactToReload!=null||$('#vCardEditor').attr('data-url')!=nextCandidateToLoad.uid) && !globalCardDAVInitLoad) - { - this.loadContactByUID(nextCandidateToLoad.uid); - } - else // because the collection click unselects the active contact we need to re-select it - { - // Make the selected contact active - globalRefABListTable.children('.ablist_item.ablist_item_selected').removeClass('ablist_item_selected'); - globalRefABListTable.children('[data-id='+jqueryEscapeSelector(nextCandidateToLoad.uid)+']').addClass('ablist_item_selected'); - } - // move scrollbar to ensure that the contact is visible in the interface - if((selected_contact=globalRefABListTable.children('.ablist_item_selected')).length==1) - globalRefABList.scrollTop(globalRefABList.scrollTop()+selected_contact.offset().top-globalRefABList.offset().top-globalRefABList.height()*globalKBNavigationPaddingRate); - } - else - { - this.contactLoaded=null; - $('#ABContactColor').css('background-color', ''); - $('#ABContact').html(''); - } - } - if(this.contactToReload!=null&& (selected_contact=globalRefABListTable.find('[data-id="'+this.contactToReload.uid+'"]')).length==1) - { - selected_contact.addClass('ablist_item_selected'); - globalRefABList.scrollTop(globalRefABList.scrollTop()+selected_contact.offset().top-globalRefABList.offset().top-globalRefABList.height()*globalKBNavigationPaddingRate); - - } - } - - this.getABCategories=function(returnSorted) - { - var categoriesArr=[]; - - for(var category in this.contact_categories) - categoriesArr.push(category); - - if(returnSorted) - return categoriesArr.sort(function(x,y){return x.customCompare(y,globalSortAlphabet,1,false)}); - else - return categoriesArr; - } - - this.getABCompanies=function(returnSorted) - { - var companiesArr=[]; - - for(var company in this.contact_companies) - companiesArr.push(company); - - if(returnSorted) - return companiesArr.sort(function(x,y){return x.customCompare(y,globalSortAlphabet,1,false)}); - else - return companiesArr; - } - - this.getABCompanyDepartments=function(inputCompany) - { - var departmentsArr=[]; - - if(this.contact_companies[inputCompany]!=undefined) - departmentsArr=this.contact_companies[inputCompany].departments.slice(); - - return departmentsArr.sort(function(x,y){return x.customCompare(y,globalSortAlphabet,1,false)}); - } - - // Contact list is not sorted, instead "insert sort" is performed - this.insertContact=function(inputContact, forceReload, disableDOM) - { - // Apple "group" vCards - if(this.isContactGroup(inputContact.vcard)) - return this.insertContactGroup(inputContact, forceReload, false); - - // check for company contact - inputContact.isCompany=false; - var vcard_element=inputContact.vcard.match(vCard.pre['X-ABShowAs']); - if(vcard_element!=null) - { - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - parsed=vcard_element[0].match(vCard.pre['contentline_parse']); - if(vcardUnescapeValue(parsed[4]).match(RegExp('^company$','i'))) - inputContact.isCompany=true; - } - - // check for company contact - if((typeof globalContactsExtVcardToData)=='function') - { - inputContact.isLegacy=false; - var vcard_element=inputContact.vcard.match(RegExp('\r\nX-IsLegacy:.*\r\n', 'mi')); - if(vcard_element!=null) - { - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - var parsed=vcard_element[0].match(vCard.pre['contentline_parse']); - if(vcardUnescapeValue(parsed[4]).match(RegExp('^(?:yes|1|true)$', 'i'))) - inputContact.isLegacy=true; - } - } - - // contact UID attr - var vcard_element=inputContact.vcard.match(vCard.pre['contentline_UID']); - if(vcard_element!=null) - { - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - parsed=vcard_element[0].match(vCard.pre['contentline_parse']); - inputContact.uidattr=vcardUnescapeValue(parsed[4]); - } - else // UID attr is REQUIRED - return false; // invalud vcard - - var this_destination=this.contacts; - var this_destination_hash=this.contacts_hash; - var this_destination_hash_uidattr=this.contacts_hash_uidattr; - - // search plugin requirement - inputContact.search_hide=false; - - // CATEGORIES suggestion - var categoriesArr=(inputContact.categories=='' ? [] : vcardSplitValue(inputContact.categories,',')); - var allCategoriesArr=this.getABCategories(false); - - // The search funcionality uses this ASCII value (you can add additional data here) - - // ORG attribute - var tmp=inputContact.vcard; - var orgArr=[]; - var depArr=[]; - var tmpCurrentCompany=''; - var tmpCurrentDepartment=''; - while((vcard_element=tmp.match(vCard.pre['contentline_ORG']))!=null) - { - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - var parsed=vcard_element[0].match(vCard.pre['contentline_parse']); - var parsed_valArr=vcardSplitValue(parsed[4], ';'); - - if(isDataColumnDefined('COMPANY')) { - setContactDataColumn(inputContact, 'COMPANY', vcardUnescapeValue(parsed_valArr[0])); - } - - if(isDataColumnDefined('DEPARTMENT')) { - setContactDataColumn(inputContact, 'DEPARTMENT', vcardUnescapeValue(parsed_valArr[1])); - } - - tmpCurrentCompany=(parsed_valArr[0]==undefined || parsed_valArr[0]=='' ? '' : parsed_valArr[0]); - tmpCurrentDepartment=(parsed_valArr[1]==undefined || parsed_valArr[1]=='' ? '' : parsed_valArr[1]); - - if(tmpCurrentCompany!='') - orgArr[orgArr.length]=vcardUnescapeValue(tmpCurrentCompany); - - if(tmpCurrentDepartment) - depArr[depArr.length]=vcardUnescapeValue(tmpCurrentDepartment); - - // remove the processed parameter - tmp=tmp.replace(vcard_element[0],'\r\n'); - } - var allOrgArr=this.getABCompanies(false); - - // N attribute - while((vcard_element=tmp.match(vCard.pre['contentline_N']))!=null) - { - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - var parsed=vcard_element[0].match(vCard.pre['contentline_parse']); - var parsed_valArr=vcardSplitValue(parsed[4],';'); - - if(isDataColumnDefined('LASTNAME')) { - setContactDataColumn(inputContact, 'LASTNAME', vcardUnescapeValue(parsed_valArr[0])); - } - - if(isDataColumnDefined('FIRSTNAME')) { - setContactDataColumn(inputContact, 'FIRSTNAME', vcardUnescapeValue(parsed_valArr[1])); - } - - if(isDataColumnDefined('MIDDLENAME')) { - setContactDataColumn(inputContact, 'MIDDLENAME', vcardUnescapeValue(parsed_valArr[2])); - } - - if(isDataColumnDefined('PREFIX')) { - setContactDataColumn(inputContact, 'PREFIX', vcardUnescapeValue(parsed_valArr[3])); - } - - if(isDataColumnDefined('SUFFIX')) { - setContactDataColumn(inputContact, 'SUFFIX', vcardUnescapeValue(parsed_valArr[4])); - } - - // remove the processed parameter - tmp=tmp.replace(vcard_element[0],'\r\n'); - } - - // NICKNAME attribute - while((vcard_element=tmp.match(vCard.pre['contentline_NICKNAME']))!=null) - { - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - parsed=vcard_element[0].match(vCard.pre['contentline_parse']); - - if(isDataColumnDefined('NICKNAME')) { - setContactDataColumn(inputContact, 'NICKNAME', parsed[4]); - } - - // remove the processed parameter - tmp=tmp.replace(vcard_element[0],'\r\n'); - } - - // X-PHONETIC-LAST-NAME attribute - while((vcard_element=tmp.match(vCard.pre['contentline_X-PHONETIC-LAST-NAME']))!=null) - { - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - parsed=vcard_element[0].match(vCard.pre['contentline_parse']); - - if(isDataColumnDefined('PHONETICLASTNAME')) { - setContactDataColumn(inputContact, 'PHONETICLASTNAME', parsed[4]); - } - - // remove the processed parameter - tmp=tmp.replace(vcard_element[0],'\r\n'); - } - - // X-PHONETIC-FIRST-NAME attribute - while((vcard_element=tmp.match(vCard.pre['contentline_X-PHONETIC-FIRST-NAME']))!=null) - { - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - parsed=vcard_element[0].match(vCard.pre['contentline_parse']); - - if(isDataColumnDefined('PHONETICFIRSTNAME')) { - setContactDataColumn(inputContact, 'PHONETICFIRSTNAME', parsed[4]); - } - - // remove the processed parameter - tmp=tmp.replace(vcard_element[0],'\r\n'); - } - - // BDAY attribute - while((vcard_element=tmp.match(vCard.pre['contentline_BDAY']))!=null) - { - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - parsed=vcard_element[0].match(vCard.pre['contentline_parse']); - - if(isDataColumnDefined('BIRTHDAY')) { - var bday = null; - try { - bday = $.datepicker.parseDate('yy-mm-dd', parsed[4]); - } - catch(e) { - - } - - if(bday) { - setContactDataColumn(inputContact, 'BIRTHDAY', $.datepicker.formatDate(globalSettings.datepickerformat.value, bday)); - } - } - - // remove the processed parameter - tmp=tmp.replace(vcard_element[0],'\r\n'); - } - - // TITLE attribute - while((vcard_element=tmp.match(vCard.pre['contentline_TITLE']))!=null) - { - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - parsed=vcard_element[0].match(vCard.pre['contentline_parse']); - - if(isDataColumnDefined('JOBTITLE')) { - setContactDataColumn(inputContact, 'JOBTITLE', vcardUnescapeValue(parsed[4])); - } - - // remove the processed parameter - tmp=tmp.replace(vcard_element[0],'\r\n'); - } - - // NOTE attribute - while((vcard_element=tmp.match(vCard.pre['contentline_NOTE']))!=null) - { - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - parsed=vcard_element[0].match(vCard.pre['contentline_parse']); - - if(isDataColumnDefined('NOTETEXT')) { - setContactDataColumn(inputContact, 'NOTETEXT', vcardUnescapeValue(parsed[4])); - } - - // remove the processed parameter - tmp=tmp.replace(vcard_element[0],'\r\n'); - } - - // ADR attribute - while((vcard_element=tmp.match(vCard.pre['contentline_ADR']))!=null) - { - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - var parsed=vcard_element[0].match(vCard.pre['contentline_parse']); - var parsed_valArr=vcardSplitValue(parsed[4],';'); - - if(isDataColumnDefined('ADDRESS')) { - var unescapedArr = $.map(parsed_valArr, function(el) { - if(el) { - return vcardUnescapeValue(el); - } - }); - - setContactDataColumn(inputContact, 'ADDRESS', unescapedArr.join(' '), {'TYPE': getParamsFromContentlineParse(tmp, parsed, 'TYPE', 'X-ABLabel', 'address_type_store_as')}); - } - - // remove the processed parameter - tmp=tmp.replace(vcard_element[0],'\r\n'); - } - - // TEL attribute - while((vcard_element=tmp.match(vCard.pre['contentline_TEL']))!=null) - { - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - parsed=vcard_element[0].match(vCard.pre['contentline_parse']); - - if(isDataColumnDefined('PHONE')) { - setContactDataColumn(inputContact, 'PHONE', parsed[4], {'TYPE': getParamsFromContentlineParse(tmp, parsed, 'TYPE', 'X-ABLabel', 'phone_type_store_as')}); - } - - // remove the processed parameter - tmp=tmp.replace(vcard_element[0],'\r\n'); - } - - // EMAIL attribute - while((vcard_element=tmp.match(vCard.pre['contentline_EMAIL']))!=null) - { - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - parsed=vcard_element[0].match(vCard.pre['contentline_parse']); - - if(isDataColumnDefined('EMAIL')) { - setContactDataColumn(inputContact, 'EMAIL', parsed[4], {'TYPE': getParamsFromContentlineParse(tmp, parsed, 'TYPE', 'X-ABLabel', 'email_type_store_as')}); - } - - // remove the processed parameter - tmp=tmp.replace(vcard_element[0],'\r\n'); - } - - // URL attribute - while((vcard_element=tmp.match(vCard.pre['contentline_URL']))!=null) - { - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - parsed=vcard_element[0].match(vCard.pre['contentline_parse']); - - if(isDataColumnDefined('URL')) { - setContactDataColumn(inputContact, 'URL', parsed[4], {'TYPE': getParamsFromContentlineParse(tmp, parsed, 'TYPE', 'X-ABLabel', 'url_type_store_as')}); - } - - // remove the processed parameter - tmp=tmp.replace(vcard_element[0],'\r\n'); - } - - // X-ABDATE attribute - while((vcard_element=tmp.match(vCard.pre['contentline_X-ABDATE']))!=null) - { - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - parsed=vcard_element[0].match(vCard.pre['contentline_parse']); - - if(isDataColumnDefined('DATES')) { - var abdate = null; - try { - abdate = $.datepicker.parseDate('yy-mm-dd', parsed[4]); - } - catch(e) { - - } - - if(abdate) { - setContactDataColumn(inputContact, 'DATES', $.datepicker.formatDate(globalSettings.datepickerformat.value, abdate), {'TYPE': getParamsFromContentlineParse(tmp, parsed, 'TYPE', 'X-ABLabel', 'date_store_as')}); - } - } - - // remove the processed parameter - tmp=tmp.replace(vcard_element[0],'\r\n'); - } - - // X-ABRELATEDNAMES attribute - while((vcard_element=tmp.match(vCard.pre['contentline_X-ABRELATEDNAMES']))!=null) - { - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - parsed=vcard_element[0].match(vCard.pre['contentline_parse']); - - if(isDataColumnDefined('RELATED')) { - setContactDataColumn(inputContact, 'RELATED', parsed[4], {'TYPE': getParamsFromContentlineParse(tmp, parsed, 'TYPE', 'X-ABLabel', 'person_type_store_as')}); - } - - // remove the processed parameter - tmp=tmp.replace(vcard_element[0],'\r\n'); - } - - // X-SOCIALPROFILE attribute - while((vcard_element=tmp.match(vCard.pre['contentline_X-SOCIALPROFILE']))!=null) - { - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - parsed=vcard_element[0].match(vCard.pre['contentline_parse']); - - if(isDataColumnDefined('PROFILE')) { - setContactDataColumn(inputContact, 'PROFILE', getParamsFromContentlineParse(tmp, parsed, 'X-USER', null, null, true)[0], {'TYPE': getParamsFromContentlineParse(tmp, parsed, 'TYPE', 'X-ABLabel', 'profile_type_store_as')}); - } - - // remove the processed parameter - tmp=tmp.replace(vcard_element[0],'\r\n'); - } - - // IMPP attribute - while((vcard_element=tmp.match(vCard.pre['contentline_IMPP']))!=null) - { - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - parsed=vcard_element[0].match(vCard.pre['contentline_parse']); - if(isDataColumnDefined('IM')) { - setContactDataColumn(inputContact, 'IM', parsed[4].replace(vCard.pre['vcardToData_before_val'], ''), { - 'TYPE': getParamsFromContentlineParse(tmp, parsed, 'TYPE', 'X-ABLabel', 'im_type_store_as'), - 'SERVICE-TYPE': getParamsFromContentlineParse(tmp, parsed, 'X-SERVICE-TYPE', null, 'im_service_type_store_as') - }); - } - - // remove the processed parameter - tmp=tmp.replace(vcard_element[0],'\r\n'); - } - - // CATEGORIES attribute (preparsed) - if(isDataColumnDefined('CATEGORIES')) { - setContactDataColumn(inputContact, 'CATEGORIES', inputContact.categories.splitCustom(',')); - } - - if((inputContact.sortkey=this.getSortKey(inputContact, globalSettings.collectionsort.value || $.map(globalSettings.collectiondisplay.value, function(el) {if($.isPlainObject(el.value)) {return el.value;} else {return [el.value];}}), 0))===false || (inputContact.displayvalue=this.getSortKey(inputContact, globalSettings.collectiondisplay.value, 1))===false) - return false; //invalid vcard - - // if company headers are used add also the header to the searchvalue - var companyHeader=''; - if(typeof globalGroupContactsByCompanies!='undefined' && globalGroupContactsByCompanies==true) - { - if(tmpCurrentCompany!='' || tmpCurrentDepartment!='') - { - if(typeof (getCRMSortKey)=='function') - companyHeader=getCRMSortKey(inputContact); - else - companyHeader=tmpCurrentCompany+'\u0009'+tmpCurrentDepartment+'\u0009'; - } - } - - inputContact.searchvalue=(companyHeader+inputContact.displayvalue).multiReplace(globalSearchTransformAlphabet); - - // CATEGORIES suggestion - for(var i=0;i<allCategoriesArr.length;i++) // if a contact is changed remove it from previous categories - if(categoriesArr.indexOf(allCategoriesArr[i])==-1) - { - var index=this.contact_categories[allCategoriesArr[i]].indexOf(inputContact.uid); - if(index!=-1) - { - this.contact_categories[allCategoriesArr[i]].splice(index,1); - - if(this.contact_categories[allCategoriesArr[i]].length==0) - delete this.contact_categories[allCategoriesArr[i]]; - } - } - for(var i=0;i<categoriesArr.length;i++) // add contact to it's categories - this.contact_categories[categoriesArr[i]]=(this.contact_categories[categoriesArr[i]]==undefined ? [] : this.contact_categories[categoriesArr[i]]).concat(inputContact.uid).sort().unique(); - - // ORG suggestion - for(var i=0;i<allOrgArr.length;i++) // if a contact is changed remove it from previous companies - if(orgArr.indexOf(allOrgArr[i])==-1) - { - var index=this.contact_companies[allOrgArr[i]].uids.indexOf(inputContact.uid); - if(index!=-1) - { - this.contact_companies[allOrgArr[i]].uids.splice(index,1); - - if(this.contact_companies[allOrgArr[i]].uids.length==0) - delete this.contact_companies[allOrgArr[i]]; - } - } - - for(var i=0;i<orgArr.length;i++) // add contact to it's companies - this.contact_companies[orgArr[i]]={uids: (this.contact_companies[orgArr[i]]==undefined ? [] : this.contact_companies[orgArr[i]].uids).concat(inputContact.uid).sort().unique(), departments: (this.contact_companies[orgArr[i]]==undefined ? [] : this.contact_companies[orgArr[i]].departments).concat(depArr).sort().unique()}; - - var makeActive=null; - - // do not insert entry with duplicate UID - if(this_destination_hash[inputContact.uid]!=undefined) - { - var beforeSortKeyChar=''; - if(typeof globalGroupContactsByCompanies!='undefined' && globalGroupContactsByCompanies==true && tmpCurrentCompany=='' && tmpCurrentDepartment=='') - beforeSortKeyChar='\u0009'; - - if(this_destination_hash[inputContact.uid].displayvalue==inputContact.displayvalue && this_destination_hash[inputContact.uid].sortkey==(beforeSortKeyChar+inputContact.sortkey) && this_destination_hash[inputContact.uid].isCompany==inputContact.isCompany && this_destination_hash[inputContact.uid].isLegacy==inputContact.isLegacy) - { - // we perform the normalization here, because we need to check whether the vCard is changed or not - // normalize the vCard when it's loaded first time - if(inputContact.normalized==false) - { - inputContact.normalized=true; - inputContact.vcard=normalizeVcard(additionalRFCFixes(inputContact.vcard)); - } - this_destination_hash[inputContact.uid]=inputContact; - this_destination_hash_uidattr[inputContact.uidattr]=inputContact; // hash by UID attr - - // if the contact is loaded and the editor is in 'show' state, reload it - if(this.contactLoaded!=null && this.contactLoaded.uid==inputContact.uid && this.contactLoaded.vcard!=inputContact.vcard && $('#vCardEditor').attr('data-editor-state')=='show') - { - this.loadContactByUID(inputContact.uid); - show_editor_message('in', 'message_success', localization[globalInterfaceLanguage].contactConcurrentChange,globalHideInfoMessageAfter); - return 0; - } - else // we are editing the contact or it is not active - return -1; - } - else - { - if(this.contactLoaded!=null && this.contactLoaded.uid==inputContact.uid && forceReload==true) - makeActive=inputContact.uid; - if($('#vCardEditor').attr('data-url')==inputContact.uid) - this.contactToReload=this.contactLoaded; - else - this.contactToReload=null; - // the contact name is changed and must be moved to correct place (we first remove it and then reinsert) - this.removeContact(inputContact.uid,false); - } - } - - if(typeof globalGroupContactsByCompanies!='undefined' && globalGroupContactsByCompanies==true) - { - if(tmpCurrentCompany=='' && tmpCurrentDepartment=='') - { - headerValue=headerSortKey='\u0009'; - inputContact.sortkey='\u0009'+inputContact.sortkey; - } - else - { - headerValue=vcardUnescapeValue(tmpCurrentCompany)+(tmpCurrentDepartment=='' ? '' : ' ['+vcardUnescapeValue(tmpCurrentDepartment)+']'); - if(typeof (getCRMSortKey)== 'function') - headerSortKey=getCRMSortKey(inputContact); - else - headerSortKey=tmpCurrentCompany+'\u0009'+tmpCurrentDepartment+'\u0009'; - } - } - else - { - var headerValue=''; - // key value for most common non-alphabet characters is defined as '#' - if(inputContact.sortkey[0]!=undefined) - { - var unicodeValue=inputContact.sortkey.charCodeAt(0); - if(unicodeValue<65 || (unicodeValue>90 && unicodeValue<97) || (unicodeValue>122 && unicodeValue<127)) - { - headerValue='#'; - inputContact.sortkey='#'+inputContact.sortkey; - } - else - headerValue=inputContact.sortkey.charAt(0).toUpperCase(); - } - else - { - headerValue='#'; - inputContact.sortkey='#'; - } - - headerSortKey=headerValue; - } - - // create the header - var headerObject={headerOnly: true, sortkey: headerSortKey, displayvalue: headerValue}; - - // find the index where to insert the new contact O(n*log(n)) - insertIndex=0; - low=0; - high=this_destination.length-1; - if(this_destination.length>0) - while(low<high) - { - insertIndex=low+Math.round((high-low)/2); - result=(cmp_str=this_destination[insertIndex].sortkey).customCompare(inputContact.sortkey,globalSortAlphabet, 1, false); - - if(result==-1) - { - if(insertIndex+1==this_destination.length-1 && typeof this_destination[insertIndex+1]!='undefined' && (cmp_str=this_destination[insertIndex+1].sortkey).customCompare(inputContact.sortkey, globalSortAlphabet, 1, false)==-1) - { - insertIndex+=2; - break; - } - else - low=++insertIndex; - } - else if(result==1) - { - if((cmp_str=this_destination[insertIndex-1].sortkey).customCompare(inputContact.sortkey, globalSortAlphabet, 1, false)==-1) - break; - else - high=--insertIndex; - } - } - - // check for header existence - var headerMiss=1; - for(var i=0;i<this_destination.length;i++) - if(this_destination[i].headerOnly!=undefined && this_destination[i].headerOnly==true && this_destination[i].displayvalue==headerObject.displayvalue) - {headerMiss=0; break;} - - // insert the header if not exists - if(headerMiss) - this_destination.splice(insertIndex,0,headerObject); - // insert the contact - this_destination.splice(insertIndex+headerMiss,0,inputContact); - // insert reference to the contact into hash for much faster search by UID and UID attr - this_destination_hash[inputContact.uid]=this_destination[insertIndex+headerMiss]; - this_destination_hash_uidattr[inputContact.uidattr]=this_destination[insertIndex+headerMiss]; - - // DOM processing can be disabled for performance (then we use mass DOM operations) - if(!disableDOM) - { - // insert header to interface if not exists - if(headerMiss) - { - var newElement=globalOrigABListHeader.clone(); - newElement.children().text(headerObject.displayvalue); - if(globalRefABListTable.children().eq(insertIndex).length==0) // if a tbody is completely empty we cannot search using index - globalRefABListTable.append(newElement); - else - globalRefABListTable.children().eq(insertIndex).before(newElement); - } - - // insert the contact to interface - var newElement=globalOrigABListItem.clone(); - if(typeof inputContact.isLegacy!='undefined' && inputContact.isLegacy) - newElement.css('text-decoration','line-through'); - else - newElement.css('text-decoration','none'); - - newElement.attr('data-id', inputContact.uid); - newElement.children('.ablist_item_color').css('background-color', inputContact.color); - - var columns = getContactDataColumns(inputContact.isCompany); - for(var i=0; i<columns.length; i++) { - $('<td>').text(getContactDataColumn(inputContact, columns[i])).appendTo(newElement); - } - - newElement.click(function() { - if($(this).hasClass('ablist_item_selected') || globalObjectLoading) - return false; - else - globalAddressbookList.loadContactByUID(this.getAttribute('data-id')); - }); - - // set the company icon - if(inputContact.isCompany==true) - newElement.addClass('company'); - - if(typeof globalDisableDragAndDrop=='undefined' || globalDisableDragAndDrop!=true) - newElement.draggable({ - delay: 250, - revert: 'invalid', - scroll: false, - opacity: 0.8, - stack: '#SystemCardDavMATE', - containment: '#SystemCardDavMATE', - appendTo: 'body', - start: function( event, ui ){ - // disallow on read-only collection - if(globalResourceCardDAVList.getCollectionPrivByUID($(this).attr('data-id').replace(RegExp('[^/]*$'),''))==true) - return false; - }, - helper: function(){ - $('#ResourceCardDAVList').find('.resourceCardDAV.ui-droppable').droppable( 'option', 'accept', false); - $('#ResourceCardDAVList').find('.group.ui-droppable').droppable( 'option', 'accept', false); - - $('#ResourceCardDAVList').find('.resourceCardDAV[data-id!='+jqueryEscapeSelector($(this).attr('data-id').replace(RegExp('[^/]+$'),''))+'].ui-droppable').droppable( 'option', 'accept', '.ablist_item'); - var myContactGroups=globalAddressbookList.getMyContactGroups($(this).attr('data-id')); - $('#ResourceCardDAVList').find('.group[data-id^='+jqueryEscapeSelector($(this).attr('data-id').replace(RegExp('[^/]+$'),''))+'].ui-droppable').each(function(index, element){ - if(myContactGroups.indexOf($(element).attr('data-id'))==-1) - $(element).droppable( 'option', 'accept', '.ablist_item'); - }); - - var tmp=$(this).clone(); - tmp.addClass('ablist_item_dragged'); - // we cannot use .css() here, because we need to add !important (problem with Gecko based browsers) - var tmp_style='max-width: '+$(this).outerWidth()+'px;'; - if($(this).css('background-image')!='none') - tmp_style+='background-image: url(images/company_s_w.svg) !important;'; - tmp.attr('style', tmp_style); - - return tmp; - } - }); - - globalRefABListTable.children().eq(insertIndex+headerMiss-1).after(newElement); - - if($('#vCardEditor').attr('data-editor-state')=='edit') - { - if((selected_contact=globalRefABListTable.children('.ablist_item_selected')).length==1) - globalRefABList.scrollTop(globalRefABList.scrollTop()+selected_contact.offset().top-globalRefABList.offset().top-globalRefABList.height()*globalKBNavigationPaddingRate); - } -// toto tu asi nahradit zavolanim trigger('click') co vyrazne sprehladni kod -// => - // load the updated contact (because we first deleted it, we need to set it active) - if(makeActive!=null) - { - // make the contact active - globalRefABListTable.children('.ablist_item.ablist_item_selected').removeClass('ablist_item_selected'); - globalRefABListTable.children().eq(insertIndex+headerMiss).addClass('ablist_item_selected'); - this.loadContactByUID(makeActive); - } - } - } - - this.renderContacs=function() - { - var this_destination=this.contacts; - var this_destination_hash=this.contacts_hash; - - var tmpResultObject=[]; - - for(var i=0;i<this_destination.length;i++) - { - if(this_destination[i].headerOnly!=undefined && this_destination[i].headerOnly==true) - { - var newElement=globalOrigABListHeader.clone(); - newElement.children().text(this_destination[i].displayvalue); - } - else - { - // insert the contact to interface - var newElement=globalOrigABListItem.clone(); - if(typeof this_destination[i].isLegacy!='undefined' && this_destination[i].isLegacy) - newElement.css('text-decoration','line-through'); - else - newElement.css('text-decoration','none'); - - newElement.attr('data-id', this_destination[i].uid); - newElement.find('.ablist_item_color').css('background-color', this_destination[i].color); - - var columns = getContactDataColumns(this_destination[i].isCompany); - for(var j=0; j<columns.length; j++) { - $('<td>').text(getContactDataColumn(this_destination[i], columns[j])).appendTo(newElement); - } - for(; j<getDataColumnCount(); j++) { - $('<td>').appendTo(newElement); - } - - newElement.click(function() { - if($(this).hasClass('ablist_item_selected') || globalObjectLoading) - return false; - else - globalAddressbookList.loadContactByUID(this.getAttribute('data-id')); - }); - - // set the company icon - if(this_destination[i].isCompany==true) - newElement.addClass('company'); - - if(typeof globalDisableDragAndDrop=='undefined' || globalDisableDragAndDrop!=true) - newElement.draggable({ - delay: 250, - revert: 'invalid', - scroll: false, - opacity: 0.8, - stack: '#SystemCardDavMATE', - containment: '#SystemCardDavMATE', - appendTo: 'body', - start: function( event, ui ){ - // disallow on read-only collection - if(globalResourceCardDAVList.getCollectionPrivByUID($(this).attr('data-id').replace(RegExp('[^/]*$'),''))==true) - return false; - }, - helper: function(){ - $('#ResourceCardDAVList').find('.resourceCardDAV.ui-droppable').droppable( 'option', 'accept', false); - $('#ResourceCardDAVList').find('.group.ui-droppable').droppable( 'option', 'accept', false); - - $('#ResourceCardDAVList').find('.resourceCardDAV[data-id!='+jqueryEscapeSelector($(this).attr('data-id').replace(RegExp('[^/]+$'),''))+'].ui-droppable').droppable( 'option', 'accept', '.ablist_item'); - var myContactGroups=globalAddressbookList.getMyContactGroups($(this).attr('data-id')); - $('#ResourceCardDAVList').find('.group[data-id^='+jqueryEscapeSelector($(this).attr('data-id').replace(RegExp('[^/]+$'),''))+'].ui-droppable').each(function(index, element){ - if(myContactGroups.indexOf($(element).attr('data-id'))==-1) - $(element).droppable( 'option', 'accept', '.ablist_item'); - }); - - var tmp=$(this).clone(); - tmp.addClass('ablist_item_dragged'); - // we cannot use .css() here, because we need to add !important (problem with Gecko based browsers) - var tmp_style='max-width: '+$(this).outerWidth()+'px;'; - if($(this).css('background-image')!='none') - tmp_style+='background-image: url(images/company_s_w.svg) !important;'; - tmp.attr('style', tmp_style); - - return tmp; - } - }); - } - tmpResultObject.push(newElement); - } - - globalRefABListTable.empty().append(tmpResultObject); - } - - this.removeContact=function(inputUid, loadNext, isFromPUT) - { - if(!(inputUid instanceof Array)) - inputUid=[inputUid]; - var tmpRex=new RegExp('/[^/]*$',''); - - // Apple "group" vCards - for(var i=inputUid.length-1;i>=0;i--) - for(var j=this.vcard_groups[inputUid[i].replace(tmpRex,'/')].length-1;j>=0;j--) - if(inputUid.indexOf(this.vcard_groups[inputUid[i].replace(tmpRex,'/')][j].uid)!=-1) - return this.removeContactGroup(inputUid[i], loadNext); - - for(var i=this.contacts.length-1;i>=0;i--) - if(this.contacts[i]!=undefined&&inputUid.indexOf(this.contacts[i].uid)!=-1) - { - var inUID=this.contacts[i].uid; - // CATEGORIES suggestion - var categoriesArr=vcardSplitValue(this.contacts[i].categories,','); - for(var j=0;j<categoriesArr.length;j++) - if(this.contact_categories[categoriesArr[j]]!=undefined) - { - var index=this.contact_categories[categoriesArr[j]].indexOf(this.contacts[i].uid); - if(index!=-1) - { - this.contact_categories[categoriesArr[j]].splice(index,1); - - if(this.contact_categories[categoriesArr[j]].length==0) - delete this.contact_categories[categoriesArr[j]]; - } - } - - // ORG suggestion - var tmp=this.contacts[i].vcard; - var orgArr=[]; - while((vcard_element=tmp.match(vCard.pre['contentline_ORG']))!=null) - { - // parsed (contentline_parse) = [1]->"group.", [2]->"name", [3]->";param;param", [4]->"value" - parsed=vcard_element[0].match(vCard.pre['contentline_parse']); - orgArr[orgArr.length]=vcardUnescapeValue(vcardSplitValue(parsed[4],';')[0]); - - // remove the processed parameter - tmp=tmp.replace(vcard_element[0],'\r\n'); - } - for(var j=0;j<orgArr.length;j++) - if(this.contact_companies[orgArr[j]]!=undefined /* there is no suggestion for '' company */ && this.contact_companies[orgArr[j]].uids!=undefined) - { - var index=this.contact_companies[orgArr[j]].uids.indexOf(this.contacts[i].uid); - if(index!=-1) - { - this.contact_companies[orgArr[j]].uids.splice(index,1); - - if(this.contact_companies[orgArr[j]].uids.length==0) - delete this.contact_companies[orgArr[j]]; - } - } - - var nextCandidateToLoad=null; - var item=globalRefABListTable.find('[data-id^="'+jqueryEscapeSelector(this.contacts[i].uid)+'"]'); - - // get the nearest candidate to load - // if we can go forward - for(j=i+1;j<this.contacts.length;j++) - if(this.contacts[j].headerOnly!=true && (typeof isFromPUT!='undefined' || this.contacts[j].show==true)) - { - nextCandidateToLoad=this.contacts[j]; - break; - } - // we must go backwards - if(nextCandidateToLoad==null) - { - for(j=i-1;j>=0;j--) - if(this.contacts[j].headerOnly!=true && this.contacts[j].show==true) - { - nextCandidateToLoad=this.contacts[j]; - break; - } - } - - // remove the item - item.remove(); - this.contacts.splice(i,1); - if(this.contacts_hash[inUID]!=undefined) - { - delete this.contacts_hash_uidattr[this.contacts_hash[inUID].uidattr]; - delete this.contacts_hash[inUID]; - } - else if(this.companies_hash[inUID]!=undefined) - { - delete this.companies_hash_uidattr[this.contacts_hash[inUID].uidattr]; - delete this.companies_hash[inUID]; - } - - // remove the header if there is no more contact - var removeHeader=true; - var prevHeader=null; - // find the previous header index - for(var j=i-1;j>=0;j--) - if(this.contacts[j].headerOnly!=undefined && this.contacts[j].headerOnly==true) - { - prevHeader=j; - break; - } - - // check for contact existence for the found header - if((prevHeader+1)<this.contacts.length && (this.contacts[prevHeader+1].headerOnly==undefined || this.contacts[prevHeader+1].headerOnly!=true)) - removeHeader=false; - - // remove the header - if(removeHeader==true) - { - globalRefABListTable.children().eq(prevHeader).remove(); - this.contacts.splice(prevHeader,1); - } - - // hide header if there is no more visible contacts - var hideHeader=true; - for(j=prevHeader+1;j<this.contacts.length && (this.contacts[j].headerOnly==undefined || this.contacts[j].headerOnly!=true);j++) - if(this.contacts[j].show==true) - { - hideHeader=false; - break; - } - - if(hideHeader) - globalRefABListTable.children().eq(prevHeader).css('display','none'); - - // update the active search - if(globalQs!=null) - globalQs.cache(); - - // load next contact - if(loadNext && this.contactLoaded!=null) - { - if(nextCandidateToLoad!=null) - this.loadContactByUID(nextCandidateToLoad.uid); - else - { - this.contactLoaded=null; - $('#ABContactColor').css('background-color', ''); - $('#ABContact').html(''); - } - } - } - } - - this.checkAndTouchIfExists=function(inputUID,inputEtag,inputTimestamp) - { - if(this.contacts_hash[inputUID]!=undefined) - { - this.contacts_hash[inputUID].timestamp=inputTimestamp; - - if(this.contacts_hash[inputUID].etag==inputEtag) - return true; - else - return false; - } - else - return false; - } - - this.removeOldContacts=function(inputUidBase, inputTimestamp) - { - for(var i=this.contacts.length-1;i>=0;i--) - if(this.contacts[i]!=undefined /* because the header can be deleted with the contact */ && this.contacts[i].timestamp!=undefined && this.contacts[i].uid.indexOf(inputUidBase)==0 && this.contacts[i].timestamp<inputTimestamp) - this.removeContact(this.contacts[i].uid, true); - } - - this.loadContactByUID=function(inputUID) - { - // find the inputUID contact - if(this.contacts_hash[inputUID]!=undefined) - { - globalObjectLoading=true; // temporary disable keyboard navigation - - // normalize the vCard when it's loaded first time - if(this.contacts_hash[inputUID].normalized==false) - { - this.contacts_hash[inputUID].normalized=true; - this.contacts_hash[inputUID].vcard=normalizeVcard(additionalRFCFixes(this.contacts_hash[inputUID].vcard)); - } - - var is_readonly=globalResourceCardDAVList.getCollectionPrivByUID(this.contacts_hash[inputUID].uid.replace(RegExp('[^/]*$'),'')); - var loadContact=this.contactLoaded=this.contacts_hash[inputUID]; - -// CardDAVeditor_cleanup(false, this.contacts_hash[inputUID].isCompany); // editor initialization - - if(vcardToData(loadContact, is_readonly, this.contacts_hash[inputUID].isCompany, 'hide', [])) - $('#EditorBox').fadeTo(0, 1, function(){ /* 0 => no animation */ - globalObjectLoading=false; // re-enable keyboard navigation - }); - else - { - $('#ABContactColor').css('background-color', ''); - $('#ABContact').empty(); - globalDisableAnimationMessageHiding='contactRfcNotCompliant'; - var tmpTime=show_editor_message('out','message_error', localization[globalInterfaceLanguage].contactRfcNotCompliant, globalHideInfoMessageAfter); - setTimeout(function(){globalObjectLoading=false;}, tmpTime); // re-enable keyboard navigation - } - // Make the selected contact active - globalRefABListTable.children('.ablist_item.ablist_item_selected').removeClass('ablist_item_selected'); - globalRefABListTable.children('[data-id='+jqueryEscapeSelector(this.contacts_hash[inputUID].uid)+']').addClass('ablist_item_selected'); - this.contactToReload=null; - if(globalRefABListTable.children('[data-id='+jqueryEscapeSelector(this.contacts_hash[inputUID].uid)+']:visible').length>0&&$('#ABInMessageEditBox').css('display')!='none') - { - animate_message('#ABInMessageEditBox', '#ABInMessageTextEditBox', 0, '-='); - $('#ABInMessageEditBox').css('display',''); - - } - else if(globalRefABListTable.children('[data-id='+jqueryEscapeSelector(this.contacts_hash[inputUID].uid)+']:visible').length==0&&$('#ABInMessageEditBox').css('display')=='none') - { - this.contactToReload=this.contacts_hash[inputUID]; - globalDisableAnimationMessageHiding='errContactHidden'; - $('#ABInMessageEditBox').css('display','block'); - $('#ABInMessageTextEditBox').attr('class','message_success'); - $('#ABInMessageTextEditBox').text(localization[globalInterfaceLanguage][globalDisableAnimationMessageHiding]); - animate_message('#ABInMessageEditBox', '#ABInMessageTextEditBox', globalHideInfoMessageAfter); - } - if($('#ResourceCardDAVListOverlay').is(':visible')) - { - if($('#ABContactOverlay').is(':visible')) - { - var animation = 400; - var duration = globalHideInfoMessageAfter + 2*animation; - setTimeout(function(){ - $('#ResourceCardDAVListOverlay').fadeOut(animation); - $('#ABListOverlay').fadeOut(animation,function(){}); - $('#ABContactOverlay').fadeOut(animation,function(){globalRefAddContact.prop('disabled',false);}); - },duration-animation); - } - else - { - $('#ResourceCardDAVListOverlay').fadeOut(globalEditorFadeAnimation); - $('#ABListOverlay').fadeOut(globalEditorFadeAnimation,function(){}); - } - } - } - else - { - $('#ABContactColor').css('background-color', ''); - $('#ABContact').empty(); -// CardDAVeditor_cleanup(false, false); // editor initialization - } - checkContactFormScrollBar(); - } - - this.loadContactByVcard=function(vcard, color, isCompany, inputEditorMode, inputEditorLockedEntries) - { -// sem callback pre index.html a v pripade ak pridavame usera (nie firmu) pridat do vcard prislusny atribut - if(typeof(globalContactsExtLoadByVcardBefore)=='function') - vcard=globalContactsExtLoadByVcardBefore(vcard, isCompany); - - var loadContact=new Object(); - loadContact.vcard=vcard; - loadContact.isCompany=isCompany; - loadContact.color=color; - - globalObjectLoading=true; // temporary disable keyboard navigation - if(vcardToData(loadContact, false /* XXX check this */, isCompany, inputEditorMode, inputEditorLockedEntries)) - $('#EditorBox').fadeTo(0, 1, function(){ /* 0 => no animation */ - // append the UID of previous contact into "data-id" for "cancel" functionality - $('#vCardEditor').find('[data-type="cancel"]').attr('data-id', globalAddressbookList.getLoadedContactUID()); - this.contactLoaded=null; // do not do this earlier - globalObjectLoading=false; // re-enable keyboard navigation - }); - else - { - // todo: replace with icon or text in the editor div - globalDisableAnimationMessageHiding='contactRfcNotCompliant'; - show_editor_message('out', 'message_error', localization[globalInterfaceLanguage].contactRfcNotCompliant, globalHideInfoMessageAfter); - this.contactLoaded=null; // do not do this earlier - globalObjectLoading=false; // re-enable keyboard navigation - } - checkContactFormScrollBar(); - } - - // DONE - this.getContactByUID=function(inputUID) - { - // find the inputUID contact - if(this.contacts_hash[inputUID]!=undefined) - return this.contacts_hash[inputUID]; - else - return null; - } - - // DONE - this.getContactGroupByUID=function(inputUID) - { - var collectionUID=inputUID.replace(RegExp('[^/]*$'),''); - for(var i=0;i<this.vcard_groups[collectionUID].length;i++) - { - if(this.vcard_groups[collectionUID][i].uid==inputUID) - return this.vcard_groups[collectionUID][i]; - } - return null; - } -} |