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