1 function resizeIframe(obj) {
2 //obj.style.height = 0;
6 function _resizeIframe(obj, desth) {
7 var h = obj.style.height;
8 var ch = obj.contentWindow.document.body.scrollHeight + 'px';
12 //console.log("_resizeIframe", obj, desth, ch);
14 setTimeout(_resizeIframe, 500, obj, ch);
16 if (ch>0) obj.style.height = ch;
17 setTimeout(_resizeIframe, 1000, obj, ch);
21 function openClose(theID) {
22 if(document.getElementById(theID).style.display == "block") {
23 document.getElementById(theID).style.display = "none"
26 document.getElementById(theID).style.display = "block"
30 function openMenu(theID) {
31 document.getElementById(theID).style.display = "block"
34 function closeMenu(theID) {
35 document.getElementById(theID).style.display = "none"
38 function decodeHtml(html) {
39 var txt = document.createElement("textarea");
48 var force_update = false;
50 var totStopped = false;
54 var in_progress = false;
55 var langSelect = false;
56 var commentBusy = false;
57 var last_popup_menu = null;
58 var last_popup_button = null;
59 var lockLoadContent = false;
62 $.ajaxSetup({cache: false});
64 /* setup tooltips *//*
65 $("a,.tt").each(function(){
68 if (e.hasClass("tttop")) pos="top";
69 if (e.hasClass("ttbottom")) pos="bottom";
70 if (e.hasClass("ttleft")) pos="left";
71 if (e.hasClass("ttright")) pos="right";
72 e.tipTip({defaultPosition: pos, edgeOffset: 8});
75 /* setup comment textarea buttons */
76 /* comment textarea buttons needs some "data-*" attributes to work:
77 * data-role="insert-formatting" : to mark the element as a formatting button
78 * data-comment="<string>" : string for "Comment", used by insertFormatting() function
79 * data-bbcode="<string>" : name of the bbcode element to insert. insertFormatting() will insert it as "[name][/name]"
80 * data-id="<string>" : id of the comment, used to find other comment-related element, like the textarea
82 $('body').on('click','[data-role="insert-formatting"]', function(e) {
85 var comment = o.data('comment');
86 var bbcode = o.data('bbcode');
87 var id = o.data('id');
89 Dialog.doImageBrowser("comment", id);
92 insertFormatting(comment, bbcode, id);
95 /* event from comment textarea button popups */
96 /* insert returned bbcode at cursor position or replace selected text */
97 $("body").on("fbrowser.image.comment", function(e, filename, bbcode, id) {
98 console.log("on", id);
100 var textarea = document.getElementById("comment-edit-text-" +id);
101 var start = textarea.selectionStart;
102 var end = textarea.selectionEnd;
103 textarea.value = textarea.value.substring(0, start) + bbcode + textarea.value.substring(end, textarea.value.length);
108 /* setup onoff widgets */
109 $(".onoff input").each(function(){
111 id = $(this).attr("id");
112 $("#"+id+"_onoff ."+ (val==0?"on":"off")).addClass("hidden");
115 $(".onoff > a").click(function(event){
116 event.preventDefault();
117 var input = $(this).siblings("input");
118 var val = 1-input.val();
119 var id = input.attr("id");
120 $("#"+id+"_onoff ."+ (val==0?"on":"off")).addClass("hidden");
121 $("#"+id+"_onoff ."+ (val==1?"on":"off")).removeClass("hidden");
126 /* setup field_richtext */
127 setupFieldRichtext();
130 function close_last_popup_menu() {
131 if(last_popup_menu) {
132 last_popup_menu.hide();
133 last_popup_button.removeClass("selected");
134 last_popup_menu = null;
135 last_popup_button = null;
138 $('a[rel^=#]').click(function(e){
140 var parent = $(this).parent();
141 var isSelected = (last_popup_button && parent.attr('id') == last_popup_button.attr('id'));
142 close_last_popup_menu();
143 if(isSelected) return false;
144 menu = $( $(this).attr('rel') );
147 if (menu.attr('popup')=="false") return false;
148 parent.toggleClass("selected");
150 if (menu.css("display") == "none") {
151 last_popup_menu = null;
152 last_popup_button = null;
154 last_popup_menu = menu;
155 last_popup_button = parent;
156 $('#nav-notifications-menu').perfectScrollbar('update');
160 $('html').click(function() {
161 close_last_popup_menu();
165 $("a.popupbox").colorbox({
167 'transition' : 'elastic'
169 $("a.ajax-popupbox").colorbox({
170 'transition' : 'elastic'
173 /* notifications template */
174 var notifications_tpl= unescape($("#nav-notifications-template[rel=template]").html());
175 var notifications_all = unescape($('<div>').append( $("#nav-notifications-see-all").clone() ).html()); //outerHtml hack
176 var notifications_mark = unescape($('<div>').append( $("#nav-notifications-mark-all").clone() ).html()); //outerHtml hack
177 var notifications_empty = unescape($("#nav-notifications-menu").html());
179 /* enable perfect-scrollbars for different elements */
180 $('#nav-notifications-menu, aside').perfectScrollbar();
182 /* nav update event */
183 $('nav').bind('nav-update', function(e,data){
184 var invalid = $(data).find('invalid').text();
185 if(invalid == 1) { window.location.href=window.location.href }
187 var net = $(data).find('net').text();
188 if(net == 0) { net = ''; $('#net-update').removeClass('show') } else { $('#net-update').addClass('show') }
189 $('#net-update').html(net);
191 var home = $(data).find('home').text();
192 if(home == 0) { home = ''; $('#home-update').removeClass('show') } else { $('#home-update').addClass('show') }
193 $('#home-update').html(home);
195 var intro = $(data).find('intro').text();
196 if(intro == 0) { intro = ''; $('#intro-update').removeClass('show') } else { $('#intro-update').addClass('show') }
197 $('#intro-update').html(intro);
199 var mail = $(data).find('mail').text();
200 if(mail == 0) { mail = ''; $('#mail-update').removeClass('show') } else { $('#mail-update').addClass('show') }
201 $('#mail-update').html(mail);
203 var intro = $(data).find('intro').text();
204 if(intro == 0) { intro = ''; $('#intro-update-li').removeClass('show') } else { $('#intro-update-li').addClass('show') }
205 $('#intro-update-li').html(intro);
207 var mail = $(data).find('mail').text();
208 if(mail == 0) { mail = ''; $('#mail-update-li').removeClass('show') } else { $('#mail-update-li').addClass('show') }
209 $('#mail-update-li').html(mail);
212 var allevents = $(data).find('all-events').text();
213 if(allevents == 0) { allevents = ''; $('#allevents-update').removeClass('show') } else { $('#allevents-update').addClass('show') }
214 $('#allevents-update').html(allevents);
216 var alleventstoday = $(data).find('all-events-today').text();
217 if(alleventstoday == 0) { $('#allevents-update').removeClass('notif-allevents-today') } else { $('#allevents-update').addClass('notif-allevents-today') }
219 var events = $(data).find('events').text();
220 if(events == 0) { events = ''; $('#events-update').removeClass('show') } else { $('#events-update').addClass('show') }
221 $('#events-update').html(events);
223 var eventstoday = $(data).find('events-today').text();
224 if(eventstoday == 0) { $('#events-update').removeClass('notif-events-today') } else { $('#events-update').addClass('notif-events-today') }
226 var birthdays = $(data).find('birthdays').text();
227 if(birthdays == 0) {birthdays = ''; $('#birthdays-update').removeClass('show') } else { $('#birthdays-update').addClass('show') }
228 $('#birthdays-update').html(birthdays);
230 var birthdaystoday = $(data).find('birthdays-today').text();
231 if(birthdaystoday == 0) { $('#birthdays-update').removeClass('notif-birthdays-today') } else { $('#birthdays-update').addClass('notif-birthdays-today') }
233 $(".sidebar-group-li .notify").removeClass("show");
234 $(data).find("group").each(function() {
236 var gcount = this.innerHTML;
237 $(".group-"+gid+" .notify").addClass("show").text(gcount);
240 $(".forum-widget-entry .notify").removeClass("show");
241 $(data).find("forum").each(function() {
243 var fcount = this.innerHTML;
244 $(".forum-"+fid+" .notify").addClass("show").text(fcount);
248 var eNotif = $(data).find('notif')
250 if (eNotif.children("note").length==0){
251 $("#nav-notifications-menu").html(notifications_empty);
253 nnm = $("#nav-notifications-menu");
254 nnm.html(notifications_all + notifications_mark);
255 //nnm.attr('popup','true');
257 var notification_lastitem = parseInt(localStorage.getItem("notification-lastitem"));
258 var notification_id = 0;
259 eNotif.children("note").each(function(){
261 var text = e.text().format("<span class='contactname'>"+e.attr('name')+"</span>");
262 var contact = ("<a href="+e.attr('url')+"><span class='contactname'>"+e.attr('name')+"</span></a>");
263 var seenclass = (e.attr('seen')==1)?"notify-seen":"notify-unseen";
264 var html = notifications_tpl.format(
265 e.attr('href'), // {0} // link to the source
266 e.attr('photo'), // {1} // photo of the contact
267 text, // {2} // preformatet text (autor + text)
268 e.attr('date'), // {3} // date of notification (time ago)
269 seenclass, // {4} // vistiting status of the notification
270 new Date(e.attr('timestamp')*1000), // {5} //date of notification
271 e.attr('url'), // {6} // profile url of the contact
272 e.text().format(""), // {7} // clean status text
273 contact // {8} //preformatat author (name + profile url)
277 $(eNotif.children("note").get().reverse()).each(function(){
279 notification_id = parseInt(e.attr('timestamp'));
280 if (notification_lastitem!== null && notification_id > notification_lastitem) {
281 if (getNotificationPermission()==="granted") {
282 var notification = new Notification(document.title, {
283 body: decodeHtml(e.text().replace('→ ','').format(e.attr('name'))),
284 icon: e.attr('photo'),
286 notification['url'] = e.attr('href');
287 notification.addEventListener("click", function(ev){
288 window.location = ev.target.url;
294 notification_lastitem = notification_id;
295 localStorage.setItem("notification-lastitem", notification_lastitem)
297 $("img[data-src]", nnm).each(function(i, el){
298 // Add src attribute for images with a data-src attribute
299 // However, don't bother if the data-src attribute is empty, because
300 // an empty "src" tag for an image will cause some browsers
301 // to prefetch the root page of the Friendica hub, which will
302 // unnecessarily load an entire profile/ or network/ page
303 if($(el).data("src") != '') $(el).attr('src', $(el).data("src"));
307 notif = eNotif.attr('count');
309 $("#nav-notifications-linkmenu").addClass("on");
311 $("#nav-notifications-linkmenu").removeClass("on");
313 if(notif == 0) { notif = ''; $('#notify-update').removeClass('show') } else { $('#notify-update').addClass('show') }
314 $('#notify-update').html(notif);
316 var eSysmsg = $(data).find('sysmsgs');
317 eSysmsg.children("notice").each(function(){
318 text = $(this).text();
319 $.jGrowl(text, { sticky: true, theme: 'notice' });
321 eSysmsg.children("info").each(function(){
322 text = $(this).text();
323 $.jGrowl(text, { sticky: false, theme: 'info', life: 5000 });
326 /* update the js scrollbars */
327 $('#nav-notifications-menu').perfectScrollbar('update');
332 // Allow folks to stop the ajax page updates with the pause/break key
333 $(document).keydown(function(event) {
334 if(event.keyCode == '8') {
335 var target = event.target || event.srcElement;
336 if (!/input|textarea/i.test(target.nodeName)) {
340 if(event.keyCode == '19' || (event.ctrlKey && event.which == '32')) {
341 event.preventDefault();
342 if(stopped == false) {
347 $('#pause').html('<img src="images/pause.gif" alt="pause" style="border: 1px solid black;" />');
358 // Set an event listener for infinite scroll
359 if(typeof infinite_scroll !== 'undefined') {
360 $(window).scroll(function(e){
361 if ($(document).height() != $(window).height()) {
362 // First method that is expected to work - but has problems with Chrome
363 if ($(window).scrollTop() > ($(document).height() - $(window).height() * 1.5))
366 // This method works with Chrome - but seems to be much slower in Firefox
367 if ($(window).scrollTop() > (($("section").height() + $("header").height() + $("footer").height()) - $(window).height() * 1.5))
376 function NavUpdate() {
379 var pingCmd = 'ping' + ((localUser != 0) ? '?f=&uid=' + localUser : '');
380 $.get(pingCmd,function(data) {
381 $(data).find('result').each(function() {
382 // send nav-update event
383 $('nav').trigger('nav-update', this);
388 if($('#live-network').length) { src = 'network'; liveUpdate(); }
389 if($('#live-profile').length) { src = 'profile'; liveUpdate(); }
390 if($('#live-community').length) { src = 'community'; liveUpdate(); }
391 if($('#live-notes').length) { src = 'notes'; liveUpdate(); }
392 if($('#live-display').length) { src = 'display'; liveUpdate(); }
393 /* if($('#live-display').length) {
396 window.location.href=window.location.href
399 if($('#live-photos').length) {
402 window.location.href=window.location.href
412 timer = setTimeout(NavUpdate,updateInterval);
415 function liveUpdate() {
416 if((src == null) || (stopped) || (! profile_uid)) { $('.like-rotator').hide(); return; }
417 if(($('.comment-edit-text-full').length) || (in_progress)) {
419 clearTimeout(livetime);
421 livetime = setTimeout(liveUpdate, 5000);
427 prev = 'live-' + src;
431 if ($(document).scrollTop() == 0)
434 var udargs = ((netargs.length) ? '/' + netargs : '');
435 var update_url = 'update_' + src + udargs + '&p=' + profile_uid + '&page=' + profile_page + '&force=' + ((force_update) ? 1 : 0);
437 $.get(update_url,function(data) {
439 force_update = false;
440 // $('.collapsed-comments',data).each(function() {
441 // var ident = $(this).attr('id');
442 // var is_hidden = $('#' + ident).is(':hidden');
443 // if($('#' + ident).length) {
444 // $('#' + ident).replaceWith($(this));
446 // $('#' + ident).hide();
451 $('.toplevel_item',data).each(function() {
452 var ident = $(this).attr('id');
454 if($('#' + ident).length == 0 && profile_page == 1) {
455 $('img',this).each(function() {
456 $(this).attr('src',$(this).attr('dst'));
458 $('#' + prev).after($(this));
461 // Find out if the hidden comments are open, so we can keep it that way
462 // if a new comment has been posted
463 var id = $('.hide-comments-total', this).attr('id');
464 if(typeof id != 'undefined') {
465 id = id.split('-')[3];
466 var commentsOpen = $("#collapsed-comments-" + id).is(":visible");
469 $('img',this).each(function() {
470 $(this).attr('src',$(this).attr('dst'));
472 //vScroll = $(document).scrollTop();
473 $('html').height($('html').height());
474 $('#' + ident).replaceWith($(this));
476 if(typeof id != 'undefined') {
477 if(commentsOpen) showHideComments(id);
479 $('html').height('auto');
480 //$(document).scrollTop(vScroll);
485 // reset vars for inserting individual items
487 /* prev = 'live-' + src;
489 $('.wall-item-outside-wrapper',data).each(function() {
490 var ident = $(this).attr('id');
492 if($('#' + ident).length == 0 && prev != 'live-' + src) {
493 $('img',this).each(function() {
494 $(this).attr('src',$(this).attr('dst'));
496 $('#' + prev).after($(this));
499 $('#' + ident + ' ' + '.wall-item-ago').replaceWith($(this).find('.wall-item-ago'));
500 if($('#' + ident + ' ' + '.comment-edit-text-empty').length)
501 $('#' + ident + ' ' + '.wall-item-comment-wrapper').replaceWith($(this).find('.wall-item-comment-wrapper'));
502 $('#' + ident + ' ' + '.hide-comments-total').replaceWith($(this).find('.hide-comments-total'));
503 $('#' + ident + ' ' + '.wall-item-like').replaceWith($(this).find('.wall-item-like'));
504 $('#' + ident + ' ' + '.wall-item-dislike').replaceWith($(this).find('.wall-item-dislike'));
505 $('#' + ident + ' ' + '.my-comment-photo').each(function() {
506 $(this).attr('src',$(this).attr('dst'));
512 $('.like-rotator').hide();
515 $('body').css('cursor', 'auto');
517 /* autocomplete @nicknames */
518 $(".comment-edit-form textarea").editor_autocomplete(baseurl+"/acl");
519 /* autocomplete bbcode */
520 $(".comment-edit-form textarea").bbco_autocomplete('bbcode');
522 // setup videos, since VideoJS won't take care of any loaded via AJAX
523 if(typeof videojs != 'undefined') videojs.autoSetup();
527 function imgbright(node) {
528 $(node).removeClass("drophide").addClass("drop");
531 function imgdull(node) {
532 $(node).removeClass("drop").addClass("drophide");
535 // Since our ajax calls are asynchronous, we will give a few
536 // seconds for the first ajax call (setting like/dislike), then
537 // run the updater to pick up any changes and display on the page.
538 // The updater will turn any rotators off when it's done.
539 // This function will have returned long before any of these
540 // events have completed and therefore there won't be any
541 // visible feedback that anything changed without all this
542 // trickery. This still could cause confusion if the "like" ajax call
543 // is delayed and NavUpdate runs before it completes.
545 function dolike(ident,verb) {
547 $('#like-rotator-' + ident.toString()).show();
548 $.get('like/' + ident.toString() + '?verb=' + verb, NavUpdate );
553 function dosubthread(ident) {
555 $('#like-rotator-' + ident.toString()).show();
556 $.get('subthread/' + ident.toString(), NavUpdate );
561 function dostar(ident) {
562 ident = ident.toString();
563 $('#like-rotator-' + ident).show();
564 $.get('starred/' + ident, function(data) {
565 if(data.match(/1/)) {
566 $('#starred-' + ident).addClass('starred');
567 $('#starred-' + ident).removeClass('unstarred');
568 $('#star-' + ident).addClass('hidden');
569 $('#unstar-' + ident).removeClass('hidden');
572 $('#starred-' + ident).addClass('unstarred');
573 $('#starred-' + ident).removeClass('starred');
574 $('#star-' + ident).removeClass('hidden');
575 $('#unstar-' + ident).addClass('hidden');
577 $('#like-rotator-' + ident).hide();
581 function doignore(ident) {
582 ident = ident.toString();
583 $('#like-rotator-' + ident).show();
584 $.get('ignored/' + ident, function(data) {
585 if(data.match(/1/)) {
586 $('#ignored-' + ident).addClass('ignored');
587 $('#ignored-' + ident).removeClass('unignored');
588 $('#ignore-' + ident).addClass('hidden');
589 $('#unignore-' + ident).removeClass('hidden');
592 $('#ignored-' + ident).addClass('unignored');
593 $('#ignored-' + ident).removeClass('ignored');
594 $('#ignore-' + ident).removeClass('hidden');
595 $('#unignore-' + ident).addClass('hidden');
597 $('#like-rotator-' + ident).hide();
601 function getPosition(e) {
602 var cursor = {x:0, y:0};
603 if ( e.pageX || e.pageY ) {
608 if( e.clientX || e.clientY ) {
609 cursor.x = e.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft) - document.documentElement.clientLeft;
610 cursor.y = e.clientY + (document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop;
622 var lockvisible = false;
624 function lockview(event,id) {
625 event = event || window.event;
626 cursor = getPosition(event);
632 $.get('lockview/' + id, function(data) {
633 $('#panel').html(data);
634 $('#panel').css({ 'left': cursor.x + 5 , 'top': cursor.y + 5});
640 function lockviewhide() {
645 function post_comment(id) {
648 $('body').css('cursor', 'wait');
649 $("#comment-preview-inp-" + id).val("0");
652 $("#comment-edit-form-" + id).serialize(),
655 $("#comment-edit-wrapper-" + id).hide();
656 $("#comment-edit-text-" + id).val('');
657 var tarea = document.getElementById("comment-edit-text-" + id);
659 commentClose(tarea,id);
660 if(timer) clearTimeout(timer);
661 timer = setTimeout(NavUpdate,10);
665 window.location.href=data.reload;
674 function preview_comment(id) {
675 $("#comment-preview-inp-" + id).val("1");
676 $("#comment-edit-preview-" + id).show();
679 $("#comment-edit-form-" + id).serialize(),
682 $("#comment-edit-preview-" + id).html(data.preview);
683 $("#comment-edit-preview-" + id + " a").click(function() { return false; });
693 function showHideComments(id) {
694 if( $("#collapsed-comments-" + id).is(":visible")) {
695 $("#collapsed-comments-" + id).hide();
696 $("#hide-comments-" + id).html(window.showMore);
699 $("#collapsed-comments-" + id).show();
700 $("#hide-comments-" + id).html(window.showFewer);
706 function preview_post() {
707 $("#jot-preview").val("1");
708 $("#jot-preview-content").show();
709 tinyMCE.triggerSave();
712 $("#profile-jot-form").serialize(),
715 $("#jot-preview-content").html(data.preview);
716 $("#jot-preview-content" + " a").click(function() { return false; });
721 $("#jot-preview").val("0");
727 // unpause auto reloads if they are currently stopped
730 $('#pause').html('');
733 // load more network content (used for infinite scroll)
734 function loadScrollContent() {
735 if (lockLoadContent) return;
736 lockLoadContent = true;
738 $("#scroll-loader").fadeIn('normal');
740 // the page number to load is one higher than the actual
742 infinite_scroll.pageno+=1;
744 console.log('Loading page ' + infinite_scroll.pageno);
746 // get the raw content from the next page and insert this content
747 // right before "#conversation-end"
748 $.get('network?mode=raw' + infinite_scroll.reload_uri + '&page=' + infinite_scroll.pageno, function(data) {
749 $("#scroll-loader").hide();
750 if ($(data).length > 0) {
751 $(data).insertBefore('#conversation-end');
752 lockLoadContent = false;
754 $("#scroll-end").fadeIn('normal');
760 // Converts the binary representation of data to hex
763 // discuss at: http://phpjs.org/functions/bin2hex
764 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
765 // + bugfixed by: Onno Marsman
766 // + bugfixed by: Linuxworld
767 // * example 1: bin2hex('Kev');
768 // * returns 1: '4b6576'
769 // * example 2: bin2hex(String.fromCharCode(0x00));
771 var v,i, f = 0, a = [];
775 for (i = 0; i<f; i++) {
776 a[i] = s.charCodeAt(i).toString(16).replace(/^([\da-f])$/,"0$1");
782 function groupChangeMember(gid, cid, sec_token) {
783 $('body .fakelink').css('cursor', 'wait');
784 $.get('group/' + gid + '/' + cid + "?t=" + sec_token, function(data) {
785 $('#group-update-wrapper').html(data);
786 $('body .fakelink').css('cursor', 'auto');
790 function profChangeMember(gid,cid) {
791 $('body .fakelink').css('cursor', 'wait');
792 $.get('profperm/' + gid + '/' + cid, function(data) {
793 $('#prof-update-wrapper').html(data);
794 $('body .fakelink').css('cursor', 'auto');
798 function contactgroupChangeMember(gid,cid) {
799 $('body').css('cursor', 'wait');
800 $.get('contactgroup/' + gid + '/' + cid, function(data) {
801 $('body').css('cursor', 'auto');
806 function checkboxhighlight(box) {
807 if($(box).is(':checked')) {
808 $(box).addClass('checkeditem');
811 $(box).removeClass('checkeditem');
815 function notifyMarkAll() {
816 $.get('notify/mark/all', function(data) {
817 if(timer) clearTimeout(timer);
818 timer = setTimeout(NavUpdate,1000);
824 // code from http://www.tinymce.com/wiki.php/How-to_implement_a_custom_file_browser
825 function fcFileBrowser (field_name, url, type, win) {
826 /* TODO: If you work with sessions in PHP and your client doesn't accept cookies you might need to carry
827 the session name and session ID in the request string (can look like this: "?PHPSESSID=88p0n70s9dsknra96qhuk6etm5").
828 These lines of code extract the necessary parameters and add them back to the filebrowser URL again. */
831 var cmsURL = baseurl+"/fbrowser/"+type+"/";
833 tinyMCE.activeEditor.windowManager.open({
835 title : 'File Browser',
836 width : 420, // Your dimensions may differ - toy around with them!
839 inline : "yes", // This parameter only has an effect if you use the inlinepopups plugin!
840 close_previous : "no"
848 function setupFieldRichtext(){
851 mode : "specific_textareas",
852 editor_selector: "fieldRichtext",
853 plugins : "bbcode,paste, inlinepopups",
854 theme_advanced_buttons1 : "bold,italic,underline,undo,redo,link,unlink,image,forecolor,formatselect,code",
855 theme_advanced_buttons2 : "",
856 theme_advanced_buttons3 : "",
857 theme_advanced_toolbar_location : "top",
858 theme_advanced_toolbar_align : "center",
859 theme_advanced_blockformats : "blockquote,code",
860 theme_advanced_resizing : true,
861 paste_text_sticky : true,
862 entity_encoding : "raw",
863 add_unload_trigger : false,
864 remove_linebreaks : false,
865 //force_p_newlines : false,
866 //force_br_newlines : true,
867 forced_root_block : 'div',
869 content_css: baseurl+"/view/custom_tinymce.css",
870 theme_advanced_path : false,
871 file_browser_callback : "fcFileBrowser",
877 * sprintf in javascript
878 * "{0} and {1}".format('zero','uno');
880 String.prototype.format = function() {
881 var formatted = this;
882 for (var i = 0; i < arguments.length; i++) {
883 var regexp = new RegExp('\\{'+i+'\\}', 'gi');
884 formatted = formatted.replace(regexp, arguments[i]);
889 Array.prototype.remove = function(item) {
890 to=undefined; from=this.indexOf(item);
891 var rest = this.slice((to || from) + 1 || this.length);
892 this.length = from < 0 ? this.length + from : from;
893 return this.push.apply(this, rest);
896 function previewTheme(elm) {
897 theme = $(elm).val();
898 $.getJSON('pretheme?f=&theme=' + theme,function(data) {
899 $('#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>');
904 // notification permission settings in localstorage
905 // set by settings page
906 function getNotificationPermission() {
907 if (window["Notification"] === undefined) {
910 if (Notification.permission === 'granted') {
911 var val = localStorage.getItem('notification-permissions');
912 if (val === null) return 'denied';
915 return Notification.permission;
920 * Show a dialog loaded from an url
921 * By defaults this load the url in an iframe in colorbox
922 * Themes can overwrite `show()` function to personalize it
929 * @return object colorbox
931 show : function (url) {
932 var size = Dialog._get_size();
933 return $.colorbox({href: url, iframe:true,innerWidth: size.width+'px',innerHeight: size.height+'px'})
937 * Show the Image browser dialog
940 * @param string id (optional)
943 * The name will be used to build the event name
944 * fired by image browser dialog when the user select
945 * an image. The optional id will be passed as argument
946 * to the event handler
948 doImageBrowser : function (name, id) {
949 var url = Dialog._get_url("image",name,id);
950 return Dialog.show(url);
954 * Show the File browser dialog
957 * @param string id (optional)
960 * The name will be used to build the event name
961 * fired by file browser dialog when the user select
962 * a file. The optional id will be passed as argument
963 * to the event handler
965 doFileBrowser : function (name, id) {
966 var url = Dialog._get_url("file",name,id);
967 return Dialog.show(url);
970 _get_url : function(type, name, id) {
972 if (id !== undefined) hash = hash + "-" + id;
973 return baseurl + "/fbrowser/"+type+"/?mode=minimal#"+hash;
976 _get_size: function() {
978 width: window.innerWidth-50,
979 height: window.innerHeight-100