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 last_popup_button.removeClass("selected");
93 last_popup_menu = null;
94 last_popup_button = null;
98 $('a[rel^=#]').click(function(e){
100 close_last_popup_menu(e);
101 menu = $( $(this).attr('rel') );
105 if (menu.attr('popup')=="false") return false;
107 $(this).parent().toggleClass("selected");
108 menu.slideToggle('fast');
110 if (menu.css("display") == "none") {
111 last_popup_menu = null;
112 last_popup_button = null;
114 last_popup_menu = menu;
115 last_popup_button = $(this).parent();
119 $('html').click(function(e) {
120 close_last_popup_menu(e);
124 $("a.popupbox").colorbox({
126 'transition' : 'elastic'
130 /* notifications template */
131 var notifications_tpl= unescape($("#nav-notifications-template[rel=template]").html());
132 var notifications_all = unescape($('<div>').append( $("#nav-notifications-see-all").clone() ).html()); //outerHtml hack
133 var notifications_mark = unescape($('<div>').append( $("#nav-notifications-mark-all").clone() ).html()); //outerHtml hack
134 var notifications_empty = unescape($("#nav-notifications-menu").html());
136 /* nav update event */
137 $('nav').bind('nav-update', function(e,data){;
138 var invalid = $(data).find('invalid').text();
139 if(invalid == 1) { window.location.href=window.location.href }
141 var net = $(data).find('net').text();
142 if(net == 0) { net = ''; $('#net-update').removeClass('show') } else { $('#net-update').addClass('show') }
143 $('#net-update').html(net);
145 var home = $(data).find('home').text();
146 if(home == 0) { home = ''; $('#home-update').removeClass('show') } else { $('#home-update').addClass('show') }
147 $('#home-update').html(home);
149 var intro = $(data).find('intro').text();
150 if(intro == 0) { intro = ''; $('#intro-update').removeClass('show') } else { $('#intro-update').addClass('show') }
151 $('#intro-update').html(intro);
153 var mail = $(data).find('mail').text();
154 if(mail == 0) { mail = ''; $('#mail-update').removeClass('show') } else { $('#mail-update').addClass('show') }
155 $('#mail-update').html(mail);
157 var intro = $(data).find('intro').text();
158 if(intro == 0) { intro = ''; $('#intro-update-li').removeClass('show') } else { $('#intro-update-li').addClass('show') }
159 $('#intro-update-li').html(intro);
161 var mail = $(data).find('mail').text();
162 if(mail == 0) { mail = ''; $('#mail-update-li').removeClass('show') } else { $('#mail-update-li').addClass('show') }
163 $('#mail-update-li').html(mail);
165 var eNotif = $(data).find('notif')
167 if (eNotif.children("note").length==0){
168 $("#nav-notifications-menu").html(notifications_empty);
170 nnm = $("#nav-notifications-menu");
171 nnm.html(notifications_all + notifications_mark);
172 //nnm.attr('popup','true');
173 eNotif.children("note").each(function(){
175 text = e.text().format("<span class='contactname'>"+e.attr('name')+"</span>");
176 html = notifications_tpl.format(e.attr('href'),e.attr('photo'), text, e.attr('date'), e.attr('seen'));
180 $("img[data-src]", nnm).each(function(i, el){
181 // Add src attribute for images with a data-src attribute
182 // However, don't bother if the data-src attribute is empty, because
183 // an empty "src" tag for an image will cause some browsers
184 // to prefetch the root page of the Friendica hub, which will
185 // unnecessarily load an entire profile/ or network/ page
186 if($(el).data("src") != '') $(el).attr('src', $(el).data("src"));
189 notif = eNotif.attr('count');
191 $("#nav-notifications-linkmenu").addClass("on");
193 $("#nav-notifications-linkmenu").removeClass("on");
195 if(notif == 0) { notif = ''; $('#notify-update').removeClass('show') } else { $('#notify-update').addClass('show') }
196 $('#notify-update').html(notif);
198 var eSysmsg = $(data).find('sysmsgs');
199 eSysmsg.children("notice").each(function(){
200 text = $(this).text();
201 $.jGrowl(text, { sticky: false, theme: 'notice', life: 3000 }); // originally: sticky: true,
203 eSysmsg.children("info").each(function(){
204 text = $(this).text();
205 $.jGrowl(text, { sticky: false, theme: 'info', life: 1000 });
212 // Allow folks to stop the ajax page updates with the pause/break key
213 $(document).keydown(function(event) {
214 if(event.keyCode == '8') {
215 var target = event.target || event.srcElement;
216 if (!/input|textarea/i.test(target.nodeName)) {
220 if(event.keyCode == '19' || (event.ctrlKey && event.which == '32')) {
221 event.preventDefault();
222 if(stopped == false) {
227 $('#pause').html('<img src="images/pause.gif" alt="pause" style="border: 1px solid black;" />');
241 function NavUpdate() {
244 var pingCmd = 'ping' + ((localUser != 0) ? '?f=&uid=' + localUser : '');
245 $.get(pingCmd,function(data) {
246 $(data).find('result').each(function() {
247 // send nav-update event
248 $('nav').trigger('nav-update', this);
255 if($('#live-network').length) { src = 'network'; liveUpdate(); }
256 if($('#live-profile').length) { src = 'profile'; liveUpdate(); }
257 if($('#live-community').length) { src = 'community'; liveUpdate(); }
258 if($('#live-notes').length) { src = 'notes'; liveUpdate(); }
259 if($('#live-display').length) { src = 'display'; liveUpdate(); }
260 /*if($('#live-display').length) {
263 window.location.href=window.location.href
266 if($('#live-photos').length) {
269 window.location.href=window.location.href
279 timer = setTimeout(NavUpdate,updateInterval);
282 function liveUpdate() {
283 if((src == null) || (stopped) || (typeof profile_uid == 'undefined') || (! profile_uid)) { $('.like-rotator').hide(); return; }
284 if(($('.comment-edit-text-full').length) || (in_progress)) {
286 clearTimeout(livetime);
288 livetime = setTimeout(liveUpdate, 5000);
294 prev = 'live-' + src;
297 var udargs = ((netargs.length) ? '/' + netargs : '');
298 var update_url = 'update_' + src + udargs + '&p=' + profile_uid + '&page=' + profile_page;
300 $.get(update_url,function(data) {
302 // $('.collapsed-comments',data).each(function() {
303 // var ident = $(this).attr('id');
304 // var is_hidden = $('#' + ident).is(':hidden');
305 // if($('#' + ident).length) {
306 // $('#' + ident).replaceWith($(this));
308 // $('#' + ident).hide();
314 $('.toplevel_item',data).each(function() {
315 var ident = $(this).attr('id');
317 if($('#' + ident).length == 0 && profile_page == 1) {
318 $('img',this).each(function() {
319 $(this).attr('src',$(this).attr('dst'));
321 $('#' + prev).after($(this));
324 // Find out if the hidden comments are open, so we can keep it that way
325 // if a new comment has been posted
326 var id = $('.hide-comments-total', this).attr('id');
327 if(typeof id != 'undefined') {
328 id = id.split('-')[3];
329 var commentsOpen = $("#collapsed-comments-" + id).is(":visible");
332 $('img',this).each(function() {
333 $(this).attr('src',$(this).attr('dst'));
335 //vScroll = $(document).scrollTop();
336 $('html').height($('html').height());
337 $('#' + ident).replaceWith($(this));
339 if(typeof id != 'undefined') {
340 if(commentsOpen) showHideComments(id);
342 $('html').height('auto');
343 //$(document).scrollTop(vScroll);
346 // Add Colorbox for viewing Network page images
347 $("#" + ident + " .wall-item-body a img").each(function(){
348 var aElem = $(this).parent();
349 var imgHref = aElem.attr("href");
351 // We need to make sure we only put a Colorbox on links to Friendica images
352 // We'll try to do this by looking for links of the form
353 // .../photo/ab803d8eg08daf85023adfec08(-0.jpg) (with nothing more following), in hopes
354 // that that will be unique enough
355 if(imgHref.match(/\/photo\/[a-fA-F0-9]+(-[0-9]\.[\w]+?)?$/)) {
357 // Add a unique class to all the images of a certain post, to allow scrolling through
358 var cBoxClass = $(this).closest(".wall-item-body").attr("id") + "-lightbox";
359 $(this).addClass(cBoxClass);
372 // reset vars for inserting individual items
374 /*prev = 'live-' + src;
376 $('.wall-item-outside-wrapper',data).each(function() {
377 var ident = $(this).attr('id');
379 if($('#' + ident).length == 0 && prev != 'live-' + src) {
380 $('img',this).each(function() {
381 $(this).attr('src',$(this).attr('dst'));
383 $('#' + prev).after($(this));
386 $('#' + ident + ' ' + '.wall-item-ago').replaceWith($(this).find('.wall-item-ago'));
387 if($('#' + ident + ' ' + '.comment-edit-text-empty').length)
388 $('#' + ident + ' ' + '.wall-item-comment-wrapper').replaceWith($(this).find('.wall-item-comment-wrapper'));
389 $('#' + ident + ' ' + '.hide-comments-total').replaceWith($(this).find('.hide-comments-total'));
390 $('#' + ident + ' ' + '.wall-item-like').replaceWith($(this).find('.wall-item-like'));
391 $('#' + ident + ' ' + '.wall-item-dislike').replaceWith($(this).find('.wall-item-dislike'));
392 $('#' + ident + ' ' + '.my-comment-photo').each(function() {
393 $(this).attr('src',$(this).attr('dst'));
399 $('.like-rotator').hide();
402 $('body').css('cursor', 'auto');
404 /* autocomplete @nicknames */
405 $(".comment-edit-form textarea").editor_autocomplete(baseurl+"/acl");
409 // setup videos, since VideoJS won't take care of any loaded via AJAX
410 if(typeof videojs != 'undefined') videojs.autoSetup();
414 function collapseHeight(elems) {
415 var elemName = '.wall-item-body:not(.divmore)';
416 if(typeof elems != 'undefined') {
417 elemName = elems + ' ' + elemName;
419 $(elemName).each(function() {
420 if($(this).height() > 450) {
421 $('html').height($('html').height());
422 $(this).divgrow({ initialHeight: 400, showBrackets: false, speed: 0 });
423 $(this).addClass('divmore');
424 $('html').height('auto');
429 /*function imgbright(node) {
430 $(node).removeClass("drophide").addClass("drop");
433 function imgdull(node) {
434 $(node).removeClass("drop").addClass("drophide");
437 // Since our ajax calls are asynchronous, we will give a few
438 // seconds for the first ajax call (setting like/dislike), then
439 // run the updater to pick up any changes and display on the page.
440 // The updater will turn any rotators off when it's done.
441 // This function will have returned long before any of these
442 // events have completed and therefore there won't be any
443 // visible feedback that anything changed without all this
444 // trickery. This still could cause confusion if the "like" ajax call
445 // is delayed and NavUpdate runs before it completes.
447 function dolike(ident,verb) {
449 $('#like-rotator-' + ident.toString()).show();
450 $.get('like/' + ident.toString() + '?verb=' + verb, NavUpdate );
454 function dostar(ident) {
455 ident = ident.toString();
456 // $('#like-rotator-' + ident).show();
457 $.get('starred/' + ident, function(data) {
458 if(data.match(/1/)) {
459 $('#starred-' + ident).addClass('starred');
460 $('#starred-' + ident).removeClass('unstarred');
461 $('#star-' + ident).addClass('hidden');
462 $('#unstar-' + ident).removeClass('hidden');
465 $('#starred-' + ident).addClass('unstarred');
466 $('#starred-' + ident).removeClass('starred');
467 $('#star-' + ident).removeClass('hidden');
468 $('#unstar-' + 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);
537 window.location.href=data.reload;
546 function preview_comment(id) {
547 $("#comment-preview-inp-" + id).val("1");
548 $("#comment-edit-preview-" + id).show();
551 $("#comment-edit-form-" + id).serialize(),
555 $("#comment-edit-preview-" + id).html(data.preview);
556 $("#comment-edit-preview-" + id + " a").click(function() { return false; });
565 function showHideComments(id) {
566 if( $("#collapsed-comments-" + id).is(":visible")) {
567 $("#collapsed-comments-" + id).hide();
568 $("#hide-comments-" + id).html(window.showMore);
571 $("#collapsed-comments-" + id).show();
572 $("#hide-comments-" + id).html(window.showFewer);
573 collapseHeight("#collapsed-comments-" + id);
578 function preview_post() {
579 $("#jot-preview").val("1");
580 $("#jot-preview-content").show();
581 tinyMCE.triggerSave();
584 $("#profile-jot-form").serialize(),
587 $("#jot-preview-content").html(data.preview);
588 $("#jot-preview-content" + " a").click(function() { return false; });
593 $("#jot-preview").val("0");
599 // unpause auto reloads if they are currently stopped
602 $('#pause').html('');
607 // Converts the binary representation of data to hex
610 // discuss at: http://phpjs.org/functions/bin2hex
611 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
612 // + bugfixed by: Onno Marsman
613 // + bugfixed by: Linuxworld
614 // * example 1: bin2hex('Kev');
615 // * returns 1: '4b6576'
616 // * example 2: bin2hex(String.fromCharCode(0x00));
618 var v,i, f = 0, a = [];
622 for (i = 0; i<f; i++) {
623 a[i] = s.charCodeAt(i).toString(16).replace(/^([\da-f])$/,"0$1");
629 function groupChangeMember(gid, cid, sec_token) {
630 $('body .fakelink').css('cursor', 'wait');
631 $.get('group/' + gid + '/' + cid + "?t=" + sec_token, function(data) {
632 $('#group-update-wrapper').html(data);
633 $('body .fakelink').css('cursor', 'auto');
637 function profChangeMember(gid,cid) {
638 $('body .fakelink').css('cursor', 'wait');
639 $.get('profperm/' + gid + '/' + cid, function(data) {
640 $('#prof-update-wrapper').html(data);
641 $('body .fakelink').css('cursor', 'auto');
645 function contactgroupChangeMember(gid,cid) {
646 $('body').css('cursor', 'wait');
647 $.get('contactgroup/' + gid + '/' + cid, function(data) {
648 $('body').css('cursor', 'auto');
653 function checkboxhighlight(box) {
654 if($(box).is(':checked')) {
655 $(box).addClass('checkeditem');
658 $(box).removeClass('checkeditem');
662 function notifyMarkAll() {
663 $.get('notify/mark/all', function(data) {
664 if(timer) clearTimeout(timer);
665 timer = setTimeout(NavUpdate,1000);
670 // code from http://www.tinymce.com/wiki.php/How-to_implement_a_custom_file_browser
671 function fcFileBrowser (field_name, url, type, win) {
672 /* TODO: If you work with sessions in PHP and your client doesn't accept cookies you might need to carry
673 the session name and session ID in the request string (can look like this: "?PHPSESSID=88p0n70s9dsknra96qhuk6etm5").
674 These lines of code extract the necessary parameters and add them back to the filebrowser URL again. */
677 var cmsURL = baseurl+"/fbrowser/"+type+"/";
679 tinyMCE.activeEditor.windowManager.open({
681 title : 'File Browser',
682 width : 420, // Your dimensions may differ - toy around with them!
685 inline : "yes", // This parameter only has an effect if you use the inlinepopups plugin!
686 close_previous : "no"
694 /*function setupFieldRichtext(){
697 mode : "specific_textareas",
698 editor_selector: "fieldRichtext",
699 plugins : "bbcode,paste, inlinepopups",
700 theme_advanced_buttons1 : "bold,italic,underline,undo,redo,link,unlink,image,forecolor,formatselect,code",
701 theme_advanced_buttons2 : "",
702 theme_advanced_buttons3 : "",
703 theme_advanced_toolbar_location : "top",
704 theme_advanced_toolbar_align : "center",
705 theme_advanced_blockformats : "blockquote,code",
706 paste_text_sticky : true,
707 entity_encoding : "raw",
708 add_unload_trigger : false,
709 remove_linebreaks : false,
710 //force_p_newlines : false,
711 //force_br_newlines : true,
712 forced_root_block : 'div',
714 content_css: baseurl+"/view/custom_tinymce.css",
715 theme_advanced_path : false,
716 file_browser_callback : "fcFileBrowser",
722 * sprintf in javascript
723 * "{0} and {1}".format('zero','uno');
725 String.prototype.format = function() {
726 var formatted = this;
727 for (var i = 0; i < arguments.length; i++) {
728 var regexp = new RegExp('\\{'+i+'\\}', 'gi');
729 formatted = formatted.replace(regexp, arguments[i]);
734 Array.prototype.remove = function(item) {
735 to=undefined; from=this.indexOf(item);
736 var rest = this.slice((to || from) + 1 || this.length);
737 this.length = from < 0 ? this.length + from : from;
738 return this.push.apply(this, rest);
741 function previewTheme(elm) {
742 theme = $(elm).val();
743 $.getJSON('pretheme?f=&theme=' + theme,function(data) {
744 $('#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>');