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