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