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