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"
38 var totStopped = false;
42 var in_progress = false;
43 var langSelect = false;
44 var commentBusy = false;
45 var last_popup_menu = null;
46 var last_popup_button = null;
49 $.ajaxSetup({cache: false});
51 msie = $.browser.msie ;
55 /* setup tooltips *//*
56 $("a,.tt").each(function(){
59 if (e.hasClass("tttop")) pos="top";
60 if (e.hasClass("ttbottom")) pos="bottom";
61 if (e.hasClass("ttleft")) pos="left";
62 if (e.hasClass("ttright")) pos="right";
63 e.tipTip({defaultPosition: pos, edgeOffset: 8});
68 /* setup onoff widgets */
69 $(".onoff input").each(function(){
71 id = $(this).attr("id");
72 $("#"+id+"_onoff ."+ (val==0?"on":"off")).addClass("hidden");
75 $(".onoff > a").click(function(event){
76 event.preventDefault();
77 var input = $(this).siblings("input");
78 var val = 1-input.val();
79 var id = input.attr("id");
80 $("#"+id+"_onoff ."+ (val==0?"on":"off")).addClass("hidden");
81 $("#"+id+"_onoff ."+ (val==1?"on":"off")).removeClass("hidden");
86 /* setup field_richtext */
87 //setupFieldRichtext();
90 function close_last_popup_menu(e) {
92 if( last_popup_menu ) {
93 if( '#' + last_popup_menu.attr('id') !== $(e.target).attr('rel')) {
94 last_popup_menu.hide();
95 last_popup_button.removeClass("selected");
96 last_popup_menu = null;
97 last_popup_button = null;
101 $('a[rel^=#]').click(function(e){
103 close_last_popup_menu(e);
104 menu = $( $(this).attr('rel') );
108 if (menu.attr('popup')=="false") return false;
110 $(this).parent().toggleClass("selected");
111 menu.slideToggle('fast');
113 if (menu.css("display") == "none") {
114 last_popup_menu = null;
115 last_popup_button = null;
117 last_popup_menu = menu;
118 last_popup_button = $(this).parent();
122 $('html').click(function(e) {
123 close_last_popup_menu(e);
127 $("a.popupbox").colorbox({
129 'transition' : 'elastic'
133 /* notifications template */
134 var notifications_tpl= unescape($("#nav-notifications-template[rel=template]").html());
135 var notifications_all = unescape($('<div>').append( $("#nav-notifications-see-all").clone() ).html()); //outerHtml hack
136 var notifications_mark = unescape($('<div>').append( $("#nav-notifications-mark-all").clone() ).html()); //outerHtml hack
137 var notifications_empty = unescape($("#nav-notifications-menu").html());
139 /* nav update event */
140 $('nav').bind('nav-update', function(e,data){;
141 var invalid = $(data).find('invalid').text();
142 if(invalid == 1) { window.location.href=window.location.href }
144 var net = $(data).find('net').text();
145 if(net == 0) { net = ''; $('#net-update').removeClass('show') } else { $('#net-update').addClass('show') }
146 $('#net-update').html(net);
148 var home = $(data).find('home').text();
149 if(home == 0) { home = ''; $('#home-update').removeClass('show') } else { $('#home-update').addClass('show') }
150 $('#home-update').html(home);
152 var intro = $(data).find('intro').text();
153 if(intro == 0) { intro = ''; $('#intro-update').removeClass('show') } else { $('#intro-update').addClass('show') }
154 $('#intro-update').html(intro);
156 var mail = $(data).find('mail').text();
157 if(mail == 0) { mail = ''; $('#mail-update').removeClass('show') } else { $('#mail-update').addClass('show') }
158 $('#mail-update').html(mail);
160 var intro = $(data).find('intro').text();
161 if(intro == 0) { intro = ''; $('#intro-update-li').removeClass('show') } else { $('#intro-update-li').addClass('show') }
162 $('#intro-update-li').html(intro);
164 var mail = $(data).find('mail').text();
165 if(mail == 0) { mail = ''; $('#mail-update-li').removeClass('show') } else { $('#mail-update-li').addClass('show') }
166 $('#mail-update-li').html(mail);
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"));
192 notif = eNotif.attr('count');
194 $("#nav-notifications-linkmenu").addClass("on");
196 $("#nav-notifications-linkmenu").removeClass("on");
198 if(notif == 0) { notif = ''; $('#notify-update').removeClass('show') } else { $('#notify-update').addClass('show') }
199 $('#notify-update').html(notif);
201 var eSysmsg = $(data).find('sysmsgs');
202 eSysmsg.children("notice").each(function(){
203 text = $(this).text();
204 $.jGrowl(text, { sticky: false, theme: 'notice', life: 3000 }); // originally: sticky: true,
206 eSysmsg.children("info").each(function(){
207 text = $(this).text();
208 $.jGrowl(text, { sticky: false, theme: 'info', life: 1000 });
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);
258 if($('#live-network').length) { src = 'network'; liveUpdate(); }
259 if($('#live-profile').length) { src = 'profile'; liveUpdate(); }
260 if($('#live-community').length) { src = 'community'; liveUpdate(); }
261 if($('#live-notes').length) { src = 'notes'; liveUpdate(); }
262 if($('#live-display').length) { src = 'display'; liveUpdate(); }
263 /*if($('#live-display').length) {
266 window.location.href=window.location.href
269 if($('#live-photos').length) {
272 window.location.href=window.location.href
282 timer = setTimeout(NavUpdate,updateInterval);
285 function liveUpdate() {
286 if((src == null) || (stopped) || (typeof profile_uid == 'undefined') || (! profile_uid)) { $('.like-rotator').hide(); return; }
287 if(($('.comment-edit-text-full').length) || (in_progress)) {
289 clearTimeout(livetime);
291 livetime = setTimeout(liveUpdate, 10000);
297 prev = 'live-' + src;
300 var udargs = ((netargs.length) ? '/' + netargs : '');
301 var update_url = 'update_' + src + udargs + '&p=' + profile_uid + '&page=' + profile_page + '&msie=' + ((msie) ? 1 : 0);
303 $.get(update_url,function(data) {
305 // $('.collapsed-comments',data).each(function() {
306 // var ident = $(this).attr('id');
307 // var is_hidden = $('#' + ident).is(':hidden');
308 // if($('#' + ident).length) {
309 // $('#' + ident).replaceWith($(this));
311 // $('#' + ident).hide();
317 $('.toplevel_item',data).each(function() {
318 var ident = $(this).attr('id');
320 if($('#' + ident).length == 0 && profile_page == 1) {
321 $('img',this).each(function() {
322 $(this).attr('src',$(this).attr('dst'));
324 $('#' + prev).after($(this));
327 // Find out if the hidden comments are open, so we can keep it that way
328 // if a new comment has been posted
329 var id = $('.hide-comments-total', this).attr('id');
330 if(typeof id != 'undefined') {
331 id = id.split('-')[3];
332 var commentsOpen = $("#collapsed-comments-" + id).is(":visible");
335 $('img',this).each(function() {
336 $(this).attr('src',$(this).attr('dst'));
338 //vScroll = $(document).scrollTop();
339 $('html').height($('html').height());
340 $('#' + ident).replaceWith($(this));
342 if(typeof id != 'undefined') {
343 if(commentsOpen) showHideComments(id);
345 $('html').height('auto');
346 //$(document).scrollTop(vScroll);
349 // Add Colorbox for viewing Network page images
350 $("#" + ident + " .wall-item-body a img").each(function(){
351 var aElem = $(this).parent();
352 var imgHref = aElem.attr("href");
354 // We need to make sure we only put a Colorbox on links to Friendica images
355 // We'll try to do this by looking for links of the form
356 // .../photo/ab803d8eg08daf85023adfec08(-0.jpg) (with nothing more following), in hopes
357 // that that will be unique enough
358 if(imgHref.match(/\/photo\/[a-fA-F0-9]+(-[0-9]\.[\w]+?)?$/)) {
360 // Add a unique class to all the images of a certain post, to allow scrolling through
361 var cBoxClass = $(this).closest(".wall-item-body").attr("id") + "-lightbox";
362 $(this).addClass(cBoxClass);
375 // reset vars for inserting individual items
377 /*prev = 'live-' + src;
379 $('.wall-item-outside-wrapper',data).each(function() {
380 var ident = $(this).attr('id');
382 if($('#' + ident).length == 0 && prev != 'live-' + src) {
383 $('img',this).each(function() {
384 $(this).attr('src',$(this).attr('dst'));
386 $('#' + prev).after($(this));
389 $('#' + ident + ' ' + '.wall-item-ago').replaceWith($(this).find('.wall-item-ago'));
390 if($('#' + ident + ' ' + '.comment-edit-text-empty').length)
391 $('#' + ident + ' ' + '.wall-item-comment-wrapper').replaceWith($(this).find('.wall-item-comment-wrapper'));
392 $('#' + ident + ' ' + '.hide-comments-total').replaceWith($(this).find('.hide-comments-total'));
393 $('#' + ident + ' ' + '.wall-item-like').replaceWith($(this).find('.wall-item-like'));
394 $('#' + ident + ' ' + '.wall-item-dislike').replaceWith($(this).find('.wall-item-dislike'));
395 $('#' + ident + ' ' + '.my-comment-photo').each(function() {
396 $(this).attr('src',$(this).attr('dst'));
402 $('.like-rotator').hide();
405 $('body').css('cursor', 'auto');
407 /* autocomplete @nicknames */
408 $(".comment-edit-form textarea").contact_autocomplete(baseurl+"/acl");
412 // setup videos, since VideoJS won't take care of any loaded via AJAX
413 if(typeof videojs != 'undefined') videojs.autoSetup();
417 function collapseHeight(elems) {
418 var elemName = '.wall-item-body:not(.divmore)';
419 if(typeof elems != 'undefined') {
420 elemName = elems + ' ' + elemName;
422 $(elemName).each(function() {
423 if($(this).height() > 450) {
424 $('html').height($('html').height());
425 $(this).divgrow({ initialHeight: 400, showBrackets: false, speed: 0 });
426 $(this).addClass('divmore');
427 $('html').height('auto');
432 /*function imgbright(node) {
433 $(node).removeClass("drophide").addClass("drop");
436 function imgdull(node) {
437 $(node).removeClass("drop").addClass("drophide");
440 // Since our ajax calls are asynchronous, we will give a few
441 // seconds for the first ajax call (setting like/dislike), then
442 // run the updater to pick up any changes and display on the page.
443 // The updater will turn any rotators off when it's done.
444 // This function will have returned long before any of these
445 // events have completed and therefore there won't be any
446 // visible feedback that anything changed without all this
447 // trickery. This still could cause confusion if the "like" ajax call
448 // is delayed and NavUpdate runs before it completes.
450 function dolike(ident,verb) {
452 $('#like-rotator-' + ident.toString()).show();
453 $.get('like/' + ident.toString() + '?verb=' + verb, NavUpdate );
457 function dostar(ident) {
458 ident = ident.toString();
459 // $('#like-rotator-' + ident).show();
460 $.get('starred/' + ident, function(data) {
461 if(data.match(/1/)) {
462 $('#starred-' + ident).addClass('starred');
463 $('#starred-' + ident).removeClass('unstarred');
464 $('#star-' + ident).addClass('hidden');
465 $('#unstar-' + ident).removeClass('hidden');
468 $('#starred-' + ident).addClass('unstarred');
469 $('#starred-' + ident).removeClass('starred');
470 $('#star-' + ident).removeClass('hidden');
471 $('#unstar-' + ident).addClass('hidden');
473 // $('#like-rotator-' + ident).hide();
477 function getPosition(e) {
478 var cursor = {x:0, y:0};
479 if ( e.pageX || e.pageY ) {
484 if( e.clientX || e.clientY ) {
485 cursor.x = e.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft) - document.documentElement.clientLeft;
486 cursor.y = e.clientY + (document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop;
498 var lockvisible = false;
500 function lockview(event,id) {
501 event = event || window.event;
502 cursor = getPosition(event);
508 $.get('lockview/' + id, function(data) {
509 $('#panel').html(data);
510 $('#panel').css({ 'left': cursor.x + 5 , 'top': cursor.y + 5});
516 function lockviewhide() {
521 function post_comment(id) {
524 $('body').css('cursor', 'wait');
525 $("#comment-preview-inp-" + id).val("0");
528 $("#comment-edit-form-" + id).serialize(),
531 $("#comment-edit-wrapper-" + id).hide();
532 $("#comment-edit-text-" + id).val('');
533 var tarea = document.getElementById("comment-edit-text-" + id);
535 commentClose(tarea,id);
536 if(timer) clearTimeout(timer);
537 timer = setTimeout(NavUpdate,10);
540 window.location.href=data.reload;
549 function preview_comment(id) {
550 $("#comment-preview-inp-" + id).val("1");
551 $("#comment-edit-preview-" + id).show();
554 $("#comment-edit-form-" + id).serialize(),
558 $("#comment-edit-preview-" + id).html(data.preview);
559 $("#comment-edit-preview-" + id + " a").click(function() { return false; });
568 function showHideComments(id) {
569 if( $("#collapsed-comments-" + id).is(":visible")) {
570 $("#collapsed-comments-" + id).hide();
571 $("#hide-comments-" + id).html(window.showMore);
574 $("#collapsed-comments-" + id).show();
575 $("#hide-comments-" + id).html(window.showFewer);
576 collapseHeight("#collapsed-comments-" + id);
581 function preview_post() {
582 $("#jot-preview").val("1");
583 $("#jot-preview-content").show();
584 tinyMCE.triggerSave();
587 $("#profile-jot-form").serialize(),
590 $("#jot-preview-content").html(data.preview);
591 $("#jot-preview-content" + " a").click(function() { return false; });
596 $("#jot-preview").val("0");
602 // unpause auto reloads if they are currently stopped
605 $('#pause').html('');
610 // Converts the binary representation of data to hex
613 // discuss at: http://phpjs.org/functions/bin2hex
614 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
615 // + bugfixed by: Onno Marsman
616 // + bugfixed by: Linuxworld
617 // * example 1: bin2hex('Kev');
618 // * returns 1: '4b6576'
619 // * example 2: bin2hex(String.fromCharCode(0x00));
621 var v,i, f = 0, a = [];
625 for (i = 0; i<f; i++) {
626 a[i] = s.charCodeAt(i).toString(16).replace(/^([\da-f])$/,"0$1");
632 function groupChangeMember(gid, cid, sec_token) {
633 $('body .fakelink').css('cursor', 'wait');
634 $.get('group/' + gid + '/' + cid + "?t=" + sec_token, function(data) {
635 $('#group-update-wrapper').html(data);
636 $('body .fakelink').css('cursor', 'auto');
640 function profChangeMember(gid,cid) {
641 $('body .fakelink').css('cursor', 'wait');
642 $.get('profperm/' + gid + '/' + cid, function(data) {
643 $('#prof-update-wrapper').html(data);
644 $('body .fakelink').css('cursor', 'auto');
648 function contactgroupChangeMember(gid,cid) {
649 $('body').css('cursor', 'wait');
650 $.get('contactgroup/' + gid + '/' + cid, function(data) {
651 $('body').css('cursor', 'auto');
656 function checkboxhighlight(box) {
657 if($(box).is(':checked')) {
658 $(box).addClass('checkeditem');
661 $(box).removeClass('checkeditem');
665 function notifyMarkAll() {
666 $.get('notify/mark/all', function(data) {
667 if(timer) clearTimeout(timer);
668 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>');