2 function openClose(listID) {
3 /* if(document.getElementById(theID).style.display == "block") {
4 document.getElementById(theID).style.display = "none"
7 document.getElementById(theID).style.display = "block"
9 listID = "#" + listID.replace(/:/g, "\\:");
10 listID = listID.replace(/\./g, "\\.");
11 listID = listID.replace(/@/g, "\\@");
13 if($(listID).is(":visible")) {
15 $(listID+"-wrapper").show();
19 $(listID+"-wrapper").hide();
23 function openMenu(theID) {
24 document.getElementById(theID).style.display = "block"
27 function closeMenu(theID) {
28 document.getElementById(theID).style.display = "none"
37 var totStopped = false;
41 var in_progress = false;
42 var langSelect = false;
43 var commentBusy = false;
44 var last_popup_menu = null;
45 var last_popup_button = null;
48 $.ajaxSetup({cache: false});
52 /* setup tooltips *//*
53 $("a,.tt").each(function(){
56 if (e.hasClass("tttop")) pos="top";
57 if (e.hasClass("ttbottom")) pos="bottom";
58 if (e.hasClass("ttleft")) pos="left";
59 if (e.hasClass("ttright")) pos="right";
60 e.tipTip({defaultPosition: pos, edgeOffset: 8});
65 /* setup onoff widgets */
66 $(".onoff input").each(function(){
68 id = $(this).attr("id");
69 $("#"+id+"_onoff ."+ (val==0?"on":"off")).addClass("hidden");
72 $(".onoff > a").click(function(event){
73 event.preventDefault();
74 var input = $(this).siblings("input");
75 var val = 1-input.val();
76 var id = input.attr("id");
77 $("#"+id+"_onoff ."+ (val==0?"on":"off")).addClass("hidden");
78 $("#"+id+"_onoff ."+ (val==1?"on":"off")).removeClass("hidden");
83 /* setup field_richtext */
84 /*setupFieldRichtext();*/
87 function close_last_popup_menu(e) {
89 if( last_popup_menu ) {
90 if( '#' + last_popup_menu.attr('id') !== $(e.target).attr('rel')) {
91 last_popup_menu.hide();
92 if (last_popup_menu.attr('id') == "nav-notifications-menu" ) $('.main-container').show();
93 last_popup_button.removeClass("selected");
94 last_popup_menu = null;
95 last_popup_button = null;
99 $('img[rel^=#]').click(function(e){
101 close_last_popup_menu(e);
102 menu = $( $(this).attr('rel') );
106 if (menu.attr('popup')=="false") return false;
108 // $(this).parent().toggleClass("selected");
111 if (menu.css("display") == "none") {
112 $(this).parent().addClass("selected");
114 if (menu.attr('id') == "nav-notifications-menu" ) $('.main-container').hide();
115 last_popup_menu = menu;
116 last_popup_button = $(this).parent();
118 $(this).parent().removeClass("selected");
120 if (menu.attr('id') == "nav-notifications-menu" ) $('.main-container').show();
121 last_popup_menu = null;
122 last_popup_button = null;
126 $('html').click(function(e) {
127 close_last_popup_menu(e);
131 /*$("a.popupbox").colorbox({
133 'transition' : 'none'
137 /* notifications template */
138 var notifications_tpl= unescape($("#nav-notifications-template[rel=template]").html());
139 var notifications_all = unescape($('<div>').append( $("#nav-notifications-see-all").clone() ).html()); //outerHtml hack
140 var notifications_mark = unescape($('<div>').append( $("#nav-notifications-mark-all").clone() ).html()); //outerHtml hack
141 var notifications_empty = unescape($("#nav-notifications-menu").html());
143 /* nav update event */
144 $('nav').bind('nav-update', function(e,data){;
145 var invalid = $(data).find('invalid').text();
146 if(invalid == 1) { window.location.href=window.location.href }
148 var net = $(data).find('net').text();
149 if(net == 0) { net = ''; $('#net-update').removeClass('show') } else { $('#net-update').addClass('show') }
150 $('#net-update').html(net);
152 var home = $(data).find('home').text();
153 if(home == 0) { home = ''; $('#home-update').removeClass('show') } else { $('#home-update').addClass('show') }
154 $('#home-update').html(home);
156 var intro = $(data).find('intro').text();
157 if(intro == 0) { intro = ''; $('#intro-update').removeClass('show') } else { $('#intro-update').addClass('show') }
158 $('#intro-update').html(intro);
160 var mail = $(data).find('mail').text();
161 if(mail == 0) { mail = ''; $('#mail-update').removeClass('show') } else { $('#mail-update').addClass('show') }
162 $('#mail-update').html(mail);
164 var intro = $(data).find('intro').text();
165 if(intro == 0) { intro = ''; $('#intro-update-li').removeClass('show') } else { $('#intro-update-li').addClass('show') }
166 $('#intro-update-li').html(intro);
168 var mail = $(data).find('mail').text();
169 if(mail == 0) { mail = ''; $('#mail-update-li').removeClass('show') } else { $('#mail-update-li').addClass('show') }
170 $('#mail-update-li').html(mail);
172 var eNotif = $(data).find('notif')
174 if (eNotif.children("note").length==0){
175 $("#nav-notifications-menu").html(notifications_empty);
177 nnm = $("#nav-notifications-menu");
178 nnm.html(notifications_all + notifications_mark);
179 //nnm.attr('popup','true');
180 eNotif.children("note").each(function(){
182 text = e.text().format("<span class='contactname'>"+e.attr('name')+"</span>");
183 html = notifications_tpl.format(e.attr('href'),e.attr('photo'), text, e.attr('date'), e.attr('seen'));
187 $("img[data-src]", nnm).each(function(i, el){
188 // Add src attribute for images with a data-src attribute
189 // However, don't bother if the data-src attribute is empty, because
190 // an empty "src" tag for an image will cause some browsers
191 // to prefetch the root page of the Friendica hub, which will
192 // unnecessarily load an entire profile/ or network/ page
193 if($(el).data("src") != '') $(el).attr('src', $(el).data("src"));
196 notif = eNotif.attr('count');
198 $("#nav-notifications-linkmenu").addClass("on");
200 $("#nav-notifications-linkmenu").removeClass("on");
202 if(notif == 0) { notif = ''; $('#notify-update').removeClass('show') } else { $('#notify-update').addClass('show') }
203 $('#notify-update').html(notif);
205 var eSysmsg = $(data).find('sysmsgs');
206 eSysmsg.children("notice").each(function(){
207 text = $(this).text();
208 $.jGrowl(text, { sticky: false, theme: 'notice', life: 1000 });
210 eSysmsg.children("info").each(function(){
211 text = $(this).text();
212 $.jGrowl(text, { sticky: false, theme: 'info', life: 1000 });
219 // Allow folks to stop the ajax page updates with the pause/break key
220 /* $(document).keydown(function(event) {
221 if(event.keyCode == '8') {
222 var target = event.target || event.srcElement;
223 if (!/input|textarea/i.test(target.nodeName)) {
227 if(event.keyCode == '19' || (event.ctrlKey && event.which == '32')) {
228 event.preventDefault();
229 if(stopped == false) {
234 $('#pause').html('<img src="images/pause.gif" alt="pause" style="border: 1px solid black;" />');
248 function NavUpdate() {
251 var pingCmd = 'ping' + ((localUser != 0) ? '?f=&uid=' + localUser : '');
252 $.get(pingCmd,function(data) {
253 $(data).find('result').each(function() {
254 // send nav-update event
255 $('nav').trigger('nav-update', this);
262 if($('#live-network').length) { src = 'network'; liveUpdate(); }
263 if($('#live-profile').length) { src = 'profile'; liveUpdate(); }
264 if($('#live-community').length) { src = 'community'; liveUpdate(); }
265 if($('#live-notes').length) { src = 'notes'; liveUpdate(); }
266 if($('#live-display').length) { src = 'display'; liveUpdate(); }
267 /*if($('#live-display').length) {
270 window.location.href=window.location.href
273 if($('#live-photos').length) {
276 window.location.href=window.location.href
286 timer = setTimeout(NavUpdate,updateInterval);
289 function liveUpdate() {
290 if((src == null) || (stopped) || (typeof profile_uid == 'undefined') || (! profile_uid)) { $('.like-rotator').hide(); return; }
291 if(($('.comment-edit-text-full').length) || (in_progress)) {
293 clearTimeout(livetime);
295 livetime = setTimeout(liveUpdate, 5000);
301 prev = 'live-' + src;
304 var udargs = ((netargs.length) ? '/' + netargs : '');
305 var update_url = 'update_' + src + udargs + '&p=' + profile_uid + '&page=' + profile_page;
307 $.get(update_url,function(data) {
309 // $('.collapsed-comments',data).each(function() {
310 // var ident = $(this).attr('id');
311 // var is_hidden = $('#' + ident).is(':hidden');
312 // if($('#' + ident).length) {
313 // $('#' + ident).replaceWith($(this));
315 // $('#' + ident).hide();
321 $('.toplevel_item',data).each(function() {
322 var ident = $(this).attr('id');
324 if($('#' + ident).length == 0 && profile_page == 1) {
325 $('img',this).each(function() {
326 $(this).attr('src',$(this).attr('dst'));
328 $('#' + prev).after($(this));
331 // Find out if the hidden comments are open, so we can keep it that way
332 // if a new comment has been posted
333 var id = $('.hide-comments-total', this).attr('id');
334 if(typeof id != 'undefined') {
335 id = id.split('-')[3];
336 var commentsOpen = $("#collapsed-comments-" + id).is(":visible");
339 $('img',this).each(function() {
340 $(this).attr('src',$(this).attr('dst'));
342 //vScroll = $(document).scrollTop();
343 $('html').height($('html').height());
344 $('#' + ident).replaceWith($(this));
346 if(typeof id != 'undefined') {
347 if(commentsOpen) showHideComments(id);
349 $('html').height('auto');
350 //$(document).scrollTop(vScroll);
358 // reset vars for inserting individual items
360 /*prev = 'live-' + src;
362 $('.wall-item-outside-wrapper',data).each(function() {
363 var ident = $(this).attr('id');
365 if($('#' + ident).length == 0 && prev != 'live-' + src) {
366 $('img',this).each(function() {
367 $(this).attr('src',$(this).attr('dst'));
369 $('#' + prev).after($(this));
372 $('#' + ident + ' ' + '.wall-item-ago').replaceWith($(this).find('.wall-item-ago'));
373 if($('#' + ident + ' ' + '.comment-edit-text-empty').length)
374 $('#' + ident + ' ' + '.wall-item-comment-wrapper').replaceWith($(this).find('.wall-item-comment-wrapper'));
375 $('#' + ident + ' ' + '.hide-comments-total').replaceWith($(this).find('.hide-comments-total'));
376 $('#' + ident + ' ' + '.wall-item-like').replaceWith($(this).find('.wall-item-like'));
377 $('#' + ident + ' ' + '.wall-item-dislike').replaceWith($(this).find('.wall-item-dislike'));
378 $('#' + ident + ' ' + '.my-comment-photo').each(function() {
379 $(this).attr('src',$(this).attr('dst'));
385 $('.like-rotator').hide();
388 $('body').css('cursor', 'auto');
390 /* autocomplete @nicknames */
391 $(".comment-edit-form textarea").editor_autocomplete(baseurl+"/acl");
393 // setup videos, since VideoJS won't take care of any loaded via AJAX
394 if(typeof videojs != 'undefined') videojs.autoSetup();
398 function collapseHeight(elems) {
399 var elemName = '.wall-item-body:not(.divmore)';
400 if(typeof elems != 'undefined') {
401 elemName = elems + ' ' + elemName;
403 $(elemName).each(function() {
404 $('html').height($('html').height());
405 $(this).readmore({maxheight:350 , moreLink:'<a href="#" class="showmore">+ Show more</a>', lessLink:'<a href="#" class="showmore">+ Show less</a>'});
406 $(this).addClass('divmore');
407 $('html').height('auto');
411 /* function imgbright(node) {
412 $(node).removeClass("drophide").addClass("drop");
415 function imgdull(node) {
416 $(node).removeClass("drop").addClass("drophide");
419 // Since our ajax calls are asynchronous, we will give a few
420 // seconds for the first ajax call (setting like/dislike), then
421 // run the updater to pick up any changes and display on the page.
422 // The updater will turn any rotators off when it's done.
423 // This function will have returned long before any of these
424 // events have completed and therefore there won't be any
425 // visible feedback that anything changed without all this
426 // trickery. This still could cause confusion if the "like" ajax call
427 // is delayed and NavUpdate runs before it completes.
429 function dolike(ident,verb) {
431 $('#like-rotator-' + ident.toString()).show();
432 $.get('like/' + ident.toString() + '?verb=' + verb, NavUpdate );
433 // if(timer) clearTimeout(timer);
434 // timer = setTimeout(NavUpdate,3000);
438 function dostar(ident) {
439 ident = ident.toString();
440 //$('#like-rotator-' + ident).show();
441 $.get('starred/' + ident, function(data) {
442 if(data.match(/1/)) {
443 $('#starred-' + ident).addClass('starred');
444 $('#starred-' + ident).removeClass('unstarred');
445 $('#star-' + ident).addClass('hidden');
446 $('#unstar-' + ident).removeClass('hidden');
449 $('#starred-' + ident).addClass('unstarred');
450 $('#starred-' + ident).removeClass('starred');
451 $('#star-' + ident).removeClass('hidden');
452 $('#unstar-' + ident).addClass('hidden');
454 //$('#like-rotator-' + ident).hide();
458 function getPosition(e) {
459 var cursor = {x:0, y:0};
460 if ( e.pageX || e.pageY ) {
465 if( e.clientX || e.clientY ) {
466 cursor.x = e.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft) - document.documentElement.clientLeft;
467 cursor.y = e.clientY + (document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop;
479 var lockvisible = false;
481 function lockview(event,id) {
482 event = event || window.event;
483 cursor = getPosition(event);
489 $.get('lockview/' + id, function(data) {
490 $('#panel').html(data);
491 $('#panel').css({ 'left': 10 , 'top': cursor.y + 20});
497 function lockviewhide() {
502 function post_comment(id) {
505 $('body').css('cursor', 'wait');
506 $("#comment-preview-inp-" + id).val("0");
509 $("#comment-edit-form-" + id).serialize(),
512 $("#comment-edit-wrapper-" + id).hide();
513 $("#comment-edit-text-" + id).val('');
514 var tarea = document.getElementById("comment-edit-text-" + id);
516 commentClose(tarea,id);
517 if(timer) clearTimeout(timer);
518 timer = setTimeout(NavUpdate,10);
521 window.location.href=data.reload;
530 function preview_comment(id) {
531 $("#comment-preview-inp-" + id).val("1");
532 $("#comment-edit-preview-" + id).show();
535 $("#comment-edit-form-" + id).serialize(),
539 $("#comment-edit-preview-" + id).html(data.preview);
540 $("#comment-edit-preview-" + id + " a").click(function() { return false; });
549 function showHideComments(id) {
550 if( $("#collapsed-comments-" + id).is(":visible")) {
551 $("#collapsed-comments-" + id).hide();
552 $("#hide-comments-" + id).html(window.showMore);
555 $("#collapsed-comments-" + id).show();
556 $("#hide-comments-" + id).html(window.showFewer);
557 collapseHeight("#collapsed-comments-" + id);
562 function preview_post() {
563 $("#jot-preview").val("1");
564 $("#jot-preview-content").show();
565 tinyMCE.triggerSave();
568 $("#profile-jot-form").serialize(),
571 $("#jot-preview-content").html(data.preview);
572 $("#jot-preview-content" + " a").click(function() { return false; });
577 $("#jot-preview").val("0");
583 // unpause auto reloads if they are currently stopped
586 $('#pause').html('');
591 // Converts the binary representation of data to hex
594 // discuss at: http://phpjs.org/functions/bin2hex
595 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
596 // + bugfixed by: Onno Marsman
597 // + bugfixed by: Linuxworld
598 // * example 1: bin2hex('Kev');
599 // * returns 1: '4b6576'
600 // * example 2: bin2hex(String.fromCharCode(0x00));
602 var v,i, f = 0, a = [];
606 for (i = 0; i<f; i++) {
607 a[i] = s.charCodeAt(i).toString(16).replace(/^([\da-f])$/,"0$1");
613 function groupChangeMember(gid, cid, sec_token) {
614 $('body .fakelink').css('cursor', 'wait');
615 $.get('group/' + gid + '/' + cid + "?t=" + sec_token, function(data) {
616 $('#group-update-wrapper').html(data);
617 $('body .fakelink').css('cursor', 'auto');
621 function profChangeMember(gid,cid) {
622 $('body .fakelink').css('cursor', 'wait');
623 $.get('profperm/' + gid + '/' + cid, function(data) {
624 $('#prof-update-wrapper').html(data);
625 $('body .fakelink').css('cursor', 'auto');
629 function contactgroupChangeMember(gid,cid) {
630 $('body').css('cursor', 'wait');
631 $.get('contactgroup/' + gid + '/' + cid, function(data) {
632 $('body').css('cursor', 'auto');
637 function checkboxhighlight(box) {
638 if($(box).is(':checked')) {
639 $(box).addClass('checkeditem');
642 $(box).removeClass('checkeditem');
646 function notifyMarkAll() {
647 $.get('notify/mark/all', function(data) {
648 if(timer) clearTimeout(timer);
649 timer = setTimeout(NavUpdate,1000);
654 // code from http://www.tinymce.com/wiki.php/How-to_implement_a_custom_file_browser
655 function fcFileBrowser (field_name, url, type, win) {
656 /* TODO: If you work with sessions in PHP and your client doesn't accept cookies you might need to carry
657 the session name and session ID in the request string (can look like this: "?PHPSESSID=88p0n70s9dsknra96qhuk6etm5").
658 These lines of code extract the necessary parameters and add them back to the filebrowser URL again. */
661 var cmsURL = baseurl+"/fbrowser/"+type+"/";
663 tinyMCE.activeEditor.windowManager.open({
665 title : 'File Browser',
666 width : 420, // Your dimensions may differ - toy around with them!
669 inline : "yes", // This parameter only has an effect if you use the inlinepopups plugin!
670 close_previous : "no"
678 function setupFieldRichtext(){
681 mode : "specific_textareas",
682 editor_selector: "fieldRichtext",
683 plugins : "bbcode,paste, inlinepopups",
684 theme_advanced_buttons1 : "bold,italic,underline,undo,redo,link,unlink,image,forecolor,formatselect,code",
685 theme_advanced_buttons2 : "",
686 theme_advanced_buttons3 : "",
687 theme_advanced_toolbar_location : "top",
688 theme_advanced_toolbar_align : "center",
689 theme_advanced_blockformats : "blockquote,code",
690 paste_text_sticky : true,
691 entity_encoding : "raw",
692 add_unload_trigger : false,
693 remove_linebreaks : false,
694 //force_p_newlines : false,
695 //force_br_newlines : true,
696 forced_root_block : 'div',
698 content_css: baseurl+"/view/custom_tinymce.css",
699 theme_advanced_path : false,
700 file_browser_callback : "fcFileBrowser",
706 * sprintf in javascript
707 * "{0} and {1}".format('zero','uno');
709 String.prototype.format = function() {
710 var formatted = this;
711 for (var i = 0; i < arguments.length; i++) {
712 var regexp = new RegExp('\\{'+i+'\\}', 'gi');
713 formatted = formatted.replace(regexp, arguments[i]);
718 Array.prototype.remove = function(item) {
719 to=undefined; from=this.indexOf(item);
720 var rest = this.slice((to || from) + 1 || this.length);
721 this.length = from < 0 ? this.length + from : from;
722 return this.push.apply(this, rest);
725 function previewTheme(elm) {
726 theme = $(elm).val();
727 $.getJSON('pretheme?f=&theme=' + theme,function(data) {
728 $('#theme-preview').html('<div id="theme-desc">' + data.desc + '</div><div id="theme-version">' + data.version + '</div><div id="theme-credits">' + data.credits + '</div>');