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($j(listID).is(":visible")) {
15 $j(listID+"-wrapper").show();
19 $j(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 $j.ajaxSetup({cache: false});
51 msie = $j.browser.msie ;
55 /* setup tooltips *//*
56 $j("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 $j(".onoff input").each(function(){
71 id = $j(this).attr("id");
72 $j("#"+id+"_onoff ."+ (val==0?"on":"off")).addClass("hidden");
75 $j(".onoff > a").click(function(event){
76 event.preventDefault();
77 var input = $j(this).siblings("input");
78 var val = 1-input.val();
79 var id = input.attr("id");
80 $j("#"+id+"_onoff ."+ (val==0?"on":"off")).addClass("hidden");
81 $j("#"+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') !== $j(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 $j('a[rel^=#]').click(function(e){
103 close_last_popup_menu(e);
104 menu = $j( $j(this).attr('rel') );
108 if (menu.attr('popup')=="false") return false;
110 $j(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 = $j(this).parent();
122 $j('html').click(function(e) {
123 close_last_popup_menu(e);
127 $j("a.popupbox").colorbox({
129 'transition' : 'elastic'
133 /* notifications template */
134 var notifications_tpl= unescape($j("#nav-notifications-template[rel=template]").html());
135 var notifications_all = unescape($j('<div>').append( $j("#nav-notifications-see-all").clone() ).html()); //outerHtml hack
136 var notifications_mark = unescape($j('<div>').append( $j("#nav-notifications-mark-all").clone() ).html()); //outerHtml hack
137 var notifications_empty = unescape($j("#nav-notifications-menu").html());
139 /* nav update event */
140 $j('nav').bind('nav-update', function(e,data){;
141 var invalid = $j(data).find('invalid').text();
142 if(invalid == 1) { window.location.href=window.location.href }
144 var net = $j(data).find('net').text();
145 if(net == 0) { net = ''; $j('#net-update').removeClass('show') } else { $j('#net-update').addClass('show') }
146 $j('#net-update').html(net);
148 var home = $j(data).find('home').text();
149 if(home == 0) { home = ''; $j('#home-update').removeClass('show') } else { $j('#home-update').addClass('show') }
150 $j('#home-update').html(home);
152 var intro = $j(data).find('intro').text();
153 if(intro == 0) { intro = ''; $j('#intro-update').removeClass('show') } else { $j('#intro-update').addClass('show') }
154 $j('#intro-update').html(intro);
156 var mail = $j(data).find('mail').text();
157 if(mail == 0) { mail = ''; $j('#mail-update').removeClass('show') } else { $j('#mail-update').addClass('show') }
158 $j('#mail-update').html(mail);
160 var intro = $j(data).find('intro').text();
161 if(intro == 0) { intro = ''; $j('#intro-update-li').removeClass('show') } else { $j('#intro-update-li').addClass('show') }
162 $j('#intro-update-li').html(intro);
164 var mail = $j(data).find('mail').text();
165 if(mail == 0) { mail = ''; $j('#mail-update-li').removeClass('show') } else { $j('#mail-update-li').addClass('show') }
166 $j('#mail-update-li').html(mail);
168 var eNotif = $j(data).find('notif')
170 if (eNotif.children("note").length==0){
171 $j("#nav-notifications-menu").html(notifications_empty);
173 nnm = $j("#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 $j("img[data-src]", nnm).each(function(i, el){
184 // Add src attribute for images with a data-src attribute
185 $j(el).attr('src', $j(el).data("src"));
188 notif = eNotif.attr('count');
190 $j("#nav-notifications-linkmenu").addClass("on");
192 $j("#nav-notifications-linkmenu").removeClass("on");
194 if(notif == 0) { notif = ''; $j('#notify-update').removeClass('show') } else { $j('#notify-update').addClass('show') }
195 $j('#notify-update').html(notif);
197 var eSysmsg = $j(data).find('sysmsgs');
198 eSysmsg.children("notice").each(function(){
199 text = $j(this).text();
200 $j.jGrowl(text, { sticky: false, theme: 'notice', life: 3000 }); // originally: sticky: true,
202 eSysmsg.children("info").each(function(){
203 text = $j(this).text();
204 $j.jGrowl(text, { sticky: false, theme: 'info', life: 1000 });
211 // Allow folks to stop the ajax page updates with the pause/break key
212 $j(document).keydown(function(event) {
213 if(event.keyCode == '8') {
214 var target = event.target || event.srcElement;
215 if (!/input|textarea/i.test(target.nodeName)) {
219 if(event.keyCode == '19' || (event.ctrlKey && event.which == '32')) {
220 event.preventDefault();
221 if(stopped == false) {
226 $j('#pause').html('<img src="images/pause.gif" alt="pause" style="border: 1px solid black;" />');
240 function NavUpdate() {
243 var pingCmd = 'ping' + ((localUser != 0) ? '?f=&uid=' + localUser : '');
244 $j.get(pingCmd,function(data) {
245 $j(data).find('result').each(function() {
246 // send nav-update event
247 $j('nav').trigger('nav-update', this);
254 if($j('#live-network').length) { src = 'network'; liveUpdate(); }
255 if($j('#live-profile').length) { src = 'profile'; liveUpdate(); }
256 if($j('#live-community').length) { src = 'community'; liveUpdate(); }
257 if($j('#live-notes').length) { src = 'notes'; liveUpdate(); }
258 if($j('#live-display').length) { src = 'display'; liveUpdate(); }
259 /*if($j('#live-display').length) {
262 window.location.href=window.location.href
265 if($j('#live-photos').length) {
268 window.location.href=window.location.href
278 timer = setTimeout(NavUpdate,updateInterval);
281 function liveUpdate() {
282 if((src == null) || (stopped) || (typeof profile_uid == 'undefined') || (! profile_uid)) { $j('.like-rotator').hide(); return; }
283 if(($j('.comment-edit-text-full').length) || (in_progress)) {
285 clearTimeout(livetime);
287 livetime = setTimeout(liveUpdate, 10000);
293 prev = 'live-' + src;
296 var udargs = ((netargs.length) ? '/' + netargs : '');
297 var update_url = 'update_' + src + udargs + '&p=' + profile_uid + '&page=' + profile_page + '&msie=' + ((msie) ? 1 : 0);
299 $j.get(update_url,function(data) {
301 // $j('.collapsed-comments',data).each(function() {
302 // var ident = $j(this).attr('id');
303 // var is_hidden = $j('#' + ident).is(':hidden');
304 // if($j('#' + ident).length) {
305 // $j('#' + ident).replaceWith($j(this));
307 // $j('#' + ident).hide();
313 $j('.toplevel_item',data).each(function() {
314 var ident = $j(this).attr('id');
316 if($j('#' + ident).length == 0 && profile_page == 1) {
317 $j('img',this).each(function() {
318 $j(this).attr('src',$j(this).attr('dst'));
320 $j('#' + prev).after($j(this));
323 // Find out if the hidden comments are open, so we can keep it that way
324 // if a new comment has been posted
325 var id = $j('.hide-comments-total', this).attr('id');
326 if(typeof id != 'undefined') {
327 id = id.split('-')[3];
328 var commentsOpen = $j("#collapsed-comments-" + id).is(":visible");
331 $j('img',this).each(function() {
332 $j(this).attr('src',$j(this).attr('dst'));
334 //vScroll = $j(document).scrollTop();
335 $j('html').height($j('html').height());
336 $j('#' + ident).replaceWith($j(this));
338 if(typeof id != 'undefined') {
339 if(commentsOpen) showHideComments(id);
341 $j('html').height('auto');
342 //$j(document).scrollTop(vScroll);
345 // Add Colorbox for viewing Network page images
346 $j("#" + ident + " .wall-item-body a img").each(function(){
347 var aElem = $j(this).parent();
348 var imgHref = aElem.attr("href");
350 // We need to make sure we only put a Colorbox on links to Friendica images
351 // We'll try to do this by looking for links of the form
352 // .../photo/ab803d8eg08daf85023adfec08(-0.jpg) (with nothing more following), in hopes
353 // that that will be unique enough
354 if(imgHref.match(/\/photo\/[a-fA-F0-9]+(-[0-9]\.[\w]+?)?$/)) {
356 // Add a unique class to all the images of a certain post, to allow scrolling through
357 var cBoxClass = $j(this).closest(".wall-item-body").attr("id") + "-lightbox";
358 $j(this).addClass(cBoxClass);
371 // reset vars for inserting individual items
373 /*prev = 'live-' + src;
375 $j('.wall-item-outside-wrapper',data).each(function() {
376 var ident = $j(this).attr('id');
378 if($j('#' + ident).length == 0 && prev != 'live-' + src) {
379 $j('img',this).each(function() {
380 $j(this).attr('src',$j(this).attr('dst'));
382 $j('#' + prev).after($j(this));
385 $j('#' + ident + ' ' + '.wall-item-ago').replaceWith($j(this).find('.wall-item-ago'));
386 if($j('#' + ident + ' ' + '.comment-edit-text-empty').length)
387 $j('#' + ident + ' ' + '.wall-item-comment-wrapper').replaceWith($j(this).find('.wall-item-comment-wrapper'));
388 $j('#' + ident + ' ' + '.hide-comments-total').replaceWith($j(this).find('.hide-comments-total'));
389 $j('#' + ident + ' ' + '.wall-item-like').replaceWith($j(this).find('.wall-item-like'));
390 $j('#' + ident + ' ' + '.wall-item-dislike').replaceWith($j(this).find('.wall-item-dislike'));
391 $j('#' + ident + ' ' + '.my-comment-photo').each(function() {
392 $j(this).attr('src',$j(this).attr('dst'));
398 $j('.like-rotator').hide();
401 $j('body').css('cursor', 'auto');
403 /* autocomplete @nicknames */
404 $j(".comment-edit-form textarea").contact_autocomplete(baseurl+"/acl");
408 // setup videos, since VideoJS won't take care of any loaded via AJAX
413 function collapseHeight(elems) {
414 var elemName = '.wall-item-body:not(.divmore)';
415 if(typeof elems != 'undefined') {
416 elemName = elems + ' ' + elemName;
418 $j(elemName).each(function() {
419 if($j(this).height() > 450) {
420 $j('html').height($j('html').height());
421 $j(this).divgrow({ initialHeight: 400, showBrackets: false, speed: 0 });
422 $j(this).addClass('divmore');
423 $j('html').height('auto');
428 /*function imgbright(node) {
429 $j(node).removeClass("drophide").addClass("drop");
432 function imgdull(node) {
433 $j(node).removeClass("drop").addClass("drophide");
436 // Since our ajax calls are asynchronous, we will give a few
437 // seconds for the first ajax call (setting like/dislike), then
438 // run the updater to pick up any changes and display on the page.
439 // The updater will turn any rotators off when it's done.
440 // This function will have returned long before any of these
441 // events have completed and therefore there won't be any
442 // visible feedback that anything changed without all this
443 // trickery. This still could cause confusion if the "like" ajax call
444 // is delayed and NavUpdate runs before it completes.
446 function dolike(ident,verb) {
448 $j('#like-rotator-' + ident.toString()).show();
449 $j.get('like/' + ident.toString() + '?verb=' + verb, NavUpdate );
453 function dostar(ident) {
454 ident = ident.toString();
455 // $j('#like-rotator-' + ident).show();
456 $j.get('starred/' + ident, function(data) {
457 if(data.match(/1/)) {
458 $j('#starred-' + ident).addClass('starred');
459 $j('#starred-' + ident).removeClass('unstarred');
460 $j('#star-' + ident).addClass('hidden');
461 $j('#unstar-' + ident).removeClass('hidden');
464 $j('#starred-' + ident).addClass('unstarred');
465 $j('#starred-' + ident).removeClass('starred');
466 $j('#star-' + ident).removeClass('hidden');
467 $j('#unstar-' + ident).addClass('hidden');
469 // $j('#like-rotator-' + ident).hide();
473 function getPosition(e) {
474 var cursor = {x:0, y:0};
475 if ( e.pageX || e.pageY ) {
480 if( e.clientX || e.clientY ) {
481 cursor.x = e.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft) - document.documentElement.clientLeft;
482 cursor.y = e.clientY + (document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop;
494 var lockvisible = false;
496 function lockview(event,id) {
497 event = event || window.event;
498 cursor = getPosition(event);
504 $j.get('lockview/' + id, function(data) {
505 $j('#panel').html(data);
506 $j('#panel').css({ 'left': cursor.x + 5 , 'top': cursor.y + 5});
512 function lockviewhide() {
517 function post_comment(id) {
520 $j('body').css('cursor', 'wait');
521 $j("#comment-preview-inp-" + id).val("0");
524 $j("#comment-edit-form-" + id).serialize(),
527 $j("#comment-edit-wrapper-" + id).hide();
528 $j("#comment-edit-text-" + id).val('');
529 var tarea = document.getElementById("comment-edit-text-" + id);
531 commentClose(tarea,id);
532 if(timer) clearTimeout(timer);
533 timer = setTimeout(NavUpdate,10);
536 window.location.href=data.reload;
545 function preview_comment(id) {
546 $j("#comment-preview-inp-" + id).val("1");
547 $j("#comment-edit-preview-" + id).show();
550 $j("#comment-edit-form-" + id).serialize(),
554 $j("#comment-edit-preview-" + id).html(data.preview);
555 $j("#comment-edit-preview-" + id + " a").click(function() { return false; });
564 function showHideComments(id) {
565 if( $j("#collapsed-comments-" + id).is(":visible")) {
566 $j("#collapsed-comments-" + id).hide();
567 $j("#hide-comments-" + id).html(window.showMore);
570 $j("#collapsed-comments-" + id).show();
571 $j("#hide-comments-" + id).html(window.showFewer);
572 collapseHeight("#collapsed-comments-" + id);
577 function preview_post() {
578 $j("#jot-preview").val("1");
579 $j("#jot-preview-content").show();
580 tinyMCE.triggerSave();
583 $j("#profile-jot-form").serialize(),
586 $j("#jot-preview-content").html(data.preview);
587 $j("#jot-preview-content" + " a").click(function() { return false; });
592 $j("#jot-preview").val("0");
598 // unpause auto reloads if they are currently stopped
601 $j('#pause').html('');
606 // Converts the binary representation of data to hex
609 // discuss at: http://phpjs.org/functions/bin2hex
610 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
611 // + bugfixed by: Onno Marsman
612 // + bugfixed by: Linuxworld
613 // * example 1: bin2hex('Kev');
614 // * returns 1: '4b6576'
615 // * example 2: bin2hex(String.fromCharCode(0x00));
617 var v,i, f = 0, a = [];
621 for (i = 0; i<f; i++) {
622 a[i] = s.charCodeAt(i).toString(16).replace(/^([\da-f])$/,"0$1");
628 function groupChangeMember(gid, cid, sec_token) {
629 $j('body .fakelink').css('cursor', 'wait');
630 $j.get('group/' + gid + '/' + cid + "?t=" + sec_token, function(data) {
631 $j('#group-update-wrapper').html(data);
632 $j('body .fakelink').css('cursor', 'auto');
636 function profChangeMember(gid,cid) {
637 $j('body .fakelink').css('cursor', 'wait');
638 $j.get('profperm/' + gid + '/' + cid, function(data) {
639 $j('#prof-update-wrapper').html(data);
640 $j('body .fakelink').css('cursor', 'auto');
644 function contactgroupChangeMember(gid,cid) {
645 $j('body').css('cursor', 'wait');
646 $j.get('contactgroup/' + gid + '/' + cid, function(data) {
647 $j('body').css('cursor', 'auto');
652 function checkboxhighlight(box) {
653 if($j(box).is(':checked')) {
654 $j(box).addClass('checkeditem');
657 $j(box).removeClass('checkeditem');
661 function notifyMarkAll() {
662 $j.get('notify/mark/all', function(data) {
663 if(timer) clearTimeout(timer);
664 timer = setTimeout(NavUpdate,1000);
669 // code from http://www.tinymce.com/wiki.php/How-to_implement_a_custom_file_browser
670 function fcFileBrowser (field_name, url, type, win) {
671 /* TODO: If you work with sessions in PHP and your client doesn't accept cookies you might need to carry
672 the session name and session ID in the request string (can look like this: "?PHPSESSID=88p0n70s9dsknra96qhuk6etm5").
673 These lines of code extract the necessary parameters and add them back to the filebrowser URL again. */
676 var cmsURL = baseurl+"/fbrowser/"+type+"/";
678 tinyMCE.activeEditor.windowManager.open({
680 title : 'File Browser',
681 width : 420, // Your dimensions may differ - toy around with them!
684 inline : "yes", // This parameter only has an effect if you use the inlinepopups plugin!
685 close_previous : "no"
693 /*function setupFieldRichtext(){
696 mode : "specific_textareas",
697 editor_selector: "fieldRichtext",
698 plugins : "bbcode,paste, inlinepopups",
699 theme_advanced_buttons1 : "bold,italic,underline,undo,redo,link,unlink,image,forecolor,formatselect,code",
700 theme_advanced_buttons2 : "",
701 theme_advanced_buttons3 : "",
702 theme_advanced_toolbar_location : "top",
703 theme_advanced_toolbar_align : "center",
704 theme_advanced_blockformats : "blockquote,code",
705 paste_text_sticky : true,
706 entity_encoding : "raw",
707 add_unload_trigger : false,
708 remove_linebreaks : false,
709 //force_p_newlines : false,
710 //force_br_newlines : true,
711 forced_root_block : 'div',
713 content_css: baseurl+"/view/custom_tinymce.css",
714 theme_advanced_path : false,
715 file_browser_callback : "fcFileBrowser",
721 * sprintf in javascript
722 * "{0} and {1}".format('zero','uno');
724 String.prototype.format = function() {
725 var formatted = this;
726 for (var i = 0; i < arguments.length; i++) {
727 var regexp = new RegExp('\\{'+i+'\\}', 'gi');
728 formatted = formatted.replace(regexp, arguments[i]);
733 Array.prototype.remove = function(item) {
734 to=undefined; from=this.indexOf(item);
735 var rest = this.slice((to || from) + 1 || this.length);
736 this.length = from < 0 ? this.length + from : from;
737 return this.push.apply(this, rest);
740 function previewTheme(elm) {
741 theme = $j(elm).val();
742 $j.getJSON('pretheme?f=&theme=' + theme,function(data) {
743 $j('#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>');