2 function openClose(theID) {
3 if(document.getElementById(theID).style.display == "block") {
4 document.getElementById(theID).style.display = "none"
7 document.getElementById(theID).style.display = "block"
11 function openMenu(theID) {
12 document.getElementById(theID).style.display = "block"
15 function closeMenu(theID) {
16 document.getElementById(theID).style.display = "none"
24 var force_update = false;
27 var totStopped = false;
31 var in_progress = false;
32 var langSelect = false;
33 var commentBusy = false;
34 var last_popup_menu = null;
35 var last_popup_button = null;
38 $.ajaxSetup({cache: false});
40 msie = $.browser.msie ;
42 /* setup tooltips *//*
43 $("a,.tt").each(function(){
46 if (e.hasClass("tttop")) pos="top";
47 if (e.hasClass("ttbottom")) pos="bottom";
48 if (e.hasClass("ttleft")) pos="left";
49 if (e.hasClass("ttright")) pos="right";
50 e.tipTip({defaultPosition: pos, edgeOffset: 8});
55 /* setup onoff widgets */
56 $(".onoff input").each(function(){
58 id = $(this).attr("id");
59 $("#"+id+"_onoff ."+ (val==0?"on":"off")).addClass("hidden");
62 $(".onoff > a").click(function(event){
63 event.preventDefault();
64 var input = $(this).siblings("input");
65 var val = 1-input.val();
66 var id = input.attr("id");
67 $("#"+id+"_onoff ."+ (val==0?"on":"off")).addClass("hidden");
68 $("#"+id+"_onoff ."+ (val==1?"on":"off")).removeClass("hidden");
73 /* setup field_richtext */
77 function close_last_popup_menu() {
79 last_popup_menu.hide();
80 last_popup_button.removeClass("selected");
81 last_popup_menu = null;
82 last_popup_button = null;
85 $('a[rel^=#]').click(function(e){
86 close_last_popup_menu();
87 menu = $( $(this).attr('rel') );
90 if (menu.attr('popup')=="false") return false;
91 $(this).parent().toggleClass("selected");
93 if (menu.css("display") == "none") {
94 last_popup_menu = null;
95 last_popup_button = null;
97 last_popup_menu = menu;
98 last_popup_button = $(this).parent();
102 $('html').click(function() {
103 close_last_popup_menu();
107 /*$("a.popupbox").fancybox({
108 'transitionIn' : 'elastic',
109 'transitionOut' : 'elastic'
111 $("a.popupbox").colorbox({
113 'transition' : 'elastic'
117 /* notifications template */
118 var notifications_tpl= unescape($("#nav-notifications-template[rel=template]").html());
119 var notifications_all = unescape($('<div>').append( $("#nav-notifications-see-all").clone() ).html()); //outerHtml hack
120 var notifications_mark = unescape($('<div>').append( $("#nav-notifications-mark-all").clone() ).html()); //outerHtml hack
121 var notifications_empty = unescape($("#nav-notifications-menu").html());
123 /* nav update event */
124 $('nav').bind('nav-update', function(e,data){;
125 var invalid = $(data).find('invalid').text();
126 if(invalid == 1) { window.location.href=window.location.href }
128 var net = $(data).find('net').text();
129 if(net == 0) { net = ''; $('#net-update').removeClass('show') } else { $('#net-update').addClass('show') }
130 $('#net-update').html(net);
132 var home = $(data).find('home').text();
133 if(home == 0) { home = ''; $('#home-update').removeClass('show') } else { $('#home-update').addClass('show') }
134 $('#home-update').html(home);
136 var intro = $(data).find('intro').text();
137 if(intro == 0) { intro = ''; $('#intro-update').removeClass('show') } else { $('#intro-update').addClass('show') }
138 $('#intro-update').html(intro);
140 var mail = $(data).find('mail').text();
141 if(mail == 0) { mail = ''; $('#mail-update').removeClass('show') } else { $('#mail-update').addClass('show') }
142 $('#mail-update').html(mail);
144 var intro = $(data).find('intro').text();
145 if(intro == 0) { intro = ''; $('#intro-update-li').removeClass('show') } else { $('#intro-update-li').addClass('show') }
146 $('#intro-update-li').html(intro);
148 var mail = $(data).find('mail').text();
149 if(mail == 0) { mail = ''; $('#mail-update-li').removeClass('show') } else { $('#mail-update-li').addClass('show') }
150 $('#mail-update-li').html(mail);
153 var allevents = $(data).find('all-events').text();
154 if(allevents == 0) { allevents = ''; $('#allevents-update').removeClass('show') } else { $('#allevents-update').addClass('show') }
155 $('#allevents-update').html(allevents);
157 var alleventstoday = $(data).find('all-events-today').text();
158 if(alleventstoday == 0) { $('#allevents-update').removeClass('notif-allevents-today') } else { $('#allevents-update').addClass('notif-allevents-today') }
160 var events = $(data).find('events').text();
161 if(events == 0) { events = ''; $('#events-update').removeClass('show') } else { $('#events-update').addClass('show') }
162 $('#events-update').html(events);
164 var eventstoday = $(data).find('events-today').text();
165 if(eventstoday == 0) { $('#events-update').removeClass('notif-events-today') } else { $('#events-update').addClass('notif-events-today') }
167 var birthdays = $(data).find('birthdays').text();
168 if(birthdays == 0) {birthdays = ''; $('#birthdays-update').removeClass('show') } else { $('#birthdays-update').addClass('show') }
169 $('#birthdays-update').html(birthdays);
171 var birthdaystoday = $(data).find('birthdays-today').text();
172 if(birthdaystoday == 0) { $('#birthdays-update').removeClass('notif-birthdays-today') } else { $('#birthdays-update').addClass('notif-birthdays-today') }
175 var eNotif = $(data).find('notif')
177 if (eNotif.children("note").length==0){
178 $("#nav-notifications-menu").html(notifications_empty);
180 nnm = $("#nav-notifications-menu");
181 nnm.html(notifications_all + notifications_mark);
182 //nnm.attr('popup','true');
183 eNotif.children("note").each(function(){
185 text = e.text().format("<span class='contactname'>"+e.attr('name')+"</span>");
186 html = notifications_tpl.format(e.attr('href'),e.attr('photo'), text, e.attr('date'), e.attr('seen'));
190 $("img[data-src]", nnm).each(function(i, el){
191 // Add src attribute for images with a data-src attribute
192 // However, don't bother if the data-src attribute is empty, because
193 // an empty "src" tag for an image will cause some browsers
194 // to prefetch the root page of the Friendica hub, which will
195 // unnecessarily load an entire profile/ or network/ page
196 if($(el).data("src") != '') $(el).attr('src', $(el).data("src"));
200 notif = eNotif.attr('count');
202 $("#nav-notifications-linkmenu").addClass("on");
204 $("#nav-notifications-linkmenu").removeClass("on");
206 if(notif == 0) { notif = ''; $('#notify-update').removeClass('show') } else { $('#notify-update').addClass('show') }
207 $('#notify-update').html(notif);
209 var eSysmsg = $(data).find('sysmsgs');
210 eSysmsg.children("notice").each(function(){
211 text = $(this).text();
212 $.jGrowl(text, { sticky: true, theme: 'notice' });
214 eSysmsg.children("info").each(function(){
215 text = $(this).text();
216 $.jGrowl(text, { sticky: false, theme: 'info', life: 10000 });
222 // Allow folks to stop the ajax page updates with the pause/break key
223 $(document).keydown(function(event) {
224 if(event.keyCode == '8') {
225 var target = event.target || event.srcElement;
226 if (!/input|textarea/i.test(target.nodeName)) {
230 if(event.keyCode == '19' || (event.ctrlKey && event.which == '32')) {
231 event.preventDefault();
232 if(stopped == false) {
237 $('#pause').html('<img src="images/pause.gif" alt="pause" style="border: 1px solid black;" />');
251 function NavUpdate() {
254 var pingCmd = 'ping' + ((localUser != 0) ? '?f=&uid=' + localUser : '');
255 $.get(pingCmd,function(data) {
256 $(data).find('result').each(function() {
257 // send nav-update event
258 $('nav').trigger('nav-update', this);
263 if($('#live-network').length) { src = 'network'; liveUpdate(); }
264 if($('#live-profile').length) { src = 'profile'; liveUpdate(); }
265 if($('#live-community').length) { src = 'community'; liveUpdate(); }
266 if($('#live-notes').length) { src = 'notes'; liveUpdate(); }
267 if($('#live-display').length) { src = 'display'; liveUpdate(); }
268 /* if($('#live-display').length) {
271 window.location.href=window.location.href
274 if($('#live-photos').length) {
277 window.location.href=window.location.href
287 timer = setTimeout(NavUpdate,updateInterval);
290 function liveUpdate() {
291 if((src == null) || (stopped) || (! profile_uid)) { $('.like-rotator').hide(); return; }
292 if(($('.comment-edit-text-full').length) || (in_progress)) {
294 clearTimeout(livetime);
296 livetime = setTimeout(liveUpdate, 10000);
302 prev = 'live-' + src;
306 if ($(document).scrollTop() == 0)
309 var udargs = ((netargs.length) ? '/' + netargs : '');
310 var update_url = 'update_' + src + udargs + '&p=' + profile_uid + '&page=' + profile_page + '&msie=' + ((msie) ? 1 : 0) + '&force=' + ((force_update) ? 1 : 0);
312 $.get(update_url,function(data) {
314 force_update = false;
315 // $('.collapsed-comments',data).each(function() {
316 // var ident = $(this).attr('id');
317 // var is_hidden = $('#' + ident).is(':hidden');
318 // if($('#' + ident).length) {
319 // $('#' + ident).replaceWith($(this));
321 // $('#' + ident).hide();
326 $('.toplevel_item',data).each(function() {
327 var ident = $(this).attr('id');
329 if($('#' + ident).length == 0 && profile_page == 1) {
330 $('img',this).each(function() {
331 $(this).attr('src',$(this).attr('dst'));
333 $('#' + prev).after($(this));
336 // Find out if the hidden comments are open, so we can keep it that way
337 // if a new comment has been posted
338 var id = $('.hide-comments-total', this).attr('id');
339 if(typeof id != 'undefined') {
340 id = id.split('-')[3];
341 var commentsOpen = $("#collapsed-comments-" + id).is(":visible");
344 $('img',this).each(function() {
345 $(this).attr('src',$(this).attr('dst'));
347 //vScroll = $(document).scrollTop();
348 $('html').height($('html').height());
349 $('#' + ident).replaceWith($(this));
351 if(typeof id != 'undefined') {
352 if(commentsOpen) showHideComments(id);
354 $('html').height('auto');
355 //$(document).scrollTop(vScroll);
360 // reset vars for inserting individual items
362 /* prev = 'live-' + src;
364 $('.wall-item-outside-wrapper',data).each(function() {
365 var ident = $(this).attr('id');
367 if($('#' + ident).length == 0 && prev != 'live-' + src) {
368 $('img',this).each(function() {
369 $(this).attr('src',$(this).attr('dst'));
371 $('#' + prev).after($(this));
374 $('#' + ident + ' ' + '.wall-item-ago').replaceWith($(this).find('.wall-item-ago'));
375 if($('#' + ident + ' ' + '.comment-edit-text-empty').length)
376 $('#' + ident + ' ' + '.wall-item-comment-wrapper').replaceWith($(this).find('.wall-item-comment-wrapper'));
377 $('#' + ident + ' ' + '.hide-comments-total').replaceWith($(this).find('.hide-comments-total'));
378 $('#' + ident + ' ' + '.wall-item-like').replaceWith($(this).find('.wall-item-like'));
379 $('#' + ident + ' ' + '.wall-item-dislike').replaceWith($(this).find('.wall-item-dislike'));
380 $('#' + ident + ' ' + '.my-comment-photo').each(function() {
381 $(this).attr('src',$(this).attr('dst'));
387 $('.like-rotator').hide();
390 $('body').css('cursor', 'auto');
392 /* autocomplete @nicknames */
393 $(".comment-edit-form textarea").contact_autocomplete(baseurl+"/acl");
395 // setup videos, since VideoJS won't take care of any loaded via AJAX
396 if(typeof videojs != 'undefined') videojs.autoSetup();
400 function imgbright(node) {
401 $(node).removeClass("drophide").addClass("drop");
404 function imgdull(node) {
405 $(node).removeClass("drop").addClass("drophide");
408 // Since our ajax calls are asynchronous, we will give a few
409 // seconds for the first ajax call (setting like/dislike), then
410 // run the updater to pick up any changes and display on the page.
411 // The updater will turn any rotators off when it's done.
412 // This function will have returned long before any of these
413 // events have completed and therefore there won't be any
414 // visible feedback that anything changed without all this
415 // trickery. This still could cause confusion if the "like" ajax call
416 // is delayed and NavUpdate runs before it completes.
418 function dolike(ident,verb) {
420 $('#like-rotator-' + ident.toString()).show();
421 $.get('like/' + ident.toString() + '?verb=' + verb, NavUpdate );
426 function dosubthread(ident) {
428 $('#like-rotator-' + ident.toString()).show();
429 $.get('subthread/' + ident.toString(), NavUpdate );
434 function dostar(ident) {
435 ident = ident.toString();
436 $('#like-rotator-' + ident).show();
437 $.get('starred/' + ident, function(data) {
438 if(data.match(/1/)) {
439 $('#starred-' + ident).addClass('starred');
440 $('#starred-' + ident).removeClass('unstarred');
441 $('#star-' + ident).addClass('hidden');
442 $('#unstar-' + ident).removeClass('hidden');
445 $('#starred-' + ident).addClass('unstarred');
446 $('#starred-' + ident).removeClass('starred');
447 $('#star-' + ident).removeClass('hidden');
448 $('#unstar-' + ident).addClass('hidden');
450 $('#like-rotator-' + ident).hide();
454 function doignore(ident) {
455 ident = ident.toString();
456 $('#like-rotator-' + ident).show();
457 $.get('ignored/' + ident, function(data) {
458 if(data.match(/1/)) {
459 $('#ignored-' + ident).addClass('ignored');
460 $('#ignored-' + ident).removeClass('unignored');
461 $('#ignore-' + ident).addClass('hidden');
462 $('#unignore-' + ident).removeClass('hidden');
465 $('#ignored-' + ident).addClass('unignored');
466 $('#ignored-' + ident).removeClass('ignored');
467 $('#ignore-' + ident).removeClass('hidden');
468 $('#unignore-' + ident).addClass('hidden');
470 $('#like-rotator-' + ident).hide();
474 function getPosition(e) {
475 var cursor = {x:0, y:0};
476 if ( e.pageX || e.pageY ) {
481 if( e.clientX || e.clientY ) {
482 cursor.x = e.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft) - document.documentElement.clientLeft;
483 cursor.y = e.clientY + (document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop;
495 var lockvisible = false;
497 function lockview(event,id) {
498 event = event || window.event;
499 cursor = getPosition(event);
505 $.get('lockview/' + id, function(data) {
506 $('#panel').html(data);
507 $('#panel').css({ 'left': cursor.x + 5 , 'top': cursor.y + 5});
513 function lockviewhide() {
518 function post_comment(id) {
521 $('body').css('cursor', 'wait');
522 $("#comment-preview-inp-" + id).val("0");
525 $("#comment-edit-form-" + id).serialize(),
528 $("#comment-edit-wrapper-" + id).hide();
529 $("#comment-edit-text-" + id).val('');
530 var tarea = document.getElementById("comment-edit-text-" + id);
532 commentClose(tarea,id);
533 if(timer) clearTimeout(timer);
534 timer = setTimeout(NavUpdate,10);
538 window.location.href=data.reload;
547 function preview_comment(id) {
548 $("#comment-preview-inp-" + id).val("1");
549 $("#comment-edit-preview-" + id).show();
552 $("#comment-edit-form-" + id).serialize(),
556 $("#comment-edit-preview-" + id).html(data.preview);
557 $("#comment-edit-preview-" + id + " a").click(function() { return false; });
567 function showHideComments(id) {
568 if( $("#collapsed-comments-" + id).is(":visible")) {
569 $("#collapsed-comments-" + id).hide();
570 $("#hide-comments-" + id).html(window.showMore);
573 $("#collapsed-comments-" + id).show();
574 $("#hide-comments-" + id).html(window.showFewer);
580 function preview_post() {
581 $("#jot-preview").val("1");
582 $("#jot-preview-content").show();
583 tinyMCE.triggerSave();
586 $("#profile-jot-form").serialize(),
589 $("#jot-preview-content").html(data.preview);
590 $("#jot-preview-content" + " a").click(function() { return false; });
595 $("#jot-preview").val("0");
601 // unpause auto reloads if they are currently stopped
604 $('#pause').html('');
609 // Converts the binary representation of data to hex
612 // discuss at: http://phpjs.org/functions/bin2hex
613 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
614 // + bugfixed by: Onno Marsman
615 // + bugfixed by: Linuxworld
616 // * example 1: bin2hex('Kev');
617 // * returns 1: '4b6576'
618 // * example 2: bin2hex(String.fromCharCode(0x00));
620 var v,i, f = 0, a = [];
624 for (i = 0; i<f; i++) {
625 a[i] = s.charCodeAt(i).toString(16).replace(/^([\da-f])$/,"0$1");
631 function groupChangeMember(gid, cid, sec_token) {
632 $('body .fakelink').css('cursor', 'wait');
633 $.get('group/' + gid + '/' + cid + "?t=" + sec_token, function(data) {
634 $('#group-update-wrapper').html(data);
635 $('body .fakelink').css('cursor', 'auto');
639 function profChangeMember(gid,cid) {
640 $('body .fakelink').css('cursor', 'wait');
641 $.get('profperm/' + gid + '/' + cid, function(data) {
642 $('#prof-update-wrapper').html(data);
643 $('body .fakelink').css('cursor', 'auto');
647 function contactgroupChangeMember(gid,cid) {
648 $('body').css('cursor', 'wait');
649 $.get('contactgroup/' + gid + '/' + cid, function(data) {
650 $('body').css('cursor', 'auto');
655 function checkboxhighlight(box) {
656 if($(box).is(':checked')) {
657 $(box).addClass('checkeditem');
660 $(box).removeClass('checkeditem');
664 function notifyMarkAll() {
665 $.get('notify/mark/all', function(data) {
666 if(timer) clearTimeout(timer);
667 timer = setTimeout(NavUpdate,1000);
673 // code from http://www.tinymce.com/wiki.php/How-to_implement_a_custom_file_browser
674 function fcFileBrowser (field_name, url, type, win) {
675 /* TODO: If you work with sessions in PHP and your client doesn't accept cookies you might need to carry
676 the session name and session ID in the request string (can look like this: "?PHPSESSID=88p0n70s9dsknra96qhuk6etm5").
677 These lines of code extract the necessary parameters and add them back to the filebrowser URL again. */
680 var cmsURL = baseurl+"/fbrowser/"+type+"/";
682 tinyMCE.activeEditor.windowManager.open({
684 title : 'File Browser',
685 width : 420, // Your dimensions may differ - toy around with them!
688 inline : "yes", // This parameter only has an effect if you use the inlinepopups plugin!
689 close_previous : "no"
697 function setupFieldRichtext(){
700 mode : "specific_textareas",
701 editor_selector: "fieldRichtext",
702 plugins : "bbcode,paste, inlinepopups",
703 theme_advanced_buttons1 : "bold,italic,underline,undo,redo,link,unlink,image,forecolor,formatselect,code",
704 theme_advanced_buttons2 : "",
705 theme_advanced_buttons3 : "",
706 theme_advanced_toolbar_location : "top",
707 theme_advanced_toolbar_align : "center",
708 theme_advanced_blockformats : "blockquote,code",
709 paste_text_sticky : true,
710 entity_encoding : "raw",
711 add_unload_trigger : false,
712 remove_linebreaks : false,
713 //force_p_newlines : false,
714 //force_br_newlines : true,
715 forced_root_block : 'div',
717 content_css: baseurl+"/view/custom_tinymce.css",
718 theme_advanced_path : false,
719 file_browser_callback : "fcFileBrowser",
725 * sprintf in javascript
726 * "{0} and {1}".format('zero','uno');
728 String.prototype.format = function() {
729 var formatted = this;
730 for (var i = 0; i < arguments.length; i++) {
731 var regexp = new RegExp('\\{'+i+'\\}', 'gi');
732 formatted = formatted.replace(regexp, arguments[i]);
737 Array.prototype.remove = function(item) {
738 to=undefined; from=this.indexOf(item);
739 var rest = this.slice((to || from) + 1 || this.length);
740 this.length = from < 0 ? this.length + from : from;
741 return this.push.apply(this, rest);
744 function previewTheme(elm) {
745 theme = $(elm).val();
746 $.getJSON('pretheme?f=&theme=' + theme,function(data) {
747 $('#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>');