]> git.mxchange.org Git - friendica.git/blob - js/main.js
notifications order, unseen css class
[friendica.git] / js / main.js
1   function resizeIframe(obj) {
2     obj.style.height = 0;
3     obj.style.height = obj.contentWindow.document.body.scrollHeight + 'px';
4   }
5
6   function openClose(theID) {
7     if(document.getElementById(theID).style.display == "block") { 
8       document.getElementById(theID).style.display = "none" 
9     }
10     else { 
11       document.getElementById(theID).style.display = "block" 
12     } 
13   }
14
15   function openMenu(theID) {
16       document.getElementById(theID).style.display = "block" 
17   }
18
19   function closeMenu(theID) {
20       document.getElementById(theID).style.display = "none" 
21   }
22
23
24
25         var src = null;
26         var prev = null;
27         var livetime = null;
28         var force_update = false;
29         var stopped = false;
30         var totStopped = false;
31         var timer = null;
32         var pr = 0;
33         var liking = 0;
34         var in_progress = false;
35         var langSelect = false;
36         var commentBusy = false;
37         var last_popup_menu = null;
38         var last_popup_button = null;
39
40         $(function() {
41                 $.ajaxSetup({cache: false});
42
43                 /* setup tooltips *//*
44                 $("a,.tt").each(function(){
45                         var e = $(this);
46                         var pos="bottom";
47                         if (e.hasClass("tttop")) pos="top";
48                         if (e.hasClass("ttbottom")) pos="bottom";
49                         if (e.hasClass("ttleft")) pos="left";
50                         if (e.hasClass("ttright")) pos="right";
51                         e.tipTip({defaultPosition: pos, edgeOffset: 8});
52                 });*/
53                 
54                 
55                 
56                 /* setup onoff widgets */
57                 $(".onoff input").each(function(){
58                         val = $(this).val();
59                         id = $(this).attr("id");
60                         $("#"+id+"_onoff ."+ (val==0?"on":"off")).addClass("hidden");
61                         
62                 });
63                 $(".onoff > a").click(function(event){
64                         event.preventDefault(); 
65                         var input = $(this).siblings("input");
66                         var val = 1-input.val();
67                         var id = input.attr("id");
68                         $("#"+id+"_onoff ."+ (val==0?"on":"off")).addClass("hidden");
69                         $("#"+id+"_onoff ."+ (val==1?"on":"off")).removeClass("hidden");
70                         input.val(val);
71                         //console.log(id);
72                 });
73                 
74                 /* setup field_richtext */
75                 setupFieldRichtext();
76
77                 /* popup menus */
78                 function close_last_popup_menu() {
79                         if(last_popup_menu) {
80                                 last_popup_menu.hide();
81                                 last_popup_button.removeClass("selected");
82                                 last_popup_menu = null;
83                                 last_popup_button = null;
84                         }
85                 }
86                 $('a[rel^=#]').click(function(e){
87                         e.preventDefault();
88                         var parent = $(this).parent();
89                         var isSelected = (last_popup_button && parent.attr('id') == last_popup_button.attr('id'));
90                         close_last_popup_menu();
91                         if(isSelected) return false;
92                         menu = $( $(this).attr('rel') );
93                         e.preventDefault();
94                         e.stopPropagation();
95                         if (menu.attr('popup')=="false") return false;
96                         parent.toggleClass("selected");
97                         menu.toggle();
98                         if (menu.css("display") == "none") {
99                                 last_popup_menu = null;
100                                 last_popup_button = null;
101                         } else {
102                                 last_popup_menu = menu;
103                                 last_popup_button = parent;
104                         }
105                         return false;
106                 });
107                 $('html').click(function() {
108                         close_last_popup_menu();
109                 });
110                 
111                 // fancyboxes
112                 $("a.popupbox").colorbox({
113                         'inline' : true,
114                         'transition' : 'elastic'
115                 });
116                 
117
118                 /* notifications template */
119                 var notifications_tpl= unescape($("#nav-notifications-template[rel=template]").html());
120                 var notifications_all = unescape($('<div>').append( $("#nav-notifications-see-all").clone() ).html()); //outerHtml hack
121                 var notifications_mark = unescape($('<div>').append( $("#nav-notifications-mark-all").clone() ).html()); //outerHtml hack
122                 var notifications_empty = unescape($("#nav-notifications-menu").html());
123                 
124                 /* nav update event  */
125                 $('nav').bind('nav-update', function(e,data){;
126                         var invalid = $(data).find('invalid').text();
127                         if(invalid == 1) { window.location.href=window.location.href }
128
129                         var net = $(data).find('net').text();
130                         if(net == 0) { net = ''; $('#net-update').removeClass('show') } else { $('#net-update').addClass('show') }
131                         $('#net-update').html(net);
132
133                         var home = $(data).find('home').text();
134                         if(home == 0) { home = '';  $('#home-update').removeClass('show') } else { $('#home-update').addClass('show') }
135                         $('#home-update').html(home);
136                         
137                         var intro = $(data).find('intro').text();
138                         if(intro == 0) { intro = '';  $('#intro-update').removeClass('show') } else { $('#intro-update').addClass('show') }
139                         $('#intro-update').html(intro);
140
141                         var mail = $(data).find('mail').text();
142                         if(mail == 0) { mail = '';  $('#mail-update').removeClass('show') } else { $('#mail-update').addClass('show') }
143                         $('#mail-update').html(mail);
144                         
145                         var intro = $(data).find('intro').text();
146                         if(intro == 0) { intro = '';  $('#intro-update-li').removeClass('show') } else { $('#intro-update-li').addClass('show') }
147                         $('#intro-update-li').html(intro);
148
149                         var mail = $(data).find('mail').text();
150                         if(mail == 0) { mail = '';  $('#mail-update-li').removeClass('show') } else { $('#mail-update-li').addClass('show') }
151                         $('#mail-update-li').html(mail);
152
153
154                         var allevents = $(data).find('all-events').text();
155                         if(allevents == 0) { allevents = ''; $('#allevents-update').removeClass('show') } else { $('#allevents-update').addClass('show') }
156                         $('#allevents-update').html(allevents);
157
158                         var alleventstoday = $(data).find('all-events-today').text();
159                         if(alleventstoday == 0) { $('#allevents-update').removeClass('notif-allevents-today') } else { $('#allevents-update').addClass('notif-allevents-today') }
160
161                         var events = $(data).find('events').text();
162                         if(events == 0) { events = ''; $('#events-update').removeClass('show') } else { $('#events-update').addClass('show') }
163                         $('#events-update').html(events);
164
165                         var eventstoday = $(data).find('events-today').text();
166                         if(eventstoday == 0) { $('#events-update').removeClass('notif-events-today') } else { $('#events-update').addClass('notif-events-today') }
167
168                         var birthdays = $(data).find('birthdays').text();
169                         if(birthdays == 0) {birthdays = ''; $('#birthdays-update').removeClass('show') } else { $('#birthdays-update').addClass('show') }
170                         $('#birthdays-update').html(birthdays);
171
172                         var birthdaystoday = $(data).find('birthdays-today').text();
173                         if(birthdaystoday == 0) { $('#birthdays-update').removeClass('notif-birthdays-today') } else { $('#birthdays-update').addClass('notif-birthdays-today') }
174
175
176                         var eNotif = $(data).find('notif')
177                         
178                         if (eNotif.children("note").length==0){
179                                 $("#nav-notifications-menu").html(notifications_empty);
180                         } else {
181                                 nnm = $("#nav-notifications-menu");
182                                 nnm.html(notifications_all + notifications_mark);
183                                 //nnm.attr('popup','true');
184
185                                 var notification_lastitem = parseInt(localStorage.getItem("notification-lastitem"));
186                                 var notification_id = 0;
187                                 eNotif.children("note").each(function(){
188                                         e = $(this);
189                                         text = e.text().format("<span class='contactname'>"+e.attr('name')+"</span>");
190                                         html = notifications_tpl.format(e.attr('href'),e.attr('photo'), text, e.attr('date'), e.attr('seen'));
191                                         nnm.append(html);
192                                 });
193                                 $(eNotif.children("note").get().reverse()).each(function(){
194                                         e = $(this);
195                                         notification_id = parseInt(e.attr('href').match(/\d+$/)[0]);
196                                         if (notification_lastitem!== null && notification_id > notification_lastitem) {
197                                                 if (getNotificationPermission()==="granted") {
198                                                         var notification = new Notification(document.title, {
199                                                                                           body: e.text().replace('&rarr; ','').format(e.attr('name')),
200                                                                                           icon: e.attr('photo'),
201                                                                                          });
202                                                         notification['url'] = e.attr('href');
203                                                         notification.addEventListener("click", function(ev){
204                                                                 window.location = ev.target.url;
205                                                         });
206                                                 }
207                                         }
208                                         
209                                 });
210                                 notification_lastitem = notification_id;
211                                 localStorage.setItem("notification-lastitem", notification_lastitem)
212
213                                 $("img[data-src]", nnm).each(function(i, el){
214                                         // Add src attribute for images with a data-src attribute
215                                         // However, don't bother if the data-src attribute is empty, because
216                                         // an empty "src" tag for an image will cause some browsers
217                                         // to prefetch the root page of the Friendica hub, which will
218                                         // unnecessarily load an entire profile/ or network/ page
219                                         if($(el).data("src") != '') $(el).attr('src', $(el).data("src"));
220                                 });
221                         }
222
223                         notif = eNotif.attr('count');
224                         if (notif>0){
225                                 $("#nav-notifications-linkmenu").addClass("on");
226                         } else {
227                                 $("#nav-notifications-linkmenu").removeClass("on");
228                         }
229                         if(notif == 0) { notif = ''; $('#notify-update').removeClass('show') } else { $('#notify-update').addClass('show') }
230                         $('#notify-update').html(notif);
231                         
232                         var eSysmsg = $(data).find('sysmsgs');
233                         eSysmsg.children("notice").each(function(){
234                                 text = $(this).text();
235                                 $.jGrowl(text, { sticky: true, theme: 'notice' });
236                         });
237                         eSysmsg.children("info").each(function(){
238                                 text = $(this).text();
239                                 $.jGrowl(text, { sticky: false, theme: 'info', life: 5000 });
240                         });
241                         
242                 });
243
244                 NavUpdate(); 
245                 // Allow folks to stop the ajax page updates with the pause/break key
246                 $(document).keydown(function(event) {
247                         if(event.keyCode == '8') {
248                                 var target = event.target || event.srcElement;
249                                 if (!/input|textarea/i.test(target.nodeName)) {
250                                         return false;
251                                 }
252                         }
253                         if(event.keyCode == '19' || (event.ctrlKey && event.which == '32')) {
254                                 event.preventDefault();
255                                 if(stopped == false) {
256                                         stopped = true;
257                                         if (event.ctrlKey) {
258                                                 totStopped = true;
259                                         }
260                                         $('#pause').html('<img src="images/pause.gif" alt="pause" style="border: 1px solid black;" />');
261                                 } else {
262                                         unpause();
263                                 }
264                         } else {
265                                 if (!totStopped) {
266                                         unpause();
267                                 }
268                         }
269                 });
270                 
271                 
272         });
273
274         function NavUpdate() {
275
276                 if(! stopped) {
277                         var pingCmd = 'ping' + ((localUser != 0) ? '?f=&uid=' + localUser : '');
278                         $.get(pingCmd,function(data) {
279                                 $(data).find('result').each(function() {
280                                         // send nav-update event
281                                         $('nav').trigger('nav-update', this);
282                                         
283                                         
284                                         // start live update
285
286                                         if($('#live-network').length)   { src = 'network'; liveUpdate(); }
287                                         if($('#live-profile').length)   { src = 'profile'; liveUpdate(); }
288                                         if($('#live-community').length) { src = 'community'; liveUpdate(); }
289                                         if($('#live-notes').length)     { src = 'notes'; liveUpdate(); }
290                                         if($('#live-display').length)     { src = 'display'; liveUpdate(); }
291 /*                                      if($('#live-display').length) {
292                                                 if(liking) {
293                                                         liking = 0;
294                                                         window.location.href=window.location.href 
295                                                 }
296                                         }*/
297                                         if($('#live-photos').length) { 
298                                                 if(liking) {
299                                                         liking = 0;
300                                                         window.location.href=window.location.href 
301                                                 }
302                                         }
303
304                                         
305                                         
306                                         
307                                 });
308                         }) ;
309                 }
310                 timer = setTimeout(NavUpdate,updateInterval);
311         }
312
313         function liveUpdate() {
314                 if((src == null) || (stopped) || (! profile_uid)) { $('.like-rotator').hide(); return; }
315                 if(($('.comment-edit-text-full').length) || (in_progress)) {
316                         if(livetime) {
317                                 clearTimeout(livetime);
318                         }
319                         livetime = setTimeout(liveUpdate, 5000);
320                         return;
321                 }
322                 if(livetime != null)
323                         livetime = null;
324
325                 prev = 'live-' + src;
326
327                 in_progress = true;
328
329                 if ($(document).scrollTop() == 0)
330                         force_update = true;
331
332                 var udargs = ((netargs.length) ? '/' + netargs : '');
333                 var update_url = 'update_' + src + udargs + '&p=' + profile_uid + '&page=' + profile_page + '&force=' + ((force_update) ? 1 : 0);
334
335                 $.get(update_url,function(data) {
336                         in_progress = false;
337                         force_update = false;
338                         //                      $('.collapsed-comments',data).each(function() {
339                         //      var ident = $(this).attr('id');
340                         //      var is_hidden = $('#' + ident).is(':hidden');
341                         //      if($('#' + ident).length) {
342                         //              $('#' + ident).replaceWith($(this));
343                         //              if(is_hidden)
344                         //                      $('#' + ident).hide();
345                         //      }
346                         //});
347
348                         // add a new thread
349                         $('.toplevel_item',data).each(function() {
350                                 var ident = $(this).attr('id');
351
352                                 if($('#' + ident).length == 0 && profile_page == 1) {
353                                         $('img',this).each(function() {
354                                                 $(this).attr('src',$(this).attr('dst'));
355                                         });
356                                         $('#' + prev).after($(this));
357                                 }
358                                 else {
359                                         // Find out if the hidden comments are open, so we can keep it that way
360                                         // if a new comment has been posted
361                                         var id = $('.hide-comments-total', this).attr('id');
362                                         if(typeof id != 'undefined') {
363                                                 id = id.split('-')[3];
364                                                 var commentsOpen = $("#collapsed-comments-" + id).is(":visible");
365                                         }
366
367                                         $('img',this).each(function() {
368                                                 $(this).attr('src',$(this).attr('dst'));
369                                         });
370                                         //vScroll = $(document).scrollTop();
371                                         $('html').height($('html').height());
372                                         $('#' + ident).replaceWith($(this));
373
374                                         if(typeof id != 'undefined') {
375                                                 if(commentsOpen) showHideComments(id);
376                                         }
377                                         $('html').height('auto');
378                                         //$(document).scrollTop(vScroll);
379                                 }
380                                 prev = ident;
381                         });
382
383                         // reset vars for inserting individual items
384
385                         /*                      prev = 'live-' + src;
386
387                         $('.wall-item-outside-wrapper',data).each(function() {
388                                 var ident = $(this).attr('id');
389
390                                 if($('#' + ident).length == 0 && prev != 'live-' + src) {
391                                                 $('img',this).each(function() {
392                                                         $(this).attr('src',$(this).attr('dst'));
393                                                 });
394                                                 $('#' + prev).after($(this));
395                                 }
396                                 else { 
397                                         $('#' + ident + ' ' + '.wall-item-ago').replaceWith($(this).find('.wall-item-ago')); 
398                                         if($('#' + ident + ' ' + '.comment-edit-text-empty').length)
399                                                 $('#' + ident + ' ' + '.wall-item-comment-wrapper').replaceWith($(this).find('.wall-item-comment-wrapper'));
400                                         $('#' + ident + ' ' + '.hide-comments-total').replaceWith($(this).find('.hide-comments-total'));
401                                         $('#' + ident + ' ' + '.wall-item-like').replaceWith($(this).find('.wall-item-like'));
402                                         $('#' + ident + ' ' + '.wall-item-dislike').replaceWith($(this).find('.wall-item-dislike'));
403                                         $('#' + ident + ' ' + '.my-comment-photo').each(function() {
404                                                 $(this).attr('src',$(this).attr('dst'));
405                                         });
406                                 }
407                                 prev = ident; 
408                         });
409                         */
410                         $('.like-rotator').hide();
411                         if(commentBusy) {
412                                 commentBusy = false;
413                                 $('body').css('cursor', 'auto');
414                         }
415                         /* autocomplete @nicknames */
416                         $(".comment-edit-form  textarea").contact_autocomplete(baseurl+"/acl");
417
418                         // setup videos, since VideoJS won't take care of any loaded via AJAX
419                         if(typeof videojs != 'undefined') videojs.autoSetup();
420                 });
421         }
422
423         function imgbright(node) {
424                 $(node).removeClass("drophide").addClass("drop");
425         }
426
427         function imgdull(node) {
428                 $(node).removeClass("drop").addClass("drophide");
429         }
430
431         // Since our ajax calls are asynchronous, we will give a few 
432         // seconds for the first ajax call (setting like/dislike), then 
433         // run the updater to pick up any changes and display on the page.
434         // The updater will turn any rotators off when it's done. 
435         // This function will have returned long before any of these
436         // events have completed and therefore there won't be any
437         // visible feedback that anything changed without all this
438         // trickery. This still could cause confusion if the "like" ajax call
439         // is delayed and NavUpdate runs before it completes.
440
441         function dolike(ident,verb) {
442                 unpause();
443                 $('#like-rotator-' + ident.toString()).show();
444                 $.get('like/' + ident.toString() + '?verb=' + verb, NavUpdate );
445                 liking = 1;
446                 force_update = true;
447         }
448
449         function dosubthread(ident) {
450                 unpause();
451                 $('#like-rotator-' + ident.toString()).show();
452                 $.get('subthread/' + ident.toString(), NavUpdate );
453                 liking = 1;
454         }
455
456
457         function dostar(ident) {
458                 ident = ident.toString();
459                 $('#like-rotator-' + ident).show();
460                 $.get('starred/' + ident, function(data) {
461                         if(data.match(/1/)) {
462                                 $('#starred-' + ident).addClass('starred');
463                                 $('#starred-' + ident).removeClass('unstarred');
464                                 $('#star-' + ident).addClass('hidden');
465                                 $('#unstar-' + ident).removeClass('hidden');
466                         }
467                         else {
468                                 $('#starred-' + ident).addClass('unstarred');
469                                 $('#starred-' + ident).removeClass('starred');
470                                 $('#star-' + ident).removeClass('hidden');
471                                 $('#unstar-' + ident).addClass('hidden');
472                         }
473                         $('#like-rotator-' + ident).hide();
474                 });
475         }
476
477         function doignore(ident) {
478                 ident = ident.toString();
479                 $('#like-rotator-' + ident).show();
480                 $.get('ignored/' + ident, function(data) {
481                         if(data.match(/1/)) {
482                                 $('#ignored-' + ident).addClass('ignored');
483                                 $('#ignored-' + ident).removeClass('unignored');
484                                 $('#ignore-' + ident).addClass('hidden');
485                                 $('#unignore-' + ident).removeClass('hidden');
486                         }
487                         else {
488                                 $('#ignored-' + ident).addClass('unignored');
489                                 $('#ignored-' + ident).removeClass('ignored');
490                                 $('#ignore-' + ident).removeClass('hidden');
491                                 $('#unignore-' + ident).addClass('hidden');
492                         }
493                         $('#like-rotator-' + ident).hide();
494                 });
495         }
496
497         function getPosition(e) {
498                 var cursor = {x:0, y:0};
499                 if ( e.pageX || e.pageY  ) {
500                         cursor.x = e.pageX;
501                         cursor.y = e.pageY;
502                 }
503                 else {
504                         if( e.clientX || e.clientY ) {
505                                 cursor.x = e.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft) - document.documentElement.clientLeft;
506                                 cursor.y = e.clientY + (document.documentElement.scrollTop  || document.body.scrollTop)  - document.documentElement.clientTop;
507                         }
508                         else {
509                                 if( e.x || e.y ) {
510                                         cursor.x = e.x;
511                                         cursor.y = e.y;
512                                 }
513                         }
514                 }
515                 return cursor;
516         }
517
518         var lockvisible = false;
519
520         function lockview(event,id) {
521                 event = event || window.event;
522                 cursor = getPosition(event);
523                 if(lockvisible) {
524                         lockviewhide();
525                 }
526                 else {
527                         lockvisible = true;
528                         $.get('lockview/' + id, function(data) {
529                                 $('#panel').html(data);
530                                 $('#panel').css({ 'left': cursor.x + 5 , 'top': cursor.y + 5});
531                                 $('#panel').show();
532                         });
533                 }
534         }
535
536         function lockviewhide() {
537                 lockvisible = false;
538                 $('#panel').hide();
539         }
540
541         function post_comment(id) {
542                 unpause();
543                 commentBusy = true;
544                 $('body').css('cursor', 'wait');
545                 $("#comment-preview-inp-" + id).val("0");
546                 $.post(  
547              "item",  
548              $("#comment-edit-form-" + id).serialize(),
549                         function(data) {
550                                 if(data.success) {
551                                         $("#comment-edit-wrapper-" + id).hide();
552                                         $("#comment-edit-text-" + id).val('');
553                                 var tarea = document.getElementById("comment-edit-text-" + id);
554                                         if(tarea)
555                                                 commentClose(tarea,id);
556                                         if(timer) clearTimeout(timer);
557                                         timer = setTimeout(NavUpdate,10);
558                                         force_update = true;
559                                 }
560                                 if(data.reload) {
561                                         window.location.href=data.reload;
562                                 }
563                         },
564                         "json"  
565          );  
566          return false;  
567         }
568
569
570         function preview_comment(id) {
571                 $("#comment-preview-inp-" + id).val("1");
572                 $("#comment-edit-preview-" + id).show();
573                 $.post(  
574              "item",  
575              $("#comment-edit-form-" + id).serialize(),
576                         function(data) {
577                                 if(data.preview) {
578                                                 
579                                         $("#comment-edit-preview-" + id).html(data.preview);
580                                         $("#comment-edit-preview-" + id + " a").click(function() { return false; });
581                                 }
582                         },
583                         "json"  
584          );  
585          return true;  
586         }
587
588
589
590         function showHideComments(id) {
591                 if( $("#collapsed-comments-" + id).is(":visible")) {
592                         $("#collapsed-comments-" + id).hide();
593                         $("#hide-comments-" + id).html(window.showMore);
594                 }
595                 else {
596                         $("#collapsed-comments-" + id).show();
597                         $("#hide-comments-" + id).html(window.showFewer);
598                 }
599         }
600
601
602
603         function preview_post() {
604                 $("#jot-preview").val("1");
605                 $("#jot-preview-content").show();
606                 tinyMCE.triggerSave();
607                 $.post(  
608                         "item",  
609                         $("#profile-jot-form").serialize(),
610                         function(data) {
611                                 if(data.preview) {                      
612                                         $("#jot-preview-content").html(data.preview);
613                                         $("#jot-preview-content" + " a").click(function() { return false; });
614                                 }
615                         },
616                         "json"  
617                 );  
618                 $("#jot-preview").val("0");
619                 return true;  
620         }
621
622
623         function unpause() {
624                 // unpause auto reloads if they are currently stopped
625                 totStopped = false;
626                 stopped = false;
627             $('#pause').html('');
628         }
629                 
630
631     function bin2hex(s){  
632         // Converts the binary representation of data to hex    
633         //   
634         // version: 812.316  
635         // discuss at: http://phpjs.org/functions/bin2hex  
636         // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)  
637         // +   bugfixed by: Onno Marsman  
638         // +   bugfixed by: Linuxworld  
639         // *     example 1: bin2hex('Kev');  
640         // *     returns 1: '4b6576'  
641         // *     example 2: bin2hex(String.fromCharCode(0x00));  
642         // *     returns 2: '00'  
643         var v,i, f = 0, a = [];  
644         s += '';  
645         f = s.length;  
646           
647         for (i = 0; i<f; i++) {  
648             a[i] = s.charCodeAt(i).toString(16).replace(/^([\da-f])$/,"0$1");  
649         }  
650           
651         return a.join('');  
652     }  
653
654         function groupChangeMember(gid, cid, sec_token) {
655                 $('body .fakelink').css('cursor', 'wait');
656                 $.get('group/' + gid + '/' + cid + "?t=" + sec_token, function(data) {
657                                 $('#group-update-wrapper').html(data);
658                                 $('body .fakelink').css('cursor', 'auto');                              
659                 });
660         }
661
662         function profChangeMember(gid,cid) {
663                 $('body .fakelink').css('cursor', 'wait');
664                 $.get('profperm/' + gid + '/' + cid, function(data) {
665                                 $('#prof-update-wrapper').html(data);
666                                 $('body .fakelink').css('cursor', 'auto');                              
667                 });
668         }
669
670         function contactgroupChangeMember(gid,cid) {
671                 $('body').css('cursor', 'wait');
672                 $.get('contactgroup/' + gid + '/' + cid, function(data) {
673                                 $('body').css('cursor', 'auto');
674                 });
675         }
676
677
678 function checkboxhighlight(box) {
679   if($(box).is(':checked')) {
680         $(box).addClass('checkeditem');
681   }
682   else {
683         $(box).removeClass('checkeditem');
684   }
685 }
686
687 function notifyMarkAll() {
688         $.get('notify/mark/all', function(data) {
689                 if(timer) clearTimeout(timer);
690                 timer = setTimeout(NavUpdate,1000);
691                 force_update = true;
692         });
693 }
694
695
696 // code from http://www.tinymce.com/wiki.php/How-to_implement_a_custom_file_browser
697 function fcFileBrowser (field_name, url, type, win) {
698     /* TODO: If you work with sessions in PHP and your client doesn't accept cookies you might need to carry
699        the session name and session ID in the request string (can look like this: "?PHPSESSID=88p0n70s9dsknra96qhuk6etm5").
700        These lines of code extract the necessary parameters and add them back to the filebrowser URL again. */
701
702
703     var cmsURL = baseurl+"/fbrowser/"+type+"/";
704
705     tinyMCE.activeEditor.windowManager.open({
706         file : cmsURL,
707         title : 'File Browser',
708         width : 420,  // Your dimensions may differ - toy around with them!
709         height : 400,
710         resizable : "yes",
711         inline : "yes",  // This parameter only has an effect if you use the inlinepopups plugin!
712         close_previous : "no"
713     }, {
714         window : win,
715         input : field_name
716     });
717     return false;
718   }
719
720 function setupFieldRichtext(){
721         tinyMCE.init({
722                 theme : "advanced",
723                 mode : "specific_textareas",
724                 editor_selector: "fieldRichtext",
725                 plugins : "bbcode,paste, inlinepopups",
726                 theme_advanced_buttons1 : "bold,italic,underline,undo,redo,link,unlink,image,forecolor,formatselect,code",
727                 theme_advanced_buttons2 : "",
728                 theme_advanced_buttons3 : "",
729                 theme_advanced_toolbar_location : "top",
730                 theme_advanced_toolbar_align : "center",
731                 theme_advanced_blockformats : "blockquote,code",
732                 theme_advanced_resizing : true,
733                 paste_text_sticky : true,
734                 entity_encoding : "raw",
735                 add_unload_trigger : false,
736                 remove_linebreaks : false,
737                 //force_p_newlines : false,
738                 //force_br_newlines : true,
739                 forced_root_block : 'div',
740                 convert_urls: false,
741                 content_css: baseurl+"/view/custom_tinymce.css",
742                 theme_advanced_path : false,
743                 file_browser_callback : "fcFileBrowser",
744         });
745 }
746
747
748 /** 
749  * sprintf in javascript 
750  *      "{0} and {1}".format('zero','uno'); 
751  **/
752 String.prototype.format = function() {
753     var formatted = this;
754     for (var i = 0; i < arguments.length; i++) {
755         var regexp = new RegExp('\\{'+i+'\\}', 'gi');
756         formatted = formatted.replace(regexp, arguments[i]);
757     }
758     return formatted;
759 };
760 // Array Remove
761 Array.prototype.remove = function(item) {
762   to=undefined; from=this.indexOf(item);
763   var rest = this.slice((to || from) + 1 || this.length);
764   this.length = from < 0 ? this.length + from : from;
765   return this.push.apply(this, rest);
766 };
767
768 function previewTheme(elm) {
769         theme = $(elm).val();
770         $.getJSON('pretheme?f=&theme=' + theme,function(data) {
771                         $('#theme-preview').html('<div id="theme-desc">' + data.desc + '</div><div id="theme-version">' + data.version + '</div><div id="theme-credits">' + data.credits + '</div><a href="' + data.img + '"><img src="' + data.img + '" width="320" height="240" alt="' + theme + '" /></a>');
772         });
773
774 }
775
776 // notification permission settings in localstorage
777 // set by settings page
778 function getNotificationPermission() {
779         if (window["Notification"] === undefined) {
780                 return null;
781         }
782     if (Notification.permission === 'granted') {
783         var val = localStorage.getItem('notification-permissions');
784                 if (val === null) return 'denied';
785                 return val;
786     } else {
787         return Notification.permission;
788     }
789 }