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