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