resource.js 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  1. /*
  2. CalDavZAP - the open source CalDAV Web Client
  3. Copyright (C) 2011-2015
  4. Jan Mate <jan.mate@inf-it.com>
  5. Andrej Lezo <andrej.lezo@inf-it.com>
  6. Matej Mihalik <matej.mihalik@inf-it.com>
  7. This program is free software: you can redistribute it and/or modify
  8. it under the terms of the GNU Affero General Public License as
  9. published by the Free Software Foundation, either version 3 of the
  10. License, or (at your option) any later version.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU Affero General Public License for more details.
  15. You should have received a copy of the GNU Affero General Public License
  16. along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. function handleCalDAVError(isError, inputResource)
  19. {
  20. var collections='';
  21. collections=globalResourceCalDAVList.collections;
  22. for(var i=0; i<collections.length;i++)
  23. {
  24. if(collections[i].uid!=undefined)
  25. {
  26. var tmp=collections[i].accountUID.match(RegExp('^(https?://)([^@/]+(?:@[^@/]+)?)@([^/]+)(.*/)','i'));
  27. var resource_href=tmp[1]+tmp[3]+tmp[4];
  28. var resource_user=tmp[2];
  29. if(inputResource.href==resource_href && inputResource.userAuth.userName==resource_user)
  30. {
  31. if(globalSettingsSaving =='event' && isError)
  32. {
  33. var isLoaded=false;
  34. if(typeof globalCrossServerSettingsURL!='undefined'&&globalCrossServerSettingsURL!=null&globalCrossServerSettingsURL)
  35. {
  36. var uidParts=(collections[i].uid).match(RegExp('/([^/]+/[^/]+/)$'));
  37. var tmpParts = uidParts[1].match('^(.*/)([^/]+)/$');
  38. var checkHref=decodeURIComponent(tmpParts[1])+tmpParts[2]+'/';
  39. var found=false;
  40. for(var l=0;l<globalSettings.loadedcalendarcollections.value.length;l++)
  41. {
  42. var tmpParts2 = globalSettings.loadedcalendarcollections.value[l].match('^(.*/)([^/]+)/([^/]+)/$');
  43. var checkHref2=decodeURIComponent(tmpParts2[2])+'/'+tmpParts2[3]+'/';
  44. if(checkHref==checkHref2)
  45. {
  46. found=true;
  47. break;
  48. }
  49. }
  50. isLoaded=found;
  51. }
  52. else
  53. {
  54. var uidParts=(collections[i].uid).match(RegExp('^(https?://)([^@/]+(?:@[^@/]+)?)@(.*)'));
  55. var checkHref = uidParts[1]+uidParts[3];
  56. isLoaded=(globalSettings.loadedcalendarcollections.value.indexOf(checkHref)!=-1);
  57. }
  58. if(isLoaded && collections[i].oldSyncToken=='')
  59. {
  60. var newObj = $.extend(collections[i],{makeLoaded:true});
  61. globalResourceCalDAVList.insertResource(newObj, collections[i].resourceIndex, true);
  62. updateMainLoaderText(collections[i].listType);
  63. updateMainLoader();
  64. }
  65. }
  66. if(isError)
  67. $('#ResourceCalDAVList').find('[data-id="'+collections[i].uid+'"]').addClass('r_error');
  68. else
  69. $('#ResourceCalDAVList').find('[data-id="'+collections[i].uid+'"]').removeClass('r_error');
  70. }
  71. }
  72. }
  73. collections=globalResourceCalDAVList.TodoCollections;
  74. for(var i=0; i<collections.length;i++)
  75. {
  76. if(collections[i].uid!=undefined)
  77. {
  78. var tmp=collections[i].accountUID.match(RegExp('^(https?://)([^@/]+(?:@[^@/]+)?)@([^/]+)(.*/)','i'));
  79. var resource_href=tmp[1]+tmp[3]+tmp[4];
  80. var resource_user=tmp[2];
  81. if(inputResource.href==resource_href && inputResource.userAuth.userName==resource_user)
  82. {
  83. if(globalSettingsSaving =='todo' && isError)
  84. {
  85. var isLoaded=false;
  86. if(typeof globalCrossServerSettingsURL!='undefined'&&globalCrossServerSettingsURL!=null&globalCrossServerSettingsURL)
  87. {
  88. var uidParts=(collections[i].uid).match(RegExp('/([^/]+/[^/]+/)$'));
  89. var tmpParts = uidParts[1].match('^(.*/)([^/]+)/$');
  90. var checkHref=decodeURIComponent(tmpParts[1])+tmpParts[2]+'/';
  91. var found=false;
  92. for(var l=0;l<globalSettings.loadedtodocollections.value.length;l++)
  93. {
  94. var tmpParts2 = globalSettings.loadedtodocollections.value[l].match('^(.*/)([^/]+)/([^/]+)/$');
  95. var checkHref2=decodeURIComponent(tmpParts2[2])+'/'+tmpParts2[3]+'/';
  96. if(checkHref==checkHref2)
  97. {
  98. found=true;
  99. break;
  100. }
  101. }
  102. isLoaded=found;
  103. }
  104. else
  105. {
  106. var uidParts=(collections[i].uid).match(RegExp('^(https?://)([^@/]+(?:@[^@/]+)?)@(.*)'));
  107. var checkHref = uidParts[1]+uidParts[3];
  108. isLoaded=(globalSettings.loadedtodocollections.value.indexOf(checkHref)!=-1);
  109. }
  110. if(isLoaded && collections[i].oldSyncToken=='')
  111. {
  112. var newObj = $.extend(collections[i],{makeLoaded:true});
  113. globalResourceCalDAVList.insertResource(newObj, collections[i].resourceIndex, false);
  114. updateMainLoaderText(collections[i].listType);
  115. updateMainLoader();
  116. }
  117. }
  118. if(isError)
  119. $('#ResourceCalDAVTODOList').find('[data-id="'+collections[i].uid+'"]').addClass('r_error');
  120. else
  121. $('#ResourceCalDAVTODOList').find('[data-id="'+collections[i].uid+'"]').removeClass('r_error');
  122. }
  123. }
  124. }
  125. }
  126. function unloadCalDAVCollection(unloadArray, isEvent)
  127. {
  128. var collArray = {}, todoString='';
  129. if(isEvent)
  130. collArray=globalResourceCalDAVList.collections;
  131. else
  132. {
  133. collArray=globalResourceCalDAVList.TodoCollections;
  134. todoString='TODO';
  135. }
  136. for(var i=0; i<collArray.length; i++)
  137. {
  138. if(collArray[i].uid!=undefined)
  139. {
  140. var uidParts=(collArray[i].uid).match(RegExp('^(https?://)([^@/]+(?:@[^@/]+)?)@(.*)'));
  141. var checkHref = uidParts[1]+uidParts[3];
  142. if(unloadArray.indexOf(checkHref)!=-1)
  143. {
  144. $('#CalendarLoader'+todoString).children('.loaderInfo').text(localization[globalInterfaceLanguage].unloadingCalendars);
  145. if(window['globalVisibleCalDAV'+todoString+'Collections'].indexOf(collArray[i].uid)!=-1)
  146. window['globalVisibleCalDAV'+todoString+'Collections'].splice(window['globalVisibleCalDAV'+todoString+'Collections'].indexOf(collArray[i].uid),1);
  147. if(isEvent)
  148. {
  149. var beforeScroll = $('#main').width()-$('#calendar').width();
  150. $('#calendar').fullCalendar('removeEventSource', collArray[i].fcSource);
  151. var afterScroll = $('#main').width()-$('#calendar').width();
  152. rerenderCalendar(beforeScroll!=afterScroll);
  153. globalEventList.events[collArray[i].uid]={};
  154. globalEventList.displayEventsArray[collArray[i].uid]=new Array();
  155. }
  156. else
  157. {
  158. var beforeScroll = $('#mainTODO').width()-$('#todoList').width();
  159. $('#todoList').fullCalendar('removeEventSource', collArray[i].fcSource);
  160. var afterScroll = $('#mainTODO').width()-$('#todoList').width();
  161. rerenderTodo(beforeScroll!=afterScroll);
  162. globalEventList.todos[collArray[i].uid]={};
  163. globalEventList.displayTodosArray[collArray[i].uid]=new Array();
  164. }
  165. collArray[i].fcSource = null;
  166. collArray[i].someChanged=false;
  167. collArray[i].makeLoaded=false;
  168. collArray[i].syncToken='';
  169. collArray[i].oldSyncToken='';
  170. }
  171. }
  172. }
  173. if((globalSettingsSaving=='event' || globalSettingsSaving=='todo') && !globalFirstHideLoader)
  174. setTimeout(function(){hideUnloadCollectionCallback(globalSettingsSaving);},300);
  175. }
  176. function addLoadCalDAVCollection(loadingArray, isEvent)
  177. {
  178. var collArray = {}, todoString='';
  179. if(isEvent)
  180. collArray=globalResourceCalDAVList.collections;
  181. else
  182. {
  183. collArray=globalResourceCalDAVList.TodoCollections;
  184. todoString='TODO';
  185. }
  186. for(var i=0; i<collArray.length; i++)
  187. {
  188. if(collArray[i].uid!=undefined)
  189. {
  190. var uidParts=(collArray[i].uid).match(RegExp('^(https?://)([^@/]+(?:@[^@/]+)?)@(.*)'));
  191. var checkHref = uidParts[1]+uidParts[3];
  192. if(loadingArray.indexOf(checkHref)!=-1&&!collArray[i].makeLoaded)
  193. {
  194. collArray[i].urlArray={};
  195. var resDOMItem=$('#ResourceCalDAV'+todoString+'List').find('.resourceCalDAV'+todoString+'_item[data-id="'+jqueryEscapeSelector(collArray[i].uid)+'"]');
  196. collArray[i].someChanged=true;
  197. collArray[i].makeLoaded=true;
  198. var rex=vCalendar.pre['accountUidParts'];
  199. var tmp=collArray[i].accountUID.match(rex);
  200. var resourceCalDAV_href=tmp[1]+tmp[3]+tmp[4];
  201. var resourceCalDAV_user=tmp[2];
  202. for(var j=0;j<globalAccountSettings.length;j++)
  203. if(globalAccountSettings[j].href==resourceCalDAV_href && globalAccountSettings[j].userAuth.userName==resourceCalDAV_user && globalLoadedPrincipals.indexOf(resourceCalDAV_href)==-1)
  204. {
  205. globalLoadedPrincipals.push(globalAccountSettings[j].href);
  206. break;
  207. }
  208. var resDOMHeader=resDOMItem.prevUntil('.resourceCalDAV'+todoString+'_header').last().prev();
  209. if(!resDOMHeader.length)
  210. resDOMHeader=resDOMItem.prev();
  211. resDOMHeader.css('display','block');
  212. resDOMItem.css('display','');
  213. var input=resDOMItem.find('input[type=checkbox]').not('.unloadCheck');
  214. input.prop('checked',true);
  215. collectionChBoxClick(input.get(0), '#ResourceCalDAV'+todoString+'List', '.resourceCalDAV'+todoString+'_header', '.resourceCalDAV'+todoString+'_item', null, false);
  216. if(window['globalVisibleCalDAV'+todoString+'Collections'].indexOf(collArray[i].uid)==-1)
  217. window['globalVisibleCalDAV'+todoString+'Collections'].splice(window['globalVisibleCalDAV'+todoString+'Collections'].length, 0, collArray[i].uid);
  218. collArray[i].newlyAdded=true;
  219. }
  220. }
  221. }
  222. var calendarsArray=new Array();
  223. for(var i=0;i<collArray.length;i++)
  224. if(collArray[i].uid!=undefined)
  225. calendarsArray[calendarsArray.length]={displayValue:collArray[i].displayvalue,uid:collArray[i].uid, permissions_read_only:collArray[i].permissions.read_only, makeLoaded:collArray[i].makeLoaded};
  226. calendarsArray.sort(customResourceCompare);
  227. globalResourceCalDAVList.sortedCollections = calendarsArray;
  228. }
  229. // ResourceCalDAVList Class
  230. function ResourceCalDAVList()
  231. {
  232. this.collections=new Array();
  233. this.TodoCollections=new Array();
  234. this.calendarsLoaded=null;
  235. this.counterList=new Array();
  236. this.sortedTodoCollections=new Array();
  237. this.sortedCollections=new Array();
  238. this.reset=function()
  239. {
  240. this.TodoCollections.splice(0, this.TodoCollections.length);
  241. this.collections.splice(0, this.collections.length);
  242. this.counterList=new Array();
  243. this.sortedTodoCollections=new Array();
  244. this.sortedCollections=new Array();
  245. }
  246. // resource header value
  247. this.getHeaderValue=function(inputResource)
  248. {
  249. var re=new RegExp('^(https?://)([^@/]+(?:@[^@/]+)?)@([^/]+).*/([^/]*)/','i');
  250. var tmp=inputResource.accountUID.match(re);
  251. var tmp_host=tmp[3]; // hostname [%H]
  252. var tmp_host_wo_port=tmp[3].replace(vCalendar.pre['numberPortRex'],''); // hostname without port [%h]
  253. var tmp_domain=tmp_host_wo_port.replace(vCalendar.pre['domainRex'], ''); // domain name [%D]
  254. var tmp_domain_min=tmp_host_wo_port.match(vCalendar.pre['domainNameRex'])[2]; // domain name min. (only 1 or 2 level domain string) [%d]
  255. var tmp_principal=decodeURIComponent(tmp[4]); // principal username [%P]
  256. var tmp_principal_wo_domain=decodeURIComponent(tmp[4]).replace(vCalendar.pre['principalUserNameRex'],''); // principal username without @domain.com [%p]
  257. var tmp_user=inputResource.userAuth.userName; // login name [%U]
  258. var tmp_user_wo_domain=inputResource.userAuth.userName.replace(vCalendar.pre['loginRex'],''); // login name without @domain.com [%u]
  259. if(!inputResource.subscription && (typeof inputResource.hrefLabel!='string' || inputResource.hrefLabel=='' || (inputResource.hrefLabel=='%x' && inputResource.headervalue=='')))
  260. inputResource.hrefLabel='%d/%p [%u]';
  261. else if(inputResource.subscription && (typeof inputResource.hrefLabel!='string' || inputResource.hrefLabel==''))
  262. inputResource.hrefLabel=localization[globalInterfaceLanguage].txtSubscribed;
  263. var result=inputResource.hrefLabel;
  264. result=result.replace(vCalendar.pre['HRex'], tmp_host);
  265. result=result.replace(vCalendar.pre['hRex'], tmp_host_wo_port);
  266. result=result.replace(vCalendar.pre['DRex'], tmp_domain);
  267. result=result.replace(vCalendar.pre['dRex'], tmp_domain_min);
  268. result=result.replace(vCalendar.pre['PRex'], tmp_principal);
  269. result=result.replace(vCalendar.pre['pRex'], tmp_principal_wo_domain);
  270. result=result.replace(vCalendar.pre['URex'], tmp_user);
  271. result=result.replace(vCalendar.pre['uRex'], tmp_user_wo_domain);
  272. result=result.replace(vCalendar.pre['xRex'], inputResource.headervalue);
  273. inputResource.hrefLabel=result;
  274. return result;
  275. }
  276. this.getSortKey=function(inputResource, forHeader, inputResourceIndex)
  277. {
  278. var re=new RegExp('^(https?://)([^@/]+(?:@[^@/]+)?)@([^/]+)(.*/)([^/]+/)([^/]+/)([^/]*)','i');
  279. var tmp=inputResource.uid.match(re);
  280. var out='';
  281. if(!inputResource.subscription)
  282. out='A';
  283. else
  284. out='B';
  285. // custom sorting (instead of alphabetical)
  286. if(globalSettings.resourcealphabetsorting.value!=true)
  287. out+=inputResourceIndex.pad(String(globalAccountSettings.length).length);
  288. out+=tmp[1]+tmp[3]+'/'+(inputResource.hrefLabel==undefined || inputResource.hrefLabel==null ? tmp[5] : inputResource.hrefLabel)+' '+inputResource.userAuth.userName;
  289. if(forHeader==false)
  290. out+=' '+inputResource.displayvalue;
  291. return out;
  292. }
  293. // Resource list is not sorted, instead "insert sort" is performed
  294. this.insertResource=function(inputResource, index, isEvent)
  295. {
  296. var oldHrefLabel = inputResource.hrefLabel;
  297. var headerValue = this.getHeaderValue(inputResource);
  298. inputResource.sortkey=this.getSortKey(inputResource, false, index);
  299. var collObject={};
  300. var todoString = '';
  301. var makeChecked=false;
  302. var nameChanged=false;
  303. if(isEvent)
  304. collObject = this.collections;
  305. else
  306. {
  307. collObject = this.TodoCollections;
  308. todoString = 'TODO';
  309. }
  310. // do not insert entry with duplicate UID
  311. for(var i=0;i<collObject.length;i++)
  312. if(collObject[i].uid==inputResource.uid)
  313. {
  314. collObject[i].urlArray={};
  315. var resDOMItem=$('#ResourceCalDAV'+todoString+'List').find('.resourceCalDAV'+todoString+'_item[data-id="'+jqueryEscapeSelector(inputResource.uid)+'"]');
  316. if(collObject[i].displayvalue==inputResource.displayvalue && collObject[i].permissions.read_only==inputResource.permissions.read_only && collObject[i].headervalue==inputResource.headervalue)
  317. {
  318. collObject[i]=$.extend(inputResource, {fcSource: collObject[i].fcSource, syncToken: collObject[i].syncToken, oldSyncToken: collObject[i].oldSyncToken, newlyAdded: collObject[i].newlyAdded,forceSyncPROPFIND: collObject[i].forceSyncPROPFIND});
  319. return 0;
  320. }
  321. else
  322. {
  323. nameChanged=true;
  324. $.extend(inputResource, {fcSource: collObject[i].fcSource, syncToken: collObject[i].syncToken, oldSyncToken: collObject[i].oldSyncToken, newlyAdded: collObject[i].newlyAdded,forceSyncPROPFIND: collObject[i].forceSyncPROPFIND});
  325. makeChecked=resDOMItem.find('input[type=checkbox]').not('.unloadCheck').prop('checked');
  326. // the collection name is changed and must be moved to correct place (we first remove it and then reinsert)
  327. this.removeResource(inputResource.uid, false,isEvent);
  328. break;
  329. }
  330. }
  331. if(!globalCalDAVInitLoad&&!nameChanged)
  332. {
  333. var uidParts=inputResource.uid.match(RegExp('^(https?://)([^@/]+(?:@[^@/]+)?)@(.*)'));
  334. var checkHref = uidParts[1]+uidParts[3];
  335. var loadedColl=null;
  336. var isLoaded=false;
  337. if(isEvent)
  338. loadedColl=globalSettings.loadedcalendarcollections.value;
  339. else
  340. loadedColl=globalSettings.loadedtodocollections.value;
  341. if(typeof globalCrossServerSettingsURL!='undefined'&&globalCrossServerSettingsURL!=null&globalCrossServerSettingsURL)
  342. {
  343. var uidParts=inputResource.uid.match(RegExp('/([^/]+/[^/]+/)$'));
  344. var tmpParts = uidParts[1].match('^(.*/)([^/]+)/$');
  345. var checkHref3=decodeURIComponent(tmpParts[1])+tmpParts[2]+'/';
  346. var found=false;
  347. for(var l=0;l<loadedColl.length;l++)
  348. {
  349. var tmpParts2 = loadedColl[l].match('^(.*/)([^/]+)/([^/]+)/$');
  350. var checkHref2=decodeURIComponent(tmpParts2[2])+'/'+tmpParts2[3]+'/';
  351. if(checkHref3==checkHref2)
  352. {
  353. found=true;
  354. break;
  355. }
  356. }
  357. isLoaded=found;
  358. }
  359. else
  360. isLoaded=(loadedColl.indexOf(checkHref)!=-1);
  361. // if(!isLoaded)
  362. // loadedColl.push(checkHref);
  363. if(!isLoaded)
  364. {
  365. inputResource.makeLoaded=false;
  366. inputResource.newlyAdded=false;
  367. }
  368. else
  369. {
  370. inputResource.makeLoaded=true;
  371. inputResource.newlyAdded=true;
  372. }
  373. inputResource.oldSyncToken = '';
  374. inputResource.someChanged=false;
  375. makeChecked=true;
  376. }
  377. // create header
  378. var headerObject={headerOnly: true, sortkey: this.getSortKey(inputResource, true, index), displayvalue: (oldHrefLabel=='%x' ? headerValue.replace(RegExp('^[^#]+#'),'') : headerValue), index:0};
  379. // find the index where to insert the new resource
  380. // find the index where to insert the new resource O(n*log(n))
  381. var insertIndex=0;
  382. var low=0;
  383. var high=collObject.length-1;
  384. if(collObject.length>0)
  385. while(low<high)
  386. {
  387. insertIndex=low+Math.round((high-low)/2);
  388. var result=(cmp_str=collObject[insertIndex].sortkey).customCompare(inputResource.sortkey,globalSortAlphabet,1,false);
  389. if(result==-1)
  390. {
  391. if(insertIndex+1==collObject.length-1 && typeof collObject[insertIndex+1]!='undefined' && (cmp_str=collObject[insertIndex+1].sortkey).customCompare(inputResource.sortkey,globalSortAlphabet,1,false)==-1)
  392. {
  393. insertIndex+=2;
  394. break;
  395. }
  396. else
  397. low=++insertIndex;
  398. }
  399. else if(result==1)
  400. {
  401. if((cmp_str=collObject[insertIndex-1].sortkey).customCompare(inputResource.sortkey,globalSortAlphabet,1,false)==-1)
  402. break;
  403. else
  404. high=--insertIndex;
  405. }
  406. }
  407. // check for header existence
  408. var headerMiss=1;
  409. for(var i=0;i<collObject.length;i++)
  410. if(collObject[i].headerOnly==true && collObject[i].displayvalue==headerObject.displayvalue)
  411. {
  412. headerMiss=0;
  413. break;
  414. }
  415. // insert header if not exists
  416. if(headerMiss)
  417. {
  418. headerObject.index=insertIndex;
  419. collObject.splice(insertIndex, 0, headerObject);
  420. }
  421. // insert the resource
  422. if(collObject.length==1 && globalCalDAVInitLoad)
  423. $('#SystemCalDavZAP .fc-header-center ').addClass('r_operate_all');
  424. this.counterList[inputResource.uid+' '+inputResource.listType]={collectionLength: 0, counter: 0, uid: inputResource.uid, isLoading: false, isSaving: false};
  425. collObject.splice(insertIndex+headerMiss, 0, inputResource);
  426. if(!nameChanged)
  427. {
  428. if(isEvent)
  429. {
  430. globalEventList.displayEventsArray[inputResource.uid]=new Array();
  431. globalEventList.events[inputResource.uid]={};
  432. }
  433. else
  434. {
  435. globalEventList.displayTodosArray[inputResource.uid]=new Array();
  436. globalEventList.todos[inputResource.uid]={};
  437. }
  438. }
  439. var resList = '#ResourceCalDAV'+todoString+'List';
  440. var resHeader = '.resourceCalDAV'+todoString+'_header';
  441. var resItem = '.resourceCalDAV'+todoString+'_item';
  442. if(headerMiss)
  443. {
  444. var newElement=$('#ResourceCalDAV'+todoString+'ListTemplate').find('.resourceCalDAV'+todoString+'_header').clone().wrap('<div>');
  445. newElement.append(headerObject.displayvalue);
  446. if(todoString=='')
  447. newElement.find('input[type=checkbox]').attr('onclick','resourceChBoxClick(this, \'#\'+$(this).parent().parent().attr(\'id\'), \''+resHeader+'\', false);if(isCalDAVLoaded && $(this).parent().parent().attr(\'id\')== \'ResourceCalDAV'+todoString+'List\'){$(this).prop(\'checked\')?enableResource($(this).parent()):disableResource($(this).parent());}');
  448. else
  449. newElement.find('input[type=checkbox]').attr('onclick','resourceChBoxClick(this, \'#\'+$(this).parent().parent().attr(\'id\'), \''+resHeader+'\', false);if(isCalDAVLoaded && $(this).parent().parent().attr(\'id\')== \'ResourceCalDAV'+todoString+'List\'){$(this).prop(\'checked\')?enableResourceTodo($(this).parent()):disableResourceTodo($(this).parent());}');
  450. newElement.css('display', 'none');
  451. newElement=newElement.parent().html();
  452. $('#ResourceCalDAV'+todoString+'List').children().eq(insertIndex).after(newElement);
  453. }
  454. // insert the resource to interface
  455. var newElement = $('#ResourceCalDAV'+todoString+'ListTemplate').find('.resourceCalDAV'+todoString+'_item').clone().wrap('<div>');
  456. var par=inputResource.uid.split('/');
  457. if(inputResource.permissions.read_only)
  458. newElement.addClass('resourceCalDAV_item_ro');
  459. newElement.attr('data-id', inputResource.uid);
  460. if(globalCalDAVInitLoad)
  461. newElement.addClass('r_operate');
  462. newElement.html("<div class='resourceCalDAVColor' style='background:"+inputResource.ecolor+"'></div><input type='text' class='colorPicker'/><input type='checkbox' name="+inputResource.uid+" />"+$('<div/>').text(inputResource.displayvalue).html());
  463. newElement.attr('title', $('<div/>').text(inputResource.displayvalue).html());
  464. if(todoString=='')
  465. newElement.find('input[type=checkbox]').attr({'data-id':inputResource.uid, 'onclick':'var evt = arguments[0];evt.stopPropagation();collectionChBoxClick(this, \'#\'+$(this).parent().parent().attr(\'id\'), \''+resHeader+'\', \''+resItem+'\', null, false);if(isCalDAVLoaded && $(this).parent().parent().attr(\'id\')== \'ResourceCalDAV'+todoString+'List\'){$(this).prop(\'checked\')?enableCalendar(\''+inputResource.uid+'\'):disableCalendar(\''+inputResource.uid+'\');}'});
  466. else
  467. newElement.find('input[type=checkbox]').attr({'data-id':inputResource.uid, 'onclick':'var evt = arguments[0];evt.stopPropagation();collectionChBoxClick(this, \'#\'+$(this).parent().parent().attr(\'id\'), \''+resHeader+'\', \''+resItem+'\', null, false);if(isCalDAVLoaded && $(this).parent().parent().attr(\'id\')== \'ResourceCalDAV'+todoString+'List\'){$(this).prop(\'checked\')?enableCalendarTodo(\''+inputResource.uid+'\'):disableCalendarTodo(\''+inputResource.uid+'\');}'});
  468. newElement.click(function(e){
  469. if(($(this).hasClass('resourceCalDAV_item')&&globalEventCollectionsLoading) || ($(this).hasClass('resourceCalDAVTODO_item')&&globalTodoCollectionsLoading))
  470. return true;
  471. if(e.shiftKey) {
  472. if(isEvent)
  473. enableOne($(this).attr('data-id'));
  474. else
  475. enableOneTodo($(this).attr('data-id'));
  476. }
  477. $('#ResourceCalDAV'+todoString+'List .resourceCalDAV_item_selected').removeClass('resourceCalDAV_item_selected');
  478. $(this).addClass('resourceCalDAV_item_selected');
  479. });
  480. if(typeof globalCalendarColorPropertyXmlns== 'undefined' || globalCalendarColorPropertyXmlns== null || globalCalendarColorPropertyXmlns==='' || globalCalendarColorPropertyXmlns!==false)
  481. bindColorPickerClick(newElement.find('.resourceCalDAVColor'));
  482. $('#ResourceCalDAV'+todoString+'List').children().eq(insertIndex+headerMiss).after(newElement);
  483. console.log('inserted inputResource with uid=' + inputResource.uid, newElement)
  484. if(inputResource.makeLoaded)
  485. {
  486. var resDOMHeader=newElement.prevUntil('.resourceCalDAV'+todoString+'_header').last().prev();
  487. if(!resDOMHeader.length)
  488. resDOMHeader=newElement.prev();
  489. resDOMHeader.css('display','block');
  490. var rex=vCalendar.pre['accountUidParts'];
  491. var tmp=inputResource.accountUID.match(rex);
  492. var resourceCalDAV_href=tmp[1]+tmp[3]+tmp[4];
  493. var resourceCalDAV_user=tmp[2];
  494. for(var i=0;i<globalAccountSettings.length;i++)
  495. if(globalAccountSettings[i].href==resourceCalDAV_href && globalAccountSettings[i].userAuth.userName==resourceCalDAV_user && globalLoadedPrincipals.indexOf(resourceCalDAV_href)==-1)
  496. {
  497. globalLoadedPrincipals.push(globalAccountSettings[i].href);
  498. break;
  499. }
  500. }
  501. else
  502. newElement.css('display','none');
  503. // restore the checked state
  504. if(makeChecked)
  505. {
  506. if(window['globalVisibleCalDAV'+todoString+'Collections'].indexOf(inputResource.uid)==-1)
  507. window['globalVisibleCalDAV'+todoString+'Collections'].splice(window['globalVisibleCalDAV'+todoString+'Collections'].length, 0, inputResource.uid);
  508. $('#ResourceCalDAV'+todoString+'List').children().eq(insertIndex+headerMiss+1).find('input[type=checkbox]').prop('checked', true);
  509. }
  510. if(!globalCalDAVInitLoad)
  511. collectionChBoxClick(newElement.find('input[type=checkbox]').get(0), '#ResourceCalDAV'+todoString+'List', '.resourceCalDAV'+todoString+'_header', '.resourceCalDAV'+todoString+'_item', null, false);
  512. };
  513. this.removeOldResources=function(inputUidBase, inputTimestamp)
  514. {
  515. var tmp=inputUidBase.match(vCalendar.pre['hrefRex']);
  516. var inputHref=tmp[2];
  517. for(var i=this.collections.length-1;i>=0;i--)
  518. {
  519. if(this.collections[i]!=undefined && !this.collections[i].subscription && this.collections[i].timestamp!=undefined && this.collections[i].uid.indexOf(inputUidBase)==0 && this.collections[i].timestamp<inputTimestamp)
  520. {
  521. var uidRemoved=this.collections[i].uid;
  522. //if(globalEventList.displayEventsArray[uidRemoved].length>0)
  523. //{
  524. var beforeScroll = $('#main').width()-$('#calendar').width();
  525. $('#calendar').fullCalendar('removeEventSource', this.collections[i].fcSource);
  526. var afterScroll = $('#main').width()-$('#calendar').width();
  527. rerenderCalendar(beforeScroll!=afterScroll);
  528. //}
  529. var item=$('#ResourceCalDAVList').find('.resourceCalDAV_item[data-id^="'+jqueryEscapeSelector(this.collections[i].uid)+'"]');
  530. var item_header=item.prevUntil('.resourceCalDAV_header').last().prev();
  531. if(!item_header.length)
  532. item_header=item.prev();
  533. item.remove();
  534. this.collections.splice(i, 1);
  535. // if next item is undefined or it is a header and the previous item is header delete it
  536. if((this.collections[i]==undefined || this.collections[i].headerOnly==true) && this.collections[i-1].headerOnly==true)
  537. {
  538. item_header.remove();
  539. this.collections.splice(--i, 1);
  540. }
  541. else
  542. {
  543. var firstVisibleCollection=null;
  544. for(var vi=i-1;vi>0;vi--)
  545. {
  546. if(this.collections[vi].headerOnly==true)
  547. break;
  548. if(this.collections[vi].makeLoaded)
  549. {
  550. firstVisibleCollection=this.collections[vi];
  551. break;
  552. }
  553. }
  554. if(firstVisibleCollection==null)
  555. {
  556. for(var vi=i;vi<this.collections.length;vi++)
  557. {
  558. if(this.collections[vi].headerOnly==true)
  559. break;
  560. if(this.collections[vi].makeLoaded)
  561. {
  562. firstVisibleCollection=this.collections[vi];
  563. break;
  564. }
  565. }
  566. }
  567. if(firstVisibleCollection==null)
  568. item_header.css('display','none');
  569. else
  570. {
  571. var triggerInput=$('#ResourceCalDAVList').find('.resourceCalDAV_item[data-id^="'+jqueryEscapeSelector(firstVisibleCollection.uid)+'"]').find('input[type=checkbox]');
  572. collectionChBoxClick(triggerInput.get(0), '#ResourceCalDAVList', '.resourceCalDAV_header', '.resourceCalDAV_item', null, false);
  573. }
  574. }
  575. }
  576. }
  577. for(var i=this.TodoCollections.length-1;i>=0;i--)
  578. {
  579. if(this.TodoCollections[i]!=undefined && !this.TodoCollections[i].subscription && this.TodoCollections[i].timestamp!=undefined && this.TodoCollections[i].uid.indexOf(inputUidBase)==0 && this.TodoCollections[i].timestamp<inputTimestamp)
  580. {
  581. var uidRemoved=this.TodoCollections[i].uid;
  582. //if(globalEventList.displayEventsArray[uidRemoved].length>0)
  583. //{
  584. var beforeScroll = $('#mainTODO').width()-$('#todoList').width();
  585. $('#todoList').fullCalendar('removeEventSource', this.TodoCollections[i].fcSource);
  586. var afterScroll = $('#mainTODO').width()-$('#todoList').width();
  587. rerenderTodo(beforeScroll!=afterScroll);
  588. //}
  589. var item=$('#ResourceCalDAVTODOList').find('.resourceCalDAVTODO_item[data-id^="'+jqueryEscapeSelector(this.TodoCollections[i].uid)+'"]');
  590. var item_header=item.prevUntil('.resourceCalDAVTODO_header').last().prev();
  591. if(!item_header.length)
  592. item_header=item.prev();
  593. item.remove();
  594. this.TodoCollections.splice(i, 1);
  595. // if next item is undefined or it is a header and the previous item is header delete it
  596. if((this.TodoCollections[i]==undefined || this.TodoCollections[i].headerOnly==true) && this.TodoCollections[i-1].headerOnly==true)
  597. {
  598. item_header.remove();
  599. this.TodoCollections.splice(--i, 1);
  600. }
  601. else
  602. {
  603. var firstVisibleCollection=null;
  604. for(var vi=i-1;vi>0;vi--)
  605. {
  606. if(this.TodoCollections[vi].headerOnly==true)
  607. break;
  608. if(this.TodoCollections[vi].makeLoaded)
  609. {
  610. firstVisibleCollection=this.TodoCollections[vi];
  611. break;
  612. }
  613. }
  614. if(firstVisibleCollection==null)
  615. {
  616. for(var vi=i;vi<this.TodoCollections.length;vi++)
  617. {
  618. if(this.TodoCollections[vi].headerOnly==true)
  619. break;
  620. if(this.TodoCollections[vi].makeLoaded)
  621. {
  622. firstVisibleCollection=this.TodoCollections[vi];
  623. break;
  624. }
  625. }
  626. }
  627. if(firstVisibleCollection==null)
  628. item_header.css('display','none');
  629. else
  630. {
  631. var triggerInput=$('#ResourceCalDAVTODOList').find('.resourceCalDAVTODO_item[data-id^="'+jqueryEscapeSelector(firstVisibleCollection.uid)+'"]').find('input[type=checkbox]');
  632. collectionChBoxClick(triggerInput.get(0), '#ResourceCalDAVTODOList', '.resourceCalDAVTODO_header', '.resourceCalDAVTODO_item', null, false);
  633. }
  634. }
  635. }
  636. }
  637. };
  638. this.removeResource=function(inputUid, loadNext,isEvent)
  639. {
  640. if(isEvent)
  641. {
  642. for(var i=this.collections.length-1;i>=0;i--)
  643. if(this.collections[i].uid==inputUid)
  644. {
  645. var uidRemoved=this.collections[i].uid;
  646. var item=$('#ResourceCalDAVList').find('[data-id^="'+jqueryEscapeSelector(this.collections[i].uid)+'"]');
  647. var item_prev=item.prev();
  648. item.remove();
  649. this.collections.splice(i, 1);
  650. // if next item is undefined or it is a header and the previous item is header delete it
  651. if((this.collections[i]==undefined || this.collections[i].headerOnly==true) && i>0 && this.collections[i-1].headerOnly==true)
  652. {
  653. item_prev.remove();
  654. this.collections.splice(i, 1);
  655. }
  656. }
  657. }
  658. else
  659. for(var i=this.TodoCollections.length-1;i>=0;i--)
  660. if(this.TodoCollections[i].uid==inputUid)
  661. {
  662. var uidRemoved=this.TodoCollections[i].uid;
  663. var item=$('#ResourceCalDAVTODOList').find('[data-id^="'+jqueryEscapeSelector(this.TodoCollections[i].uid)+'"]');
  664. var item_prev=item.prev();
  665. item.remove();
  666. this.TodoCollections.splice(i, 1);
  667. // if next item is undefined or it is a header and the previous item is header delete it
  668. if((this.TodoCollections[i]==undefined || this.TodoCollections[i].headerOnly==true) && i>0 && this.TodoCollections[i-1].headerOnly==true)
  669. {
  670. item_prev.remove();
  671. this.TodoCollections.splice(i, 1);
  672. }
  673. }
  674. };
  675. this.getCollectionByUID=function(inputUID)
  676. {
  677. for(var i=0;i<this.collections.length;i++)
  678. {
  679. if(this.collections[i].uid==inputUID)
  680. return this.collections[i];
  681. }
  682. for(var i=0;i<this.TodoCollections.length;i++)
  683. {
  684. if(this.TodoCollections[i].uid==inputUID)
  685. return this.TodoCollections[i];
  686. }
  687. return null;
  688. };
  689. this.getEventCollectionByUID=function(inputUID)
  690. {
  691. for(var i=0;i<this.collections.length;i++)
  692. {
  693. if(this.collections[i].uid==inputUID)
  694. return this.collections[i];
  695. }
  696. return null;
  697. };
  698. this.getTodoCollectionByUID=function(inputUID)
  699. {
  700. for(var i=0;i<this.TodoCollections.length;i++)
  701. {
  702. if(this.TodoCollections[i].uid==inputUID)
  703. return this.TodoCollections[i];
  704. }
  705. return null;
  706. };
  707. this.getTodoCollectionAndIndexByUID=function(inputUID)
  708. {
  709. for(var i=0;i<this.TodoCollections.length;i++)
  710. {
  711. if(this.TodoCollections[i].uid==inputUID)
  712. return {coll:this.TodoCollections[i],index:i};
  713. }
  714. return null;
  715. };
  716. this.getResources=function()
  717. {
  718. return this.collections;
  719. };
  720. this.getSyncResourceArray=function()
  721. {
  722. return this.syncResourceArray;
  723. };
  724. }