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"
43 var force_update = false;
45 var totStopped = false;
49 var in_progress = false;
50 var langSelect = false;
51 var commentBusy = false;
52 var last_popup_menu = null;
53 var last_popup_button = null;
56 $.ajaxSetup({cache: false});
58 /* setup tooltips *//*
59 $("a,.tt").each(function(){
62 if (e.hasClass("tttop")) pos="top";
63 if (e.hasClass("ttbottom")) pos="bottom";
64 if (e.hasClass("ttleft")) pos="left";
65 if (e.hasClass("ttright")) pos="right";
66 e.tipTip({defaultPosition: pos, edgeOffset: 8});
69 /* setup comment textarea buttons */
70 /* comment textarea buttons needs some "data-*" attributes to work:
71 * data-role="insert-formatting" : to mark the element as a formatting button
72 * data-comment="<string>" : string for "Comment", used by insertFormatting() function
73 * data-bbcode="<string>" : name of the bbcode element to insert. insertFormatting() will insert it as "[name][/name]"
74 * data-id="<string>" : id of the comment, used to find other comment-related element, like the textarea
76 $('body').on('click','[data-role="insert-formatting"]', function(e) {
79 var comment = o.data('comment');
80 var bbcode = o.data('bbcode');
81 var id = o.data('id');
83 Dialog.doImageBrowser("comment", id);
86 insertFormatting(comment, bbcode, id);
89 /* event from comment textarea button popups */
90 /* insert returned bbcode at cursor position or replace selected text */
91 $("body").on("fbrowser.image.comment", function(e, filename, bbcode, id) {
92 console.log("on", id);
94 var textarea = document.getElementById("comment-edit-text-" +id);
95 var start = textarea.selectionStart;
96 var end = textarea.selectionEnd;
97 textarea.value = textarea.value.substring(0, start) + bbcode + textarea.value.substring(end, textarea.value.length);
102 /* setup onoff widgets */
103 $(".onoff input").each(function(){
105 id = $(this).attr("id");
106 $("#"+id+"_onoff ."+ (val==0?"on":"off")).addClass("hidden");
109 $(".onoff > a").click(function(event){
110 event.preventDefault();
111 var input = $(this).siblings("input");
112 var val = 1-input.val();
113 var id = input.attr("id");
114 $("#"+id+"_onoff ."+ (val==0?"on":"off")).addClass("hidden");
115 $("#"+id+"_onoff ."+ (val==1?"on":"off")).removeClass("hidden");
120 /* setup field_richtext */
121 setupFieldRichtext();
124 function close_last_popup_menu() {
125 if(last_popup_menu) {
126 last_popup_menu.hide();
127 last_popup_button.removeClass("selected");
128 last_popup_menu = null;
129 last_popup_button = null;
132 $('a[rel^=#]').click(function(e){
134 var parent = $(this).parent();
135 var isSelected = (last_popup_button && parent.attr('id') == last_popup_button.attr('id'));
136 close_last_popup_menu();
137 if(isSelected) return false;
138 menu = $( $(this).attr('rel') );
141 if (menu.attr('popup')=="false") return false;
142 parent.toggleClass("selected");
144 if (menu.css("display") == "none") {
145 last_popup_menu = null;
146 last_popup_button = null;
148 last_popup_menu = menu;
149 last_popup_button = parent;
150 $('#nav-notifications-menu').perfectScrollbar('update');
154 $('html').click(function() {
155 close_last_popup_menu();
159 $("a.popupbox").colorbox({
161 'transition' : 'elastic'
163 $("a.ajax-popupbox").colorbox({
164 'transition' : 'elastic'
167 /* notifications template */
168 var notifications_tpl= unescape($("#nav-notifications-template[rel=template]").html());
169 var notifications_all = unescape($('<div>').append( $("#nav-notifications-see-all").clone() ).html()); //outerHtml hack
170 var notifications_mark = unescape($('<div>').append( $("#nav-notifications-mark-all").clone() ).html()); //outerHtml hack
171 var notifications_empty = unescape($("#nav-notifications-menu").html());
173 /* enable perfect-scrollbars for nav-notivications-menu */
174 $('#nav-notifications-menu').perfectScrollbar();
175 $('aside').perfectScrollbar();
177 /* nav update event */
178 $('nav').bind('nav-update', function(e,data){
179 var invalid = $(data).find('invalid').text();
180 if(invalid == 1) { window.location.href=window.location.href }
182 var net = $(data).find('net').text();
183 if(net == 0) { net = ''; $('#net-update').removeClass('show') } else { $('#net-update').addClass('show') }
184 $('#net-update').html(net);
186 var home = $(data).find('home').text();
187 if(home == 0) { home = ''; $('#home-update').removeClass('show') } else { $('#home-update').addClass('show') }
188 $('#home-update').html(home);
190 var intro = $(data).find('intro').text();
191 if(intro == 0) { intro = ''; $('#intro-update').removeClass('show') } else { $('#intro-update').addClass('show') }
192 $('#intro-update').html(intro);
194 var mail = $(data).find('mail').text();
195 if(mail == 0) { mail = ''; $('#mail-update').removeClass('show') } else { $('#mail-update').addClass('show') }
196 $('#mail-update').html(mail);
198 var intro = $(data).find('intro').text();
199 if(intro == 0) { intro = ''; $('#intro-update-li').removeClass('show') } else { $('#intro-update-li').addClass('show') }
200 $('#intro-update-li').html(intro);
202 var mail = $(data).find('mail').text();
203 if(mail == 0) { mail = ''; $('#mail-update-li').removeClass('show') } else { $('#mail-update-li').addClass('show') }
204 $('#mail-update-li').html(mail);
207 var allevents = $(data).find('all-events').text();
208 if(allevents == 0) { allevents = ''; $('#allevents-update').removeClass('show') } else { $('#allevents-update').addClass('show') }
209 $('#allevents-update').html(allevents);
211 var alleventstoday = $(data).find('all-events-today').text();
212 if(alleventstoday == 0) { $('#allevents-update').removeClass('notif-allevents-today') } else { $('#allevents-update').addClass('notif-allevents-today') }
214 var events = $(data).find('events').text();
215 if(events == 0) { events = ''; $('#events-update').removeClass('show') } else { $('#events-update').addClass('show') }
216 $('#events-update').html(events);
218 var eventstoday = $(data).find('events-today').text();
219 if(eventstoday == 0) { $('#events-update').removeClass('notif-events-today') } else { $('#events-update').addClass('notif-events-today') }
221 var birthdays = $(data).find('birthdays').text();
222 if(birthdays == 0) {birthdays = ''; $('#birthdays-update').removeClass('show') } else { $('#birthdays-update').addClass('show') }
223 $('#birthdays-update').html(birthdays);
225 var birthdaystoday = $(data).find('birthdays-today').text();
226 if(birthdaystoday == 0) { $('#birthdays-update').removeClass('notif-birthdays-today') } else { $('#birthdays-update').addClass('notif-birthdays-today') }
228 $(".sidebar-group-li .notify").removeClass("show");
229 $(data).find("group").each(function() {
231 var gcount = this.innerHTML;
232 $(".group-"+gid+" .notify").addClass("show").text(gcount);
235 $(".forum-widget-entry .notify").removeClass("show");
236 $(data).find("forum").each(function() {
238 var fcount = this.innerHTML;
239 $(".forum-"+fid+" .notify").addClass("show").text(fcount);
243 var eNotif = $(data).find('notif')
245 if (eNotif.children("note").length==0){
246 $("#nav-notifications-menu").html(notifications_empty);
248 nnm = $("#nav-notifications-menu");
249 nnm.html(notifications_all + notifications_mark);
250 //nnm.attr('popup','true');
252 var notification_lastitem = parseInt(localStorage.getItem("notification-lastitem"));
253 var notification_id = 0;
254 eNotif.children("note").each(function(){
256 var text = e.text().format("<span class='contactname'>"+e.attr('name')+"</span>");
257 var contact = ("<a href="+e.attr('url')+"><span class='contactname'>"+e.attr('name')+"</span></a>");
258 var seenclass = (e.attr('seen')==1)?"notify-seen":"notify-unseen";
259 var html = notifications_tpl.format(
260 e.attr('href'), // {0} // link to the source
261 e.attr('photo'), // {1} // photo of the contact
262 text, // {2} // preformatet text (autor + text)
263 e.attr('date'), // {3} // date of notification (time ago)
264 seenclass, // {4} // vistiting status of the notification
265 new Date(e.attr('timestamp')*1000), // {5} //date of notification
266 e.attr('url'), // {6} // profile url of the contact
267 e.text().format(""), // {7} // clean status text
268 contact // {8} //preformatat author (name + profile url)
272 $(eNotif.children("note").get().reverse()).each(function(){
274 notification_id = parseInt(e.attr('timestamp'));
275 if (notification_lastitem!== null && notification_id > notification_lastitem) {
276 if (getNotificationPermission()==="granted") {
277 var notification = new Notification(document.title, {
278 body: e.text().replace('→ ','').format(e.attr('name')),
279 icon: e.attr('photo'),
281 notification['url'] = e.attr('href');
282 notification.addEventListener("click", function(ev){
283 window.location = ev.target.url;
289 notification_lastitem = notification_id;
290 localStorage.setItem("notification-lastitem", notification_lastitem)
292 $("img[data-src]", nnm).each(function(i, el){
293 // Add src attribute for images with a data-src attribute
294 // However, don't bother if the data-src attribute is empty, because
295 // an empty "src" tag for an image will cause some browsers
296 // to prefetch the root page of the Friendica hub, which will
297 // unnecessarily load an entire profile/ or network/ page
298 if($(el).data("src") != '') $(el).attr('src', $(el).data("src"));
302 notif = eNotif.attr('count');
304 $("#nav-notifications-linkmenu").addClass("on");
306 $("#nav-notifications-linkmenu").removeClass("on");
308 if(notif == 0) { notif = ''; $('#notify-update').removeClass('show') } else { $('#notify-update').addClass('show') }
309 $('#notify-update').html(notif);
311 var eSysmsg = $(data).find('sysmsgs');
312 eSysmsg.children("notice").each(function(){
313 text = $(this).text();
314 $.jGrowl(text, { sticky: true, theme: 'notice' });
316 eSysmsg.children("info").each(function(){
317 text = $(this).text();
318 $.jGrowl(text, { sticky: false, theme: 'info', life: 5000 });
321 /* update the js scrollbars */
322 $('#nav-notifications-menu').perfectScrollbar('update');
327 // Allow folks to stop the ajax page updates with the pause/break key
328 $(document).keydown(function(event) {
329 if(event.keyCode == '8') {
330 var target = event.target || event.srcElement;
331 if (!/input|textarea/i.test(target.nodeName)) {
335 if(event.keyCode == '19' || (event.ctrlKey && event.which == '32')) {
336 event.preventDefault();
337 if(stopped == false) {
342 $('#pause').html('<img src="images/pause.gif" alt="pause" style="border: 1px solid black;" />');
356 function NavUpdate() {
359 var pingCmd = 'ping' + ((localUser != 0) ? '?f=&uid=' + localUser : '');
360 $.get(pingCmd,function(data) {
361 $(data).find('result').each(function() {
362 // send nav-update event
363 $('nav').trigger('nav-update', this);
368 if($('#live-network').length) { src = 'network'; liveUpdate(); }
369 if($('#live-profile').length) { src = 'profile'; liveUpdate(); }
370 if($('#live-community').length) { src = 'community'; liveUpdate(); }
371 if($('#live-notes').length) { src = 'notes'; liveUpdate(); }
372 if($('#live-display').length) { src = 'display'; liveUpdate(); }
373 /* if($('#live-display').length) {
376 window.location.href=window.location.href
379 if($('#live-photos').length) {
382 window.location.href=window.location.href
392 timer = setTimeout(NavUpdate,updateInterval);
395 function liveUpdate() {
396 if((src == null) || (stopped) || (! profile_uid)) { $('.like-rotator').hide(); return; }
397 if(($('.comment-edit-text-full').length) || (in_progress)) {
399 clearTimeout(livetime);
401 livetime = setTimeout(liveUpdate, 5000);
407 prev = 'live-' + src;
411 if ($(document).scrollTop() == 0)
414 var udargs = ((netargs.length) ? '/' + netargs : '');
415 var update_url = 'update_' + src + udargs + '&p=' + profile_uid + '&page=' + profile_page + '&force=' + ((force_update) ? 1 : 0);
417 $.get(update_url,function(data) {
419 force_update = false;
420 // $('.collapsed-comments',data).each(function() {
421 // var ident = $(this).attr('id');
422 // var is_hidden = $('#' + ident).is(':hidden');
423 // if($('#' + ident).length) {
424 // $('#' + ident).replaceWith($(this));
426 // $('#' + ident).hide();
431 $('.toplevel_item',data).each(function() {
432 var ident = $(this).attr('id');
434 if($('#' + ident).length == 0 && profile_page == 1) {
435 $('img',this).each(function() {
436 $(this).attr('src',$(this).attr('dst'));
438 $('#' + prev).after($(this));
441 // Find out if the hidden comments are open, so we can keep it that way
442 // if a new comment has been posted
443 var id = $('.hide-comments-total', this).attr('id');
444 if(typeof id != 'undefined') {
445 id = id.split('-')[3];
446 var commentsOpen = $("#collapsed-comments-" + id).is(":visible");
449 $('img',this).each(function() {
450 $(this).attr('src',$(this).attr('dst'));
452 //vScroll = $(document).scrollTop();
453 $('html').height($('html').height());
454 $('#' + ident).replaceWith($(this));
456 if(typeof id != 'undefined') {
457 if(commentsOpen) showHideComments(id);
459 $('html').height('auto');
460 //$(document).scrollTop(vScroll);
465 // reset vars for inserting individual items
467 /* prev = 'live-' + src;
469 $('.wall-item-outside-wrapper',data).each(function() {
470 var ident = $(this).attr('id');
472 if($('#' + ident).length == 0 && prev != 'live-' + src) {
473 $('img',this).each(function() {
474 $(this).attr('src',$(this).attr('dst'));
476 $('#' + prev).after($(this));
479 $('#' + ident + ' ' + '.wall-item-ago').replaceWith($(this).find('.wall-item-ago'));
480 if($('#' + ident + ' ' + '.comment-edit-text-empty').length)
481 $('#' + ident + ' ' + '.wall-item-comment-wrapper').replaceWith($(this).find('.wall-item-comment-wrapper'));
482 $('#' + ident + ' ' + '.hide-comments-total').replaceWith($(this).find('.hide-comments-total'));
483 $('#' + ident + ' ' + '.wall-item-like').replaceWith($(this).find('.wall-item-like'));
484 $('#' + ident + ' ' + '.wall-item-dislike').replaceWith($(this).find('.wall-item-dislike'));
485 $('#' + ident + ' ' + '.my-comment-photo').each(function() {
486 $(this).attr('src',$(this).attr('dst'));
492 $('.like-rotator').hide();
495 $('body').css('cursor', 'auto');
497 /* autocomplete @nicknames */
498 $(".comment-edit-form textarea").contact_autocomplete(baseurl+"/acl");
500 // setup videos, since VideoJS won't take care of any loaded via AJAX
501 if(typeof videojs != 'undefined') videojs.autoSetup();
505 function imgbright(node) {
506 $(node).removeClass("drophide").addClass("drop");
509 function imgdull(node) {
510 $(node).removeClass("drop").addClass("drophide");
513 // Since our ajax calls are asynchronous, we will give a few
514 // seconds for the first ajax call (setting like/dislike), then
515 // run the updater to pick up any changes and display on the page.
516 // The updater will turn any rotators off when it's done.
517 // This function will have returned long before any of these
518 // events have completed and therefore there won't be any
519 // visible feedback that anything changed without all this
520 // trickery. This still could cause confusion if the "like" ajax call
521 // is delayed and NavUpdate runs before it completes.
523 function dolike(ident,verb) {
525 $('#like-rotator-' + ident.toString()).show();
526 $.get('like/' + ident.toString() + '?verb=' + verb, NavUpdate );
531 function dosubthread(ident) {
533 $('#like-rotator-' + ident.toString()).show();
534 $.get('subthread/' + ident.toString(), NavUpdate );
539 function dostar(ident) {
540 ident = ident.toString();
541 $('#like-rotator-' + ident).show();
542 $.get('starred/' + ident, function(data) {
543 if(data.match(/1/)) {
544 $('#starred-' + ident).addClass('starred');
545 $('#starred-' + ident).removeClass('unstarred');
546 $('#star-' + ident).addClass('hidden');
547 $('#unstar-' + ident).removeClass('hidden');
550 $('#starred-' + ident).addClass('unstarred');
551 $('#starred-' + ident).removeClass('starred');
552 $('#star-' + ident).removeClass('hidden');
553 $('#unstar-' + ident).addClass('hidden');
555 $('#like-rotator-' + ident).hide();
559 function doignore(ident) {
560 ident = ident.toString();
561 $('#like-rotator-' + ident).show();
562 $.get('ignored/' + ident, function(data) {
563 if(data.match(/1/)) {
564 $('#ignored-' + ident).addClass('ignored');
565 $('#ignored-' + ident).removeClass('unignored');
566 $('#ignore-' + ident).addClass('hidden');
567 $('#unignore-' + ident).removeClass('hidden');
570 $('#ignored-' + ident).addClass('unignored');
571 $('#ignored-' + ident).removeClass('ignored');
572 $('#ignore-' + ident).removeClass('hidden');
573 $('#unignore-' + ident).addClass('hidden');
575 $('#like-rotator-' + ident).hide();
579 function getPosition(e) {
580 var cursor = {x:0, y:0};
581 if ( e.pageX || e.pageY ) {
586 if( e.clientX || e.clientY ) {
587 cursor.x = e.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft) - document.documentElement.clientLeft;
588 cursor.y = e.clientY + (document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop;
600 var lockvisible = false;
602 function lockview(event,id) {
603 event = event || window.event;
604 cursor = getPosition(event);
610 $.get('lockview/' + id, function(data) {
611 $('#panel').html(data);
612 $('#panel').css({ 'left': cursor.x + 5 , 'top': cursor.y + 5});
618 function lockviewhide() {
623 function post_comment(id) {
626 $('body').css('cursor', 'wait');
627 $("#comment-preview-inp-" + id).val("0");
630 $("#comment-edit-form-" + id).serialize(),
633 $("#comment-edit-wrapper-" + id).hide();
634 $("#comment-edit-text-" + id).val('');
635 var tarea = document.getElementById("comment-edit-text-" + id);
637 commentClose(tarea,id);
638 if(timer) clearTimeout(timer);
639 timer = setTimeout(NavUpdate,10);
643 window.location.href=data.reload;
652 function preview_comment(id) {
653 $("#comment-preview-inp-" + id).val("1");
654 $("#comment-edit-preview-" + id).show();
657 $("#comment-edit-form-" + id).serialize(),
660 $("#comment-edit-preview-" + id).html(data.preview);
661 $("#comment-edit-preview-" + id + " a").click(function() { return false; });
671 function showHideComments(id) {
672 if( $("#collapsed-comments-" + id).is(":visible")) {
673 $("#collapsed-comments-" + id).hide();
674 $("#hide-comments-" + id).html(window.showMore);
677 $("#collapsed-comments-" + id).show();
678 $("#hide-comments-" + id).html(window.showFewer);
684 function preview_post() {
685 $("#jot-preview").val("1");
686 $("#jot-preview-content").show();
687 tinyMCE.triggerSave();
690 $("#profile-jot-form").serialize(),
693 $("#jot-preview-content").html(data.preview);
694 $("#jot-preview-content" + " a").click(function() { return false; });
699 $("#jot-preview").val("0");
705 // unpause auto reloads if they are currently stopped
708 $('#pause').html('');
713 // Converts the binary representation of data to hex
716 // discuss at: http://phpjs.org/functions/bin2hex
717 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
718 // + bugfixed by: Onno Marsman
719 // + bugfixed by: Linuxworld
720 // * example 1: bin2hex('Kev');
721 // * returns 1: '4b6576'
722 // * example 2: bin2hex(String.fromCharCode(0x00));
724 var v,i, f = 0, a = [];
728 for (i = 0; i<f; i++) {
729 a[i] = s.charCodeAt(i).toString(16).replace(/^([\da-f])$/,"0$1");
735 function groupChangeMember(gid, cid, sec_token) {
736 $('body .fakelink').css('cursor', 'wait');
737 $.get('group/' + gid + '/' + cid + "?t=" + sec_token, function(data) {
738 $('#group-update-wrapper').html(data);
739 $('body .fakelink').css('cursor', 'auto');
743 function profChangeMember(gid,cid) {
744 $('body .fakelink').css('cursor', 'wait');
745 $.get('profperm/' + gid + '/' + cid, function(data) {
746 $('#prof-update-wrapper').html(data);
747 $('body .fakelink').css('cursor', 'auto');
751 function contactgroupChangeMember(gid,cid) {
752 $('body').css('cursor', 'wait');
753 $.get('contactgroup/' + gid + '/' + cid, function(data) {
754 $('body').css('cursor', 'auto');
759 function checkboxhighlight(box) {
760 if($(box).is(':checked')) {
761 $(box).addClass('checkeditem');
764 $(box).removeClass('checkeditem');
768 function notifyMarkAll() {
769 $.get('notify/mark/all', function(data) {
770 if(timer) clearTimeout(timer);
771 timer = setTimeout(NavUpdate,1000);
777 // code from http://www.tinymce.com/wiki.php/How-to_implement_a_custom_file_browser
778 function fcFileBrowser (field_name, url, type, win) {
779 /* TODO: If you work with sessions in PHP and your client doesn't accept cookies you might need to carry
780 the session name and session ID in the request string (can look like this: "?PHPSESSID=88p0n70s9dsknra96qhuk6etm5").
781 These lines of code extract the necessary parameters and add them back to the filebrowser URL again. */
784 var cmsURL = baseurl+"/fbrowser/"+type+"/";
786 tinyMCE.activeEditor.windowManager.open({
788 title : 'File Browser',
789 width : 420, // Your dimensions may differ - toy around with them!
792 inline : "yes", // This parameter only has an effect if you use the inlinepopups plugin!
793 close_previous : "no"
801 function setupFieldRichtext(){
804 mode : "specific_textareas",
805 editor_selector: "fieldRichtext",
806 plugins : "bbcode,paste, inlinepopups",
807 theme_advanced_buttons1 : "bold,italic,underline,undo,redo,link,unlink,image,forecolor,formatselect,code",
808 theme_advanced_buttons2 : "",
809 theme_advanced_buttons3 : "",
810 theme_advanced_toolbar_location : "top",
811 theme_advanced_toolbar_align : "center",
812 theme_advanced_blockformats : "blockquote,code",
813 theme_advanced_resizing : true,
814 paste_text_sticky : true,
815 entity_encoding : "raw",
816 add_unload_trigger : false,
817 remove_linebreaks : false,
818 //force_p_newlines : false,
819 //force_br_newlines : true,
820 forced_root_block : 'div',
822 content_css: baseurl+"/view/custom_tinymce.css",
823 theme_advanced_path : false,
824 file_browser_callback : "fcFileBrowser",
830 * sprintf in javascript
831 * "{0} and {1}".format('zero','uno');
833 String.prototype.format = function() {
834 var formatted = this;
835 for (var i = 0; i < arguments.length; i++) {
836 var regexp = new RegExp('\\{'+i+'\\}', 'gi');
837 formatted = formatted.replace(regexp, arguments[i]);
842 Array.prototype.remove = function(item) {
843 to=undefined; from=this.indexOf(item);
844 var rest = this.slice((to || from) + 1 || this.length);
845 this.length = from < 0 ? this.length + from : from;
846 return this.push.apply(this, rest);
849 function previewTheme(elm) {
850 theme = $(elm).val();
851 $.getJSON('pretheme?f=&theme=' + theme,function(data) {
852 $('#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>');
857 // notification permission settings in localstorage
858 // set by settings page
859 function getNotificationPermission() {
860 if (window["Notification"] === undefined) {
863 if (Notification.permission === 'granted') {
864 var val = localStorage.getItem('notification-permissions');
865 if (val === null) return 'denied';
868 return Notification.permission;
873 * Show a dialog loaded from an url
874 * By defaults this load the url in an iframe in colorbox
875 * Themes can overwrite `show()` function to personalize it
882 * @return object colorbox
884 show : function (url) {
885 var size = Dialog._get_size();
886 return $.colorbox({href: url, iframe:true,innerWidth: size.width+'px',innerHeight: size.height+'px'})
890 * Show the Image browser dialog
893 * @param string id (optional)
896 * The name will be used to build the event name
897 * fired by image browser dialog when the user select
898 * an image. The optional id will be passed as argument
899 * to the event handler
901 doImageBrowser : function (name, id) {
902 var url = Dialog._get_url("image",name,id);
903 return Dialog.show(url);
907 * Show the File browser dialog
910 * @param string id (optional)
913 * The name will be used to build the event name
914 * fired by file browser dialog when the user select
915 * a file. The optional id will be passed as argument
916 * to the event handler
918 doFileBrowser : function (name, id) {
919 var url = Dialog._get_url("file",name,id);
920 return Dialog.show(url);
923 _get_url : function(type, name, id) {
925 if (id !== undefined) hash = hash + "-" + id;
926 return baseurl + "/fbrowser/"+type+"/?mode=minimal#"+hash;
929 _get_size: function() {
931 width: window.innerWidth-50,
932 height: window.innerHeight-100