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