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