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