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;
26 var totStopped = false;
30 var in_progress = false;
31 var langSelect = false;
32 var commentBusy = false;
33 var last_popup_menu = null;
34 var last_popup_button = null;
37 $.ajaxSetup({cache: false});
39 /* setup tooltips *//*
40 $("a,.tt").each(function(){
43 if (e.hasClass("tttop")) pos="top";
44 if (e.hasClass("ttbottom")) pos="bottom";
45 if (e.hasClass("ttleft")) pos="left";
46 if (e.hasClass("ttright")) pos="right";
47 e.tipTip({defaultPosition: pos, edgeOffset: 8});
52 /* setup onoff widgets */
53 $(".onoff input").each(function(){
55 id = $(this).attr("id");
56 $("#"+id+"_onoff ."+ (val==0?"on":"off")).addClass("hidden");
59 $(".onoff > a").click(function(event){
60 event.preventDefault();
61 var input = $(this).siblings("input");
62 var val = 1-input.val();
63 var id = input.attr("id");
64 $("#"+id+"_onoff ."+ (val==0?"on":"off")).addClass("hidden");
65 $("#"+id+"_onoff ."+ (val==1?"on":"off")).removeClass("hidden");
70 /* setup field_richtext */
74 function close_last_popup_menu() {
76 last_popup_menu.hide();
77 last_popup_button.removeClass("selected");
78 last_popup_menu = null;
79 last_popup_button = null;
82 $('a[rel^=#]').click(function(e){
83 close_last_popup_menu();
84 menu = $( $(this).attr('rel') );
87 if (menu.attr('popup')=="false") return false;
88 $(this).parent().toggleClass("selected");
90 if (menu.css("display") == "none") {
91 last_popup_menu = null;
92 last_popup_button = null;
94 last_popup_menu = menu;
95 last_popup_button = $(this).parent();
99 $('html').click(function() {
100 close_last_popup_menu();
104 $("a.popupbox").colorbox({
106 'transition' : 'elastic'
110 /* notifications template */
111 var notifications_tpl= unescape($("#nav-notifications-template[rel=template]").html());
112 var notifications_all = unescape($('<div>').append( $("#nav-notifications-see-all").clone() ).html()); //outerHtml hack
113 var notifications_mark = unescape($('<div>').append( $("#nav-notifications-mark-all").clone() ).html()); //outerHtml hack
114 var notifications_empty = unescape($("#nav-notifications-menu").html());
116 /* nav update event */
117 $('nav').bind('nav-update', function(e,data){;
118 var invalid = $(data).find('invalid').text();
119 if(invalid == 1) { window.location.href=window.location.href }
121 var net = $(data).find('net').text();
122 if(net == 0) { net = ''; $('#net-update').removeClass('show') } else { $('#net-update').addClass('show') }
123 $('#net-update').html(net);
125 var home = $(data).find('home').text();
126 if(home == 0) { home = ''; $('#home-update').removeClass('show') } else { $('#home-update').addClass('show') }
127 $('#home-update').html(home);
129 var intro = $(data).find('intro').text();
130 if(intro == 0) { intro = ''; $('#intro-update').removeClass('show') } else { $('#intro-update').addClass('show') }
131 $('#intro-update').html(intro);
133 var mail = $(data).find('mail').text();
134 if(mail == 0) { mail = ''; $('#mail-update').removeClass('show') } else { $('#mail-update').addClass('show') }
135 $('#mail-update').html(mail);
137 var intro = $(data).find('intro').text();
138 if(intro == 0) { intro = ''; $('#intro-update-li').removeClass('show') } else { $('#intro-update-li').addClass('show') }
139 $('#intro-update-li').html(intro);
141 var mail = $(data).find('mail').text();
142 if(mail == 0) { mail = ''; $('#mail-update-li').removeClass('show') } else { $('#mail-update-li').addClass('show') }
143 $('#mail-update-li').html(mail);
146 var allevents = $(data).find('all-events').text();
147 if(allevents == 0) { allevents = ''; $('#allevents-update').removeClass('show') } else { $('#allevents-update').addClass('show') }
148 $('#allevents-update').html(allevents);
150 var alleventstoday = $(data).find('all-events-today').text();
151 if(alleventstoday == 0) { $('#allevents-update').removeClass('notif-allevents-today') } else { $('#allevents-update').addClass('notif-allevents-today') }
153 var events = $(data).find('events').text();
154 if(events == 0) { events = ''; $('#events-update').removeClass('show') } else { $('#events-update').addClass('show') }
155 $('#events-update').html(events);
157 var eventstoday = $(data).find('events-today').text();
158 if(eventstoday == 0) { $('#events-update').removeClass('notif-events-today') } else { $('#events-update').addClass('notif-events-today') }
160 var birthdays = $(data).find('birthdays').text();
161 if(birthdays == 0) {birthdays = ''; $('#birthdays-update').removeClass('show') } else { $('#birthdays-update').addClass('show') }
162 $('#birthdays-update').html(birthdays);
164 var birthdaystoday = $(data).find('birthdays-today').text();
165 if(birthdaystoday == 0) { $('#birthdays-update').removeClass('notif-birthdays-today') } else { $('#birthdays-update').addClass('notif-birthdays-today') }
168 var eNotif = $(data).find('notif')
170 if (eNotif.children("note").length==0){
171 $("#nav-notifications-menu").html(notifications_empty);
173 nnm = $("#nav-notifications-menu");
174 nnm.html(notifications_all + notifications_mark);
175 //nnm.attr('popup','true');
176 eNotif.children("note").each(function(){
178 text = e.text().format("<span class='contactname'>"+e.attr('name')+"</span>");
179 html = notifications_tpl.format(e.attr('href'),e.attr('photo'), text, e.attr('date'), e.attr('seen'));
183 $("img[data-src]", nnm).each(function(i, el){
184 // Add src attribute for images with a data-src attribute
185 // However, don't bother if the data-src attribute is empty, because
186 // an empty "src" tag for an image will cause some browsers
187 // to prefetch the root page of the Friendica hub, which will
188 // unnecessarily load an entire profile/ or network/ page
189 if($(el).data("src") != '') $(el).attr('src', $(el).data("src"));
193 notif = eNotif.attr('count');
195 $("#nav-notifications-linkmenu").addClass("on");
197 $("#nav-notifications-linkmenu").removeClass("on");
199 if(notif == 0) { notif = ''; $('#notify-update').removeClass('show') } else { $('#notify-update').addClass('show') }
200 $('#notify-update').html(notif);
202 var eSysmsg = $(data).find('sysmsgs');
203 eSysmsg.children("notice").each(function(){
204 text = $(this).text();
205 $.jGrowl(text, { sticky: true, theme: 'notice' });
207 eSysmsg.children("info").each(function(){
208 text = $(this).text();
209 $.jGrowl(text, { sticky: false, theme: 'info', life: 10000 });
215 // Allow folks to stop the ajax page updates with the pause/break key
216 $(document).keydown(function(event) {
217 if(event.keyCode == '8') {
218 var target = event.target || event.srcElement;
219 if (!/input|textarea/i.test(target.nodeName)) {
223 if(event.keyCode == '19' || (event.ctrlKey && event.which == '32')) {
224 event.preventDefault();
225 if(stopped == false) {
230 $('#pause').html('<img src="images/pause.gif" alt="pause" style="border: 1px solid black;" />');
244 function NavUpdate() {
247 var pingCmd = 'ping' + ((localUser != 0) ? '?f=&uid=' + localUser : '');
248 $.get(pingCmd,function(data) {
249 $(data).find('result').each(function() {
250 // send nav-update event
251 $('nav').trigger('nav-update', this);
256 if($('#live-network').length) { src = 'network'; liveUpdate(); }
257 if($('#live-profile').length) { src = 'profile'; liveUpdate(); }
258 if($('#live-community').length) { src = 'community'; liveUpdate(); }
259 if($('#live-notes').length) { src = 'notes'; liveUpdate(); }
260 if($('#live-display').length) { src = 'display'; liveUpdate(); }
261 /* if($('#live-display').length) {
264 window.location.href=window.location.href
267 if($('#live-photos').length) {
270 window.location.href=window.location.href
280 timer = setTimeout(NavUpdate,updateInterval);
283 function liveUpdate() {
284 if((src == null) || (stopped) || (! profile_uid)) { $('.like-rotator').hide(); return; }
285 if(($('.comment-edit-text-full').length) || (in_progress)) {
287 clearTimeout(livetime);
289 livetime = setTimeout(liveUpdate, 10000);
295 prev = 'live-' + src;
299 if ($(document).scrollTop() == 0)
302 var udargs = ((netargs.length) ? '/' + netargs : '');
303 var update_url = 'update_' + src + udargs + '&p=' + profile_uid + '&page=' + profile_page + '&force=' + ((force_update) ? 1 : 0);
305 $.get(update_url,function(data) {
307 force_update = false;
308 // $('.collapsed-comments',data).each(function() {
309 // var ident = $(this).attr('id');
310 // var is_hidden = $('#' + ident).is(':hidden');
311 // if($('#' + ident).length) {
312 // $('#' + ident).replaceWith($(this));
314 // $('#' + ident).hide();
319 $('.toplevel_item',data).each(function() {
320 var ident = $(this).attr('id');
322 if($('#' + ident).length == 0 && profile_page == 1) {
323 $('img',this).each(function() {
324 $(this).attr('src',$(this).attr('dst'));
326 $('#' + prev).after($(this));
329 // Find out if the hidden comments are open, so we can keep it that way
330 // if a new comment has been posted
331 var id = $('.hide-comments-total', this).attr('id');
332 if(typeof id != 'undefined') {
333 id = id.split('-')[3];
334 var commentsOpen = $("#collapsed-comments-" + id).is(":visible");
337 $('img',this).each(function() {
338 $(this).attr('src',$(this).attr('dst'));
340 //vScroll = $(document).scrollTop();
341 $('html').height($('html').height());
342 $('#' + ident).replaceWith($(this));
344 if(typeof id != 'undefined') {
345 if(commentsOpen) showHideComments(id);
347 $('html').height('auto');
348 //$(document).scrollTop(vScroll);
353 // reset vars for inserting individual items
355 /* prev = 'live-' + src;
357 $('.wall-item-outside-wrapper',data).each(function() {
358 var ident = $(this).attr('id');
360 if($('#' + ident).length == 0 && prev != 'live-' + src) {
361 $('img',this).each(function() {
362 $(this).attr('src',$(this).attr('dst'));
364 $('#' + prev).after($(this));
367 $('#' + ident + ' ' + '.wall-item-ago').replaceWith($(this).find('.wall-item-ago'));
368 if($('#' + ident + ' ' + '.comment-edit-text-empty').length)
369 $('#' + ident + ' ' + '.wall-item-comment-wrapper').replaceWith($(this).find('.wall-item-comment-wrapper'));
370 $('#' + ident + ' ' + '.hide-comments-total').replaceWith($(this).find('.hide-comments-total'));
371 $('#' + ident + ' ' + '.wall-item-like').replaceWith($(this).find('.wall-item-like'));
372 $('#' + ident + ' ' + '.wall-item-dislike').replaceWith($(this).find('.wall-item-dislike'));
373 $('#' + ident + ' ' + '.my-comment-photo').each(function() {
374 $(this).attr('src',$(this).attr('dst'));
380 $('.like-rotator').hide();
383 $('body').css('cursor', 'auto');
385 /* autocomplete @nicknames */
386 $(".comment-edit-form textarea").contact_autocomplete(baseurl+"/acl");
388 // setup videos, since VideoJS won't take care of any loaded via AJAX
389 if(typeof videojs != 'undefined') videojs.autoSetup();
393 function imgbright(node) {
394 $(node).removeClass("drophide").addClass("drop");
397 function imgdull(node) {
398 $(node).removeClass("drop").addClass("drophide");
401 // Since our ajax calls are asynchronous, we will give a few
402 // seconds for the first ajax call (setting like/dislike), then
403 // run the updater to pick up any changes and display on the page.
404 // The updater will turn any rotators off when it's done.
405 // This function will have returned long before any of these
406 // events have completed and therefore there won't be any
407 // visible feedback that anything changed without all this
408 // trickery. This still could cause confusion if the "like" ajax call
409 // is delayed and NavUpdate runs before it completes.
411 function dolike(ident,verb) {
413 $('#like-rotator-' + ident.toString()).show();
414 $.get('like/' + ident.toString() + '?verb=' + verb, NavUpdate );
419 function dosubthread(ident) {
421 $('#like-rotator-' + ident.toString()).show();
422 $.get('subthread/' + ident.toString(), NavUpdate );
427 function dostar(ident) {
428 ident = ident.toString();
429 $('#like-rotator-' + ident).show();
430 $.get('starred/' + ident, function(data) {
431 if(data.match(/1/)) {
432 $('#starred-' + ident).addClass('starred');
433 $('#starred-' + ident).removeClass('unstarred');
434 $('#star-' + ident).addClass('hidden');
435 $('#unstar-' + ident).removeClass('hidden');
438 $('#starred-' + ident).addClass('unstarred');
439 $('#starred-' + ident).removeClass('starred');
440 $('#star-' + ident).removeClass('hidden');
441 $('#unstar-' + ident).addClass('hidden');
443 $('#like-rotator-' + ident).hide();
447 function doignore(ident) {
448 ident = ident.toString();
449 $('#like-rotator-' + ident).show();
450 $.get('ignored/' + ident, function(data) {
451 if(data.match(/1/)) {
452 $('#ignored-' + ident).addClass('ignored');
453 $('#ignored-' + ident).removeClass('unignored');
454 $('#ignore-' + ident).addClass('hidden');
455 $('#unignore-' + ident).removeClass('hidden');
458 $('#ignored-' + ident).addClass('unignored');
459 $('#ignored-' + ident).removeClass('ignored');
460 $('#ignore-' + ident).removeClass('hidden');
461 $('#unignore-' + ident).addClass('hidden');
463 $('#like-rotator-' + ident).hide();
467 function getPosition(e) {
468 var cursor = {x:0, y:0};
469 if ( e.pageX || e.pageY ) {
474 if( e.clientX || e.clientY ) {
475 cursor.x = e.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft) - document.documentElement.clientLeft;
476 cursor.y = e.clientY + (document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop;
488 var lockvisible = false;
490 function lockview(event,id) {
491 event = event || window.event;
492 cursor = getPosition(event);
498 $.get('lockview/' + id, function(data) {
499 $('#panel').html(data);
500 $('#panel').css({ 'left': cursor.x + 5 , 'top': cursor.y + 5});
506 function lockviewhide() {
511 function post_comment(id) {
514 $('body').css('cursor', 'wait');
515 $("#comment-preview-inp-" + id).val("0");
518 $("#comment-edit-form-" + id).serialize(),
521 $("#comment-edit-wrapper-" + id).hide();
522 $("#comment-edit-text-" + id).val('');
523 var tarea = document.getElementById("comment-edit-text-" + id);
525 commentClose(tarea,id);
526 if(timer) clearTimeout(timer);
527 timer = setTimeout(NavUpdate,10);
531 window.location.href=data.reload;
540 function preview_comment(id) {
541 $("#comment-preview-inp-" + id).val("1");
542 $("#comment-edit-preview-" + id).show();
545 $("#comment-edit-form-" + id).serialize(),
549 $("#comment-edit-preview-" + id).html(data.preview);
550 $("#comment-edit-preview-" + id + " a").click(function() { return false; });
560 function showHideComments(id) {
561 if( $("#collapsed-comments-" + id).is(":visible")) {
562 $("#collapsed-comments-" + id).hide();
563 $("#hide-comments-" + id).html(window.showMore);
566 $("#collapsed-comments-" + id).show();
567 $("#hide-comments-" + id).html(window.showFewer);
573 function preview_post() {
574 $("#jot-preview").val("1");
575 $("#jot-preview-content").show();
576 tinyMCE.triggerSave();
579 $("#profile-jot-form").serialize(),
582 $("#jot-preview-content").html(data.preview);
583 $("#jot-preview-content" + " a").click(function() { return false; });
588 $("#jot-preview").val("0");
594 // unpause auto reloads if they are currently stopped
597 $('#pause').html('');
602 // Converts the binary representation of data to hex
605 // discuss at: http://phpjs.org/functions/bin2hex
606 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
607 // + bugfixed by: Onno Marsman
608 // + bugfixed by: Linuxworld
609 // * example 1: bin2hex('Kev');
610 // * returns 1: '4b6576'
611 // * example 2: bin2hex(String.fromCharCode(0x00));
613 var v,i, f = 0, a = [];
617 for (i = 0; i<f; i++) {
618 a[i] = s.charCodeAt(i).toString(16).replace(/^([\da-f])$/,"0$1");
624 function groupChangeMember(gid, cid, sec_token) {
625 $('body .fakelink').css('cursor', 'wait');
626 $.get('group/' + gid + '/' + cid + "?t=" + sec_token, function(data) {
627 $('#group-update-wrapper').html(data);
628 $('body .fakelink').css('cursor', 'auto');
632 function profChangeMember(gid,cid) {
633 $('body .fakelink').css('cursor', 'wait');
634 $.get('profperm/' + gid + '/' + cid, function(data) {
635 $('#prof-update-wrapper').html(data);
636 $('body .fakelink').css('cursor', 'auto');
640 function contactgroupChangeMember(gid,cid) {
641 $('body').css('cursor', 'wait');
642 $.get('contactgroup/' + gid + '/' + cid, function(data) {
643 $('body').css('cursor', 'auto');
648 function checkboxhighlight(box) {
649 if($(box).is(':checked')) {
650 $(box).addClass('checkeditem');
653 $(box).removeClass('checkeditem');
657 function notifyMarkAll() {
658 $.get('notify/mark/all', function(data) {
659 if(timer) clearTimeout(timer);
660 timer = setTimeout(NavUpdate,1000);
666 // code from http://www.tinymce.com/wiki.php/How-to_implement_a_custom_file_browser
667 function fcFileBrowser (field_name, url, type, win) {
668 /* TODO: If you work with sessions in PHP and your client doesn't accept cookies you might need to carry
669 the session name and session ID in the request string (can look like this: "?PHPSESSID=88p0n70s9dsknra96qhuk6etm5").
670 These lines of code extract the necessary parameters and add them back to the filebrowser URL again. */
673 var cmsURL = baseurl+"/fbrowser/"+type+"/";
675 tinyMCE.activeEditor.windowManager.open({
677 title : 'File Browser',
678 width : 420, // Your dimensions may differ - toy around with them!
681 inline : "yes", // This parameter only has an effect if you use the inlinepopups plugin!
682 close_previous : "no"
690 function setupFieldRichtext(){
693 mode : "specific_textareas",
694 editor_selector: "fieldRichtext",
695 plugins : "bbcode,paste, inlinepopups",
696 theme_advanced_buttons1 : "bold,italic,underline,undo,redo,link,unlink,image,forecolor,formatselect,code",
697 theme_advanced_buttons2 : "",
698 theme_advanced_buttons3 : "",
699 theme_advanced_toolbar_location : "top",
700 theme_advanced_toolbar_align : "center",
701 theme_advanced_blockformats : "blockquote,code",
702 paste_text_sticky : true,
703 entity_encoding : "raw",
704 add_unload_trigger : false,
705 remove_linebreaks : false,
706 //force_p_newlines : false,
707 //force_br_newlines : true,
708 forced_root_block : 'div',
710 content_css: baseurl+"/view/custom_tinymce.css",
711 theme_advanced_path : false,
712 file_browser_callback : "fcFileBrowser",
718 * sprintf in javascript
719 * "{0} and {1}".format('zero','uno');
721 String.prototype.format = function() {
722 var formatted = this;
723 for (var i = 0; i < arguments.length; i++) {
724 var regexp = new RegExp('\\{'+i+'\\}', 'gi');
725 formatted = formatted.replace(regexp, arguments[i]);
730 Array.prototype.remove = function(item) {
731 to=undefined; from=this.indexOf(item);
732 var rest = this.slice((to || from) + 1 || this.length);
733 this.length = from < 0 ? this.length + from : from;
734 return this.push.apply(this, rest);
737 function previewTheme(elm) {
738 theme = $(elm).val();
739 $.getJSON('pretheme?f=&theme=' + theme,function(data) {
740 $('#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>');