PageSourceSearch

https://www.kubaforen.de/inc/lib/bootstrap4/js/xresponsive.js?rev=2085

js kubaforen.de collected 2026-09-26 18:33:16 UTC 88,989 bytes, 2,368 lines download raw bytes

1if (!xobor) {
2    var xobor = new function () { };
3    xobor['mbt'] = {};
4}
5
6xobor.cookie = {
7    set: function (name, val, days) {
8        var mydate = new Date();
9        d = days ? days : 3;
10        mydate.setTime(mydate.getTime() + (d * 24 * 60 * 60 * 1000));
11        var expires = "; expires=" + mydate.toGMTString();
12        document.cookie = name + "=" + val + expires + "; path=/";
13        return true;
14    },
15    get: function (name) {
16        var nameEQ = name + "=";
17        var ca = document.cookie.split(';');
18        for (var i = 0; i < ca.length; i++) {
19            var c = ca[i];
20            while (c.charAt(0) == ' ') c = c.substring(1, c.length);
21            if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
22        }
23        return null;
24
25    },
26    del: function (name) {
27        return xobor.cookie.set(name, 0, -1);
28    }
29
30}
31
32xobor.mbt = $.extend(xobor.mbt, {
33    default_breakpoints: { 'xxxl': 1920, 'xxl': 1600, 'xl': 1200, 'lg': 992, 'md': 768, 'sm': 667, 'xs': 568 },
34    modalcount: 0,
35    currentlightbox: false,
36    currentmodal: false,
37    prevmodal: false,
38    currenticonbarcontainer: false,
39    test: function (cont) {
40        alert("This is working!\n" + cont);
41    },
42
43    setBodyClass: function () {
44        var windowwidth = $(window).width();
45        var padding = 17;
46        windowwidth += padding;
47
48        var newclass = 'xxs';
49
50        if (windowwidth >= this.default_breakpoints.xxxl) {
51            newclass = "xxxl";
52        } else if (windowwidth >= this.default_breakpoints.xxl) {
53            newclass = "xxl";
54        } else if (windowwidth >= this.default_breakpoints.xl) {
55            newclass = "xl";
56        } else if (windowwidth >= this.default_breakpoints.lg) {
57            newclass = "lg";
58        } else if (windowwidth >= this.default_breakpoints.md) {
59            newclass = "md";
60        } else if (windowwidth >= this.default_breakpoints.sm) {
61            newclass = "sm";
62        } else if (windowwidth >= this.default_breakpoints.xs) {
63            newclass = "xs";
64        }
65
66        $('body').toggleClass('xxxl', newclass === 'xxxl')
67            .toggleClass('xxl', newclass === 'xxl')
68            .toggleClass('xl', newclass === 'xl')
69            .toggleClass('lg', newclass === 'lg')
70            .toggleClass('md', newclass === 'md')
71            .toggleClass('sm', newclass === 'sm')
72            .toggleClass('xs', newclass === 'xs')
73            .toggleClass('xxs', newclass === 'xxs');
74
75        return newclass;
76
77    },
78
79    windowResizeFunction: function () {
80        var curbodyclass = this.setBodyClass();
81
82
83        /* Page specific resize funcitons: */
84        if ($('div.main.index').length) {
85            var show_feed_in_scnd_row = curbodyclass.indexOf('xl') > -1 && !$('body').hasClass('singlecol') && !$('body').hasClass('withfeed');
86
87            if (show_feed_in_scnd_row && $('.firstrow #activity_feed').length) {
88                $('#activity_feed').prependTo('.scndrow');
89            }
90            if (!show_feed_in_scnd_row && $('.scndrow #activity_feed').length) {
91                $('#activity_feed').prependTo('.firstrow');
92            }
93        }
94
95        if ($('div.main.user').length) {
96
97            /* Profile Page move Infodiv  if needed */
98            if (curbodyclass == "xxs" || curbodyclass == "xs" || curbodyclass == "sm" || curbodyclass == "md") {
99
100                $('#profileinfos').appendTo($('#profileinfos_mobile_placeholder'));
101            } else {
102
103                $('#profileinfos').appendTo($('#profileinfos_desktop_placeholder'));
104            }
105
106        } else {
107
108        }
109
110
111
112
113
114        this.fixNavigation();
115
116        this.fixFooter();
117
118        this.fixScndRow();
119
120    },
121
122    fixNavigation: function () {
123
124        if ($('#navigation').hasClass('fixed-top')) {
125            var bodypadding = $('#navigation').outerHeight();
126            if (!$('.xpagehead').is(':visible')) { bodypadding += 10; }
127            $('body').css('paddingTop', bodypadding + "px");
128
129            /* Navbar scrollable machen */
130            var $navelements = $('.navbar-collapse').find('.navbar-nav').first().children();
131            var navpadding = parseInt($navelements.first().css('paddingTop')) * 2;
132            var navlineheight = parseInt($navelements.first().css('line-height'));
133            var navheight = $navelements.length * (navpadding + navlineheight);
134
135
136            if ((navheight + 50) > $(window).height()) {
137                $('.navbar-collapse').addClass('doscroll');
138            } else {
139                $('.navbar-collapse').removeClass('doscroll');
140            }
141
142
143        }
144
145        if ($('.nav-link.active').length == 0) {
146            let curpath = window.location.pathname + window.location.search;
147            $.each($(".nav-link"), function () {
148                let curhref = $(this).attr('href');
149
150
151                if (curhref.indexOf(".") === 0) { curhref = curhref.substring(1, curhref.length); }
152                if (curhref.indexOf("/") !== 0) { curhref = "/" + curhref }
153
154                if (curhref == curpath) { $(this).addClass('active'); }
155
156                else { }
157            }
158            );
159        }
160
161        if (parseInt($('.xpagehead').css('height')) + 10 >= $(window).height()) {
162            $('.xpagehead').css('height', ($(window).height() - $('#navigation').outerHeight()) + 'px');
163        }
164
165
166
167    },
168
169
170    fixFooter: function () {
171        if ($(window).height() > $('body').height()) { $('#footernav').addClass('fixed-bottom'); } else { $('#footernav').removeClass('fixed-bottom'); }
172    },
173
174    fixScndRow: function () {
175
176
177
178        $firstrow = $('.firstrow');
179        $scndrow = $('.scndrow');
180        $firstvisiblerow = $firstrow;
181        $scndvisiblerow = $scndrow;
182
183
184        if ($firstrow.hasClass('order-xl-2')) {
185            $firstvisiblerow = $('.scndrow');
186            $scndvisiblerow = $('.firstrow');
187        }
188
189
190        if (!$('body').hasClass('lg') && !$('body').hasClass('md') && !$('body').hasClass('xl') && !$('body').hasClass('xxl') && !$('body').hasClass('xxxl')) {
191            $scndrow.css('marginTop', '0px');
192            $scndrow.removeClass('loading');
193            return true;
194        }
195
196        var mainoffset = $('.main').offset().top;
197        var mainpadding = $('.main').css('paddingTop');
198
199
200
201        var alertoffset = 0;
202        var paneloffset = 0;
203
204        if ($firstvisiblerow.find('.alert:visible').length > 0) {
205            //Set margin by Alert in first row
206            var alertoffset = $firstvisiblerow.find('.alert:visible').first().offset().top;
207            xobor.log.add(4, "scndrowfix alert", alertoffset);
208        }
209
210        if ($firstvisiblerow.find('.card:visible').length > 0) {
211            //Set margin by Panel in first row:
212            var paneloffset = $firstvisiblerow.find('.card:visible').first().offset().top;
213            xobor.log.add(4, "scndrowfix by card", paneloffset);
214        }
215
216
217
218
219        if (alertoffset > 0 && (alertoffset < paneloffset || paneloffset == 0)) {
220            $scndvisiblerow.css('marginTop', parseInt(alertoffset) - parseInt(mainoffset) - parseInt(mainpadding));
221        } else if (paneloffset > 0) {
222            $scndvisiblerow.css('marginTop', parseInt(paneloffset) - parseInt(mainoffset) - parseInt(mainpadding));
223        } else {
224            //try to use breadcrumbs as offset:
225            xobor.log.add(4, "scndrowfix breads", $('.breadcrumb').css('marginBottom')) + parseInt($('#breadcrumbs').outerHeight());
226            $scndvisiblerow.css('marginTop', parseInt($('.breadcrumb').css('marginBottom')) + parseInt($('#breadcrumbs').outerHeight()));
227        }
228
229        $scndrow.removeClass('loading');
230    },
231    banUser: function (id, unban) {
232        var method = unban ? 'unbanUser' : 'banUser';
233        var url = "./ajax/handler.php";
234        $.post(url, { method: method, userid: id }, function (res) {
235            location.reload();
236
237        });
238    },
239    unbanUser: function (id) {
240        this.banUser(id, true);
241    },
242
243    modalAlert: function (title, content) {
244        return this.modal("text-" + content, title);
245    },
246
247    modalPrompt: function (title, content, success, preset, inputmode) {
248        options = { successfunction: success, preset: preset, inputmode: inputmode };
249
250        return this.modal("prompt-" + content, title, options);
251    },
252    modalConfirm: function (title = null, content = null, successfunction) {
253        $('#confirmdelete').remove();
254
255        var curmodaltitle = title ? title : 'Inhalt löschen';
256        var curmodalcontent = content ? content : 'Möchten Sie diesen Inhalt wirklich löschen';
257
258
259
260        var confirmModal = '<div class="modal fade" id="confirmdelete" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"><div class="modal-dialog"><div class="modal-content"><div class="modal-header">' + curmodaltitle + '</div>';
261        confirmModal += '<div class="modal-body">' + curmodalcontent + '</div>';
262        confirmModal += '<div class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">Nein</button><a class="btn btn-primary btn-ok" data-dismiss="modal" id="confirmdelete_confirm" >Ja</a></div>';
263        confirmModal += '</div></div></div>';
264
265        $(confirmModal).appendTo('body');
266
267
268        $('#confirmdelete').on('shown.bs.modal',
269            function () { $('#confirmdelete_confirm').on('click', successfunction); }
270        );
271
272        $('#confirmdelete').modal();
273
274    },
275
276    loadRecaptcha: function (cid) {
277        try {
278            var cont_id = cid ? cid : 'recaptcha_container';
279            var sitekey = $('#' + cont_id).data('sitekey');
280            grecaptcha.render(cont_id, {
281                'sitekey': sitekey,
282                'callback': function (response) {
283                    console.log(response);
284                }
285            });
286        } catch (e) {
287            /*could not load recaptcha*/
288        }
289    },
290
291
292
293    pasteImageHelper: function () {
294        document.onpaste = function (event) {
295            var items = (event.clipboardData || event.originalEvent.clipboardData).items;
296            for (var i = 0; i < items.length; i++) {
297                if (items[i].type.indexOf("image") === 0) {
298
299                    if (!$('#uploadform').is(':visible')) {
300                        event.preventDefault();
301                        var itext = $('#pasteFileInfoText').length ? $('#pasteFileInfoText').html() : 'Bitte klicken Sie zuerst auf Dateien hinzufügn, bevor Sie Bilder aus der Zwischenablage einfügen';
302                        xobor.mbt.shownotice({ title: 'Info', text: itext, type: 'error' });
303                        $('#doattach').trigger('click');
304                    }
305                }
306            }
307        }
308    },
309
310
311    makePwVisibleHelper: function ($input) {
312
313
314        $input.on('keydown', function () {
315            if ($(this).val() == "") {
316                $('#passwordunhider').remove();
317                $(this).attr('type', 'password');
318            } else if (!$('#passwordunhider').length) {
319                let unhider = $('<div class="input-group"><div id="passwordunhider" class="input-group-append"><span class="btn btn-outline-secondary"><a href=""><i class="fa fa-eye-slash" aria-hidden="true"></i></a></span></div></div>');
320                unhider.insertAfter($(this));
321                $(this).insertBefore('#passwordunhider');
322                $(this).focus();
323
324                $("#passwordunhider a").on('click', function (event) {
325                    let curpwinput = $(this).closest('.input-group').find('input');
326                    let curpwinputicon = $(this).closest('.input-group').find('i.fa');
327                    event.preventDefault();
328                    if (curpwinput.attr("type") == "text") {
329                        curpwinput.attr('type', 'password');
330                        curpwinputicon.addClass("fa-eye-slash");
331                        curpwinputicon.removeClass("fa-eye");
332                    } else if (curpwinput.attr("type") == "password") {
333                        curpwinput.attr('type', 'text');
334                        curpwinputicon.removeClass("fa-eye-slash");
335                        curpwinputicon.addClass("fa-eye");
336                    }
337                });
338            }
339        });
340    },
341
342    gotoPageHelper: function (perpage = false) {
343        val = xobor.mbt.modalPrompt("Springe zu Seite", "Seitenzahl angeben", function () {
344            var prepage = window.location.href.substring(0, window.location.href.indexOf('.html'));
345
346            if (xobor.mbt.modalpromptval < 1) { xobor.mbt.shownotice({ text: 'Das ist keine gültige Seitenzahl' }); return; }
347
348            hasPageRegex = new RegExp("(.*)-([0-9]+)$");
349            var pageMatch = prepage.match(hasPageRegex);
350            var pageval = perpage ? perpage * (xobor.mbt.modalpromptval - 1) : xobor.mbt.modalpromptval - 1;
351            var gotopage = parseInt(pageval);
352
353            var newloc = "";
354
355
356            if (window.location.toString().indexOf("show=last") > -1) {
357                /* Letzte Beiträge Seite und letzte Bilder Seite haben ein anderes URL Format */
358                if ($('div.main').hasClass('gallery')) {
359                    newloc = '/gallery.php?show=last&p=' + (gotopage + 1);
360                } else {
361                    newloc = '/forum.php?show=last&s=' + gotopage;
362                }
363            }
364
365            else if (window.location.toString().indexOf("member.php") > -1) {
366                /* Seitenzahlen bei den Themenabos haben ein eigenes Format */
367                prepage = '/member.php?abostart=';
368                newloc = prepage + gotopage;
369            }
370
371            else if (window.location.pathname.toString().indexOf("/blog") == 0) {
372                /* Hier sind wir in einem Blog */
373
374                let pageaddon = (pageval <= 0) ? "" : "-" + (pageval + 1);
375
376                let pagematch = window.location.toString().match(/-([0-9]+).html/g)
377
378                if (pagematch) {
379                    /* Es gibt schon eine Seitenzahl, erst entfernen */
380
381                    newloc = window.location.toString().replace(pagematch, "");
382                    newloc += pageaddon + ".html";
383
384                } else {
385                    /* noch keine Seitenzahl */
386
387                    newloc = window.location.toString().replace(".html", "") + pageaddon + ".html"
388                }
389            }
390
391
392            else if (window.location.toString().indexOf("search.php") > -1) {
393                /* Forensuche Seite hat ein anderes URL Format */
394
395                if (window.location.toString().indexOf("&page=") > -1) {
396                    /* Es gibt schon eine Seitenzahl, einfach tauschen */
397                    newloc = window.location.toString().replace(/&page=([0-9]+)/g, "&page=" + pageval);
398
399                } else {
400                    /* noch keine Seitenzahl */
401                    newloc = window.location.toString() + "&page=" + pageval;
402                }
403            }
404            else if ($('div.main').hasClass('gallery')) {
405                /* Gallery format: */
406
407                if (window.location.toString().indexOf("-p") > -1) {
408
409                    /* Es gibt schon eine Seitenzahl, einfach tauschen */
410                    newloc = window.location.toString().replace(/-p([0-9]+).html/g, "-p" + xobor.mbt.modalpromptval + ".html");
411
412                } else {
413                    /* noch keine Seitenzahl */
414                    newloc = window.location.toString().replace(/.html/g, "-p" + xobor.mbt.modalpromptval + ".html");
415                }
416
417                alert(newloc); return;
418
419            }
420
421
422
423
424
425            else if (window.location.toString().indexOf("userlist.php") > -1) {
426                /* Userlist Seite hat ein anderes URL Format */
427
428                prepage = '/userlist.php?page=';
429                newloc = prepage + (gotopage + 1);
430
431            }
432            else if (window.location.toString().indexOf("/private.php") > -1) {
433                /* Private Nachrichten Seite hat ein anderes URL Format */
434                let is_outbox = (window.location.search.toString().indexOf("out") > -1) ? 1 : 0;
435
436                if (is_outbox) { prepage = '/private.php?sentpage='; }
437                else { prepage = '/private.php?page='; }
438
439                newloc = prepage + (gotopage + 1);
440            }
441            else {
442
443
444                if (pageMatch) {
445                    /*Es gibt schon eine Seitenzahl, einfach austauschen*/
446                    var curpage = pageMatch[2];
447
448                    var rep_what = "-" + curpage + ".html";
449                    var rep_with = "-" + gotopage + ".html";
450                    newloc = window.location.href.replace(rep_what, rep_with);
451
452                    /*Falls der Link einen msg-Hash enthält, muss dieser entfernt werden um eine erneute Weiterleitung zu verhindern */
453                    //https://2001010.ssldev.miranus.eu/t399091f88-asdasd-1.html#msg6384979
454                    let hash_in_string = newloc.lastIndexOf("#");
455                    if (hash_in_string > 0) {
456                        newloc = newloc.substring(0, hash_in_string);
457                    }
458
459
460                } else {
461                    /* Es gibt noch keine Seitenzahl im Link */
462                    newloc = prepage + "-" + gotopage + ".html";
463                }
464            }
465
466
467            xobor.mbt.closemodal(xobor.mbt.currentmodal.attr('id'))
468            window.location = newloc;
469        }, null, 'decimal');
470    },
471
472    modal: function (selector, title, options) {
473        this.modalcount++;
474        var default_options = { modalid: "modal" + this.modalcount, modalclass: '', hide_buttons: 0, successfunction: null, closefunction: null, sizeclass: '', nostack: false }
475        var modalid, hide_buttons, successfunction, closefunction;
476
477        if (!options) { options = {}; }
478        modalid = default_options.modalid;
479        modalclass = options.modalclass ? options.modalclass : default_options.modalclass;
480        sizeclass = options.size ? 'modal-' + options.size : default_options.sizeclass;
481        nostack = options.nostack ? options.nostack : default_options.nostack;
482
483
484        hide_buttons = options.hide_buttons ? options.hide_buttons : default_options.hide_buttons;
485        closefunction = options.closefunction ? options.closefunction : default_options.closefunction;
486        successfunction = options.successfunction ? options.successfunction : default_options.successfunction;
487        preset = options.preset ? options.preset : "";
488
489        if (nostack) {
490            //reuse current modal:
491            this.modalcount--;
492            modalid = "modal" + this.modalcount;
493            $('#' + modalid).off('hidden.bs.modal');
494        } else {
495            var savebutton = "Ok";
496
497            modFooter = '<div class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">Schlie&szlig;en</button><button id="' + modalid + '_save" type="button" class="modalsavebutton btn btn-primary">' + savebutton + '</button></div>'
498            modSkel = '<div class="modal fade ' + modalclass + '" id="' + modalid + '" tabindex="-1" role="dialog" aria-labelledby="' + modalid + '" aria-hidden="true">'
499                + '<div class="modal-dialog ' + sizeclass + '">'
500                + '<div class="modal-content">'
501                + '<div class="modal-header">'
502                + '<h4 class="modal-title" id="myModalLabel">' + title + '</h4>'
503                + '<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>'
504                + '</div>'
505                + '<div class="modal-body"></div>';
506            if (!hide_buttons) { modSkel += modFooter; }
507            modSkel += '</div></div></div>';
508            $modSkel = $(modSkel);
509            $modSkel.appendTo('body');
510        }
511
512
513        if (selector.indexOf("remote-") === 0) {
514
515            $('#' + modalid).modal();
516
517            //Selector ist URL, remote Modal &ouml;ffnen...
518            url = selector.replace("remote-", "");
519            var params = {
520                openDialogRequest: true,
521                last_location: encodeURIComponent(location.href),
522                next_location: encodeURIComponent(url)
523            };
524
525            $.get(url, params, function (res) {
526                $('#modal' + xobor.mbt.modalcount).find('.modal-body').html(res);
527            });
528
529
530
531        } else if (selector.indexOf("text-") === 0) {
532            text = selector.replace("text-", "");
533            $modSkel.find('.modal-body').html(text).show();
534            $('#' + modalid).modal();
535        } else if (selector.indexOf("prompt-") === 0) {
536            text = selector.replace("prompt-", "");
537            var inputmode = "";
538            if (options.inputmode) {
539                inputmode = " inputmode='" + options.inputmode + "'";
540            }
541            input = "<input type='text' class='form-control' id='modalprompt' autocomplete='off' value='" + preset + "' " + inputmode + " >";
542            $modSkel.find('.modal-body').html(text + input).show();
543            $('#' + modalid).on('shown.bs.modal', function () {
544                $('#modalprompt').focus();
545                $('#modalprompt').select();
546            });
547            $('#' + modalid).modal();
548        }
549        else {
550
551
552            $phdiv = $("<div id='" + modalid + "_placeholder' data-originalcontent='" + selector + "' class='d-none'></div>");
553            $phdiv.insertBefore($(selector));
554
555
556            //$clone=$(selector).clone();
557            $clone = $(selector);
558
559
560            $clone.appendTo($modSkel.find('.modal-body')).show().removeClass('d-none');
561            $('#' + modalid).modal();
562        }
563
564        if (this.modalcount > 1) {
565            xobor.mbt.prevmodal = xobor.mbt.currentmodal;
566        }
567
568
569
570        $('#' + modalid + '_save').on('click', function () {
571            if ($('#modalprompt').length) {
572                xobor.mbt.modalpromptval = $('#modalprompt').val();
573            }
574            $(this).closest('.modal').modal('hide');
575        });
576
577        if (successfunction) {
578            $('#' + modalid + '_save').on('click', successfunction);
579        }
580
581        if (options.onshownfunction) {
582            xobor.log.dev("onshownfunction set ", options.onshownfunction);
583            $('#' + modalid).on('shown.bs.modal', options.onshownfunction);
584        } else {
585            xobor.log.dev("no onshownfunction set ", options);
586        }
587
588        $('#' + modalid).on('shown.bs.modal',
589            function () {
590                xobor.mbt.currentmodal = $('#' + modalid);
591                xobor.log.dev("Added modal with Id: " + modalid + " Modalcount is " + xobor.mbt.modalcount);
592
593
594            }
595        );
596
597
598
599
600        $('#' + modalid).on('hidden.bs.modal',
601            function () {
602                xobor.mbt.modalcount--;
603
604                if ($('#' + $(this).attr('id') + '_placeholder').length) {
605                    let sel = $('#' + modalid + '_placeholder').data('originalcontent');
606                    $(sel).addClass('d-none').insertAfter($('#' + $(this).attr('id') + '_placeholder'));
607                    $('#' + $(this).attr('id') + '_placeholder').remove();
608                }
609
610
611
612                if (xobor.mbt.modalcount > 0) {
613                    xobor.log.dev("Still have open modals", xobor.mbt.modalcount);
614                    $('body').addClass('modal-open');
615                    xobor.mbt.currentmodal = xobor.mbt.prevmodal
616                } else {
617                    $('body').removeClass('modal-open');
618                }
619
620                xobor.log.dev("Remove Modal " + $(this).attr('id'), xobor.mbt.modalcount);
621                $(this).remove();
622            }
623        );
624
625
626
627        if (closefunction) {
628            $('#' + modalid).find('.save').on('click', closefunction);
629        }
630
631    },
632
633    remoteModal: function (url, title, options) {
634        selector = "remote-" + url;
635        options = options ? options : {};
636        if (!options['show_buttons']) {
637            options['hide_buttons'] = true;
638        }
639
640        return this.modal(selector, title, options);
641    },
642
643
644    /*Animations*/
645    animate: function (sel, type) {
646        var curtype = type;
647        $(sel).removeClass('animate__animated').removeClass('animate__' + curtype);
648
649        setTimeout(function () {
650            $(sel).addClass('animate__' + type + ' animate__animated').on('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function () {
651                $(this).removeClass('animate__animated').removeClass('animate__' + curtype);
652            });
653        }, 1000);
654
655    },
656
657
658    xDateFormat: function (t) {
659        cur = t ? t : 0;
660        if ((cur + "").length < 13) { cur = cur * 1000 };
661        off = timezone_user_offset ? timezone_user_offset : 0;
662        now = new Date();
663        if (typeof time_diff_to_server === 'undefined') {
664            var time_diff_to_server = false;
665        }
666
667        if (time_diff_to_server) { curts = Date.parse(now); now.setTime(curts + time_diff_to_server); }
668
669        now_s = now.getFullYear() + ' ' + (now.getMonth() + 1) + ' ' + now.getDate();
670        today_start = Date.parse(now_s);
671
672        yesterday_start = today_start - 24 * 60 * 60 * 1000;
673        diff = (Date.parse(now) - cur) / 1000;
674
675        if (diff < (60)) { return '{[time_minute_one]}' }	//diff kleiner als 1 minute?
676        else if (diff < (60 * 30)) { mins = Math.ceil(diff / 60); res = '{[time_minute_more]}'.replace("%minutes", mins); }	//diff kleiner als 30 minuten?
677        else if (cur > today_start) { cur = cur + off; res = dateFormat(cur, "today"); }	//cur größer als today_start
678        else if (cur > yesterday_start) { cur = cur + off; res = dateFormat(cur, "yesterday"); }	//cur größer als yesterday_start
679        else { cur = cur + off; res = dateFormat(cur, "norm"); }	//standard-formatierung:
680
681
682        return res;
683    },
684    xtrack: function (track_what, tracking_id) {
685        let trackingurl = '/ajax/handler.php?method=hitcounter';
686        let cururl = trackingurl + "&what=" + track_what + "&whatid=" + tracking_id;
687        let param_string = "";
688        $.get(cururl, function (res) { console.log(res) });
689        return true;
690    },
691
692
693    /*Validation*/
694    validateform: function (sel) {
695
696        xobor.log.dev("Check Form", sel);
697
698
699        // can-SSL Check
700        if (typeof $(sel).data('canssl') !== 'undefined' && $(sel).data('canssl') === 1) {
701
702            var actionLink = (typeof $(sel)[0].action !== '' && $(sel)[0].action !== '' ? $(sel)[0].action : location.href);
703            $(sel)[0].action = actionLink.replace(/^http:/, 'https:');
704        }
705
706        /*Alle Submit-Buttons disablen, um doppelversand vorzubeugen*/
707        $.each($(sel).find(':submit'), function () {
708            $(this).data('onclick', $(this).attr('onclick'));
709            $(this).attr('onclick', 'return false');
710        });
711
712
713
714
715        var inputs = $(sel).find("input,select,textarea").not(':disabled');
716        xobor.log.dev("Inputs: ", inputs);
717        $.each(inputs, function () {
718            if ($(this).closest('.form-group').hasClass('has-error')) {
719                $(this).closest('.form-group').removeClass('has-error');
720            }
721        });
722        var handled = [];
723        var identifier = "";
724        $.each(inputs, function () {
725            if ($(this).attr('data-validate')) {
726
727                identifier = $(this).attr('name');
728                xobor.log.dev("Inputs ", $(this));
729
730                if ($.inArray(identifier, handled) < 0) {
731                    xobor.mbt.validateel($(this));
732                    handled.push(identifier);
733                } else {
734                    xobor.log.dev("Input " + identifier + " already checked", handled);
735                }
736
737
738            }
739        });
740
741        //Bei PNs ausserdem pr&uuml;fen, ob ein Empf&auml;nger angegeben wurde:
742        if ($(sel).attr('id') == 'sendmail') {
743            var user_set = 0;
744            $.each($(sel).find('.userinput'), function () {
745                if ($(this).val() != "") { user_set = 1; }
746            });
747
748            if (!user_set) {
749                var errortext = xobor.mbt.constants.validationstrings.norecs;
750                xobor.mbt.shownotice({ title: 'Fehler', text: errortext, type: 'error' });
751                $('#name').closest('.form-group').addClass('has-error');
752            }
753
754        }
755
756        var form_has_errors = 0;
757        $.each(inputs, function () {
758            if (!$(this).closest('.form-group').hasClass('has-error')) {
759                $(this).closest('.form-group').addClass('has-success');
760            } else {
761
762                form_has_errors = 1;
763            }
764
765        });
766
767        if (form_has_errors) {
768            //submitbuttons wieder enablen;
769            $.each($(sel).find(':submit'), function () {
770                $(this).removeAttr('disabled');
771                if ($(this).data('onclick')) { $(this).attr('onclick', $(this).data('onclick')); }
772                else { $(this).attr('onclick', ''); }
773            });
774        }
775
776
777        return form_has_errors ? false : true;
778
779    },
780
781    validatenotempty: function ($el, val) {
782        $group = $el.closest('.form-group');
783        if (!val || val == '') {
784            $group.addClass('has-error');
785            xobor.mbt.addtodata($group, 'errors', 'notempty');
786            var errortext = xobor.mbt.constants.validationstrings.notempty;
787            errortext = errortext.replace("%input%", "<strong>" + $el.attr('placeholder') + "</strong>");
788            xobor.mbt.shownotice({ title: 'Fehler', text: errortext, type: 'error' });
789            return false;
790
791        }
792        return true;
793    },
794    validatelength: function ($el, val, param) {
795        $group = $el.closest('.form-group');
796        val = val + "";
797        if (parseInt(val.length) !== parseInt(param)) {
798            $group.addClass('has-error');
799            xobor.mbt.addtodata($group, 'errors', 'length');
800            var errortext = xobor.mbt.constants.validationstrings.length;
801            errortext = errortext.replace("%length%", param);
802            errortext = errortext.replace("%input%", "<strong>" + $el.attr('placeholder') + "</strong>");
803            xobor.mbt.shownotice({ title: 'Fehler', text: errortext, type: 'error' });
804            return false;
805        }
806
807        return true;
808    },
809    validateminlength: function ($el, val, param) {
810        $group = $el.closest('.form-group');
811        val = val + "";
812        if (val.length < param) {
813            $group.addClass('has-error'); xobor.mbt.addtodata($group, 'errors', 'minlength');
814            var errortext = xobor.mbt.constants.validationstrings.minlength;
815            errortext = errortext.replace("%length%", param);
816            errortext = errortext.replace("%input%", "<strong>" + $el.attr('placeholder') + "</strong>");
817            xobor.mbt.shownotice({ title: 'Fehler', text: errortext, type: 'error' });
818            return false;
819        }
820        return true;
821    },
822    validatemaxlength: function ($el, val, param) {
823        $group = $el.closest('.form-group');
824        val = val + "";
825        if (val.length > param) {
826            $group.addClass('has-error'); xobor.mbt.addtodata($group, 'errors', 'maxlength');
827            var errortext = xobor.mbt.constants.validationstrings.maxlength;
828            errortext = errortext.replace("%length%", param);
829            errortext = errortext.replace("%input%", "<strong>" + $el.attr('placeholder') + "</strong>");
830            xobor.mbt.shownotice({ title: 'Fehler', text: errortext, type: 'error' });
831            return false;
832        }
833        return true;
834    },
835    validateemail: function ($el, val) {
836        $group = $el.closest('.form-group');
837        val = val + "";
838        if (!val || val == "") { val = "notvalid"; }
839        pattern = xobor.mbt.constants.validationpatterns.email;
840
841        if (!pattern.test(val)) {
842            $group.addClass('has-error'); xobor.mbt.addtodata($group, 'errors', 'email');
843            var errortext = xobor.mbt.constants.validationstrings.email;
844            xobor.mbt.shownotice({ title: 'Fehler', text: errortext, type: 'error' });
845            return false;
846        }
847        return true;
848    },
849
850    validateel: function ($el) {
851        try {
852            var to_validate = $el.data('validate').split(",");
853        } catch (e) {
854            xobor.log.dev("Error validation el ", $el);
855            return;
856        }
857        $el.val($el.val().trim());
858        var elval = $el.val();
859        var param = 0;
860
861        xobor.log.dev('ValidateEl', to_validate, elval);
862
863        $.each(to_validate, function (k, v) {
864            if (v.indexOf("_")) {
865                v = v.split("_");
866                param = v[1];
867                v = v[0];
868            }
869
870            if ($el.attr('type') == "checkbox" || $el.attr('type') == "radio") {
871                //checkboxen behandeln - hier gibt es nur "mandatory"
872
873
874                $radios = $el.closest('.form-group').find('input[type="' + $el.attr('type') + '"]');
875
876                var elchecked = 0;
877                $.each($radios, function () {
878                    if ($(this).is(':checked')) { elchecked = 1; }
879                });
880
881                if (!elchecked) {
882                    $el.closest('.form-group').addClass('has-error');
883                    var errortext = xobor.mbt.constants.validationstrings.notempty;
884                    errortext = errortext.replace("%input%", "<strong>" + $el.attr('placeholder') + "</strong>");
885                    xobor.mbt.shownotice({ title: 'Fehler', text: errortext, type: 'error' });
886                }
887            }
888            else if ($el.attr('type') == "radio") {
889                //radio behandeln
890
891
892            } else if ($el[0].nodeName == "SELECT") {
893                if (v == 'notnull') {
894                    //Make sure Textarea does nto have first value selected.
895                    if ($el[0].selectedIndex === 0) {
896                        $el.closest('.form-group').addClass('has-error');
897                        var errortext = xobor.mbt.constants.validationstrings.notempty;
898                        errortext = errortext.replace("%input%", "<strong>" + $el.closest('.form-group').find('label').text() + "</strong>");
899                        xobor.mbt.shownotice({ title: 'Fehler', text: errortext, type: 'error' });
900                    }
901                }
902            }
903            else {
904                switch (v) {
905                    case 'notempty': xobor.mbt.validatenotempty($el, elval); break;
906                    case 'length': xobor.mbt.validatelength($el, elval, param); break;
907                    case 'email': xobor.mbt.validateemail($el, elval); break;
908                    case 'maxlength': xobor.mbt.validatemaxlength($el, elval, param); break;
909                    case 'minlength': xobor.mbt.validateminlength($el, elval, param); break;
910                    default: return true;
911                }
912            }
913        });
914    },
915
916    addtodata: function ($el, attr, val) {
917        if (!$el.data(attr)) { $el.data(attr, val); }
918        else {
919            if ($el.data(attr).indexOf(";" + val) < 0) {
920                $el.data(attr, $el.data(attr) + ";" + val);
921            }
922        }
923    },
924    doPNMassOptions: function (data) {
925
926        var action = data.action;
927
928        var message_ids = data.ids;
929        var inbox = data.inbox ? 1 : 0;
930        var outbox = data.outbox ? 1 : 0;
931
932
933        var actionurl = "/private_new.php?&option=delete";
934        var postdata = { 'ajax': 1, 'delmsg': message_ids, 'inbox': inbox, 'outbox': outbox };
935
936        if (action == 'deltrue') {
937            postdata.deltrue = 1;
938        }
939        else if (action == 'markall') {
940            postdata.markall = 1;
941        }
942
943        $.post(actionurl, postdata, function (res) {
944            if (res && res.done) { location.reload(); }
945            else { console.log(res); }
946        });
947
948    },
949
950    setEnterHandler: function () {
951        /*Catch when a user presses enter */
952        $(document).keypress(function (event) {
953            var keycode = (event.keyCode ? event.keyCode : event.which);
954            if (keycode == '13') {
955                /*If modal is opened, press submit button */
956                if ($('.modalsavebutton').length == 1) { $('.modalsavebutton').trigger('click'); }
957            }
958        });
959    },
960
961    setMenuHandler: function () {
962        $('.navbar-toggler').on('click',
963            function () {
964                $(this).closest('.navbar').toggleClass('collapsed');
965
966            }
967        );
968    },
969
970    markasread: function (what, id) {
971        switch (what) {
972            case 'n': return xobor.mbt.notificationread(id); break;
973            default: return false;
974        }
975
976    },
977    notificationread: function (id) {
978        $.get("/ajax/handler.php?method=inforead&nid=" + id, function (res) { });
979    },
980
981
982    pnotifyinitialized: false,
983
984    initnotifications: function (inEffect = 'fadeIn', outEffect = 'fadeOut') {
985        if (xobor.mbt.pnotifyinitialized) { return; }
986
987        try {
988            xobor.log.dev("Init Notifications");
989
990            var windowwidth = $(window).width();
991            if (windowwidth > 600) {
992                PNotify.defaults.width = '400px';
993            } else {
994                PNotify.defaults.width = (windowwidth - 50) + "px";
995            }
996
997            PNotify.defaults.styling = 'bootstrap4';
998            PNotify.defaults.icons = 'fontawesome5';
999
1000
1001            PNotify.defaults.textTrusted = true;
1002
1003            PNotify.modules.Animate.defaults.inClass = inEffect;
1004            PNotify.modules.Animate.defaults.outClass = outEffect;
1005            PNotify.modules.Buttons.defaults.closer = true;
1006            PNotify.modules.Buttons.defaults.sticker = true;
1007
1008
1009        } catch (e) {
1010            xobor.log.error("Error setting Pnotify defaults:", e);
1011        }
1012        xobor.mbt.pnotifyinitialized = true;
1013
1014
1015    },
1016
1017    shownotice: function (params, noclose) {
1018
1019        /*
1020       * Eigenes Icon:
1021       * params.icon = 'far fa-envelope';
1022       * params.icon = 'xob xob-information';
1023       *
1024       * */
1025
1026
1027        xobor.mbt.initnotifications();
1028        PNotify.alert(params);
1029    },
1030
1031    hidemobile: function () {
1032        xobor.cookie.set('nomobile', 1, 1);
1033        location.reload();
1034    },
1035
1036    notimplemented: function () {
1037        alert("Diese Funktion steht in K&uuml;rze zur Verf&uuml;gung");
1038        return;
1039    },
1040
1041    refreshtooltips: function () {
1042        $(function () {
1043            $('[data-toggle="tooltip"]').tooltip();
1044        });
1045    },
1046
1047
1048    googlefontsloaded: {},
1049    loadGoogleFont: function (link) {
1050
1051        let head = document.getElementsByTagName('head')[0];
1052
1053        if (!$('#gapi_preconnect').length) {
1054            let link1 = document.createElement('link');
1055            link1.rel = 'preconnect';
1056            link1.setAttribute('id', "gapi_preconnect");
1057            link1.href = 'https://fonts.googleapis.com';
1058            head.appendChild(link1);
1059        }
1060
1061        if (!$('#gstatic_preconnect').length) {
1062
1063            let link2 = document.createElement('link');
1064            link2.rel = 'preconnect';
1065            link2.setAttribute('id', "gstatic_preconnect");
1066            link2.href = 'https://fonts.gstatic.com';
1067            head.appendChild(link2);
1068        }
1069
1070
1071        if (!xobor.mbt.googlefontsloaded[link]) {
1072            let fontcsslink = document.createElement('link');
1073            fontcsslink.rel = 'stylesheet';
1074            fontcsslink.type = 'text/css';
1075            fontcsslink.href = link;
1076            head.appendChild(fontcsslink);
1077            xobor.mbt.googlefontsloaded[link] = 1;
1078        }
1079
1080    },
1081
1082    loadComments: function (target, ttype, tid, page) {
1083        var curpage = page ? page : 1;
1084
1085        xobor.mbt.currenticonbarcontainer = false;
1086
1087        var $targetbase = $('body');
1088        if ($('.modal-content:visible').length) {
1089            $targetbase = $('.modal-content');
1090        }
1091        $target = $targetbase.find(target);
1092
1093        var url = "/ajax/handler.php?method=getComments&ttype=" + ttype + "&tid=" + tid + "&page=" + curpage;
1094        $.get(url, function (res) {
1095
1096            if (res.done) {
1097                if ($target.length) {
1098                    $('.ekko-lightbox').find('.pic_info_details').removeClass('d-none');
1099                    $target.removeClass('animate__animated').addClass('animate__fadeIn').addClass('animate__animated');
1100                    $target.removeClass('d-none').show();
1101
1102                    $('.ekko-lightbox').find(target).html(xobor.helper.decodeHTML(res.comments));
1103                    $('.ekko-lightbox').find(target).focus();
1104                    $('.ekko-lightbox').animate({
1105                        scrollTop: $('.ekko-lightbox').find(target).offset().top
1106                    }, 500);
1107
1108                    xobor.mbt.loadRecaptcha();
1109
1110
1111                } else {
1112                    var errortext = "Zielelement nicht gefunden";
1113                    xobor.mbt.shownotice({ title: 'Fehler', text: errortext, type: 'error' });
1114                }
1115            } else {
1116                var errortext = "Fehler beim Laden der Kommentare. Bitte versuchen Sie es sp&auml;ter noch einmal";
1117                xobor.mbt.shownotice({ title: 'Fehler', text: errortext, type: 'error' });
1118            }
1119        });
1120    },
1121    addComment: function (formselector) {
1122        $form = $(formselector);
1123        url = xobor.mbt.actionurls.contenthandler;
1124
1125        action = "add"
1126        ctype = $form.find('#ctype').val()
1127
1128        comment = {
1129            "cid": $form.find('#cid').val(),
1130            "pid": $form.find('#pid').val(),
1131            "commentar": xobor.mbt.convert2entity($form.find('#commentar').val()),
1132            "name": $form.find('#name').val(),
1133            "comment_subscribe": $form.find('#comment_subscribe:checked').val(),
1134        };
1135
1136        try {
1137            comment["g-recaptcha-response"] = grecaptcha.getResponse();
1138        } catch (e) {/*no captcha*/ }
1139
1140
1141
1142        postdata = { action: action, ctype: ctype, data: comment };
1143
1144        $.post(url + "?action=" + action + "&ctype=" + ctype, postdata, function (res) {
1145            if (res.error) {
1146                xobor.mbt.shownotice({ title: 'Fehler', text: res.error, type: 'error' });
1147            } else if (res.errors) {
1148                $.each(res.errors, function () {
1149
1150                    errortext = xobor.mbt.errortexts[this] === undefined ? this : xobor.mbt.errortexts[this];
1151                    xobor.mbt.shownotice({ title: 'Fehler', text: errortext, type: 'error' });
1152                });
1153
1154            } else if (res.done) {
1155                xobor.mbt.loadComments('#pic_' + comment.pid + '_comments', '11', comment.pid);
1156            }
1157
1158        });
1159
1160        return true;
1161    },
1162    getCurrentUser: function () {
1163        if (xobor.mbt.currentUser) { return xobor.mbt.currentUser; }
1164
1165        //f&uuml;rs erste reicht uns ein object mit ein paar Basisdaten. Sp&auml;ter eventuell deeop data call hier einrichten...
1166        u = {
1167            user_id: xobor.mbt.current_user_id,
1168            uname: xobor.mbt.current_user_name,
1169        }
1170        return u;
1171        /*
1172        if(isInt(xobor.mbt.current_user_id)){
1173            var userdata = {
1174                "target_type":3,
1175                "target_id":xobor.mbt.current_user_id,
1176                "get_type" : "deepdata",
1177                "ttype" : 3,
1178                "tid" : xobor.mbt.current_user_id,
1179
1180            }
1181
1182
1183
1184            pluginurl = 'http://' + window.location.hostname + '/ajax/pluginapi.php?pid='+ ((typeof pid !== 'undefined') ? pid : 'null');
1185
1186            $.ajax({
1187                    url: pself.ajaxUrl+url,
1188                    type: type,
1189                    cache: xobor.config.ajaxCache,
1190                    async: false,
1191                    data: data,
1192                    success: function(response) {
1193            '&function=getDeep
1194
1195            u = xobor.plugin(_tempPluginId,false).getDeep(userdata);
1196        }*/
1197
1198
1199    },
1200    deleteTempIntegration: function (elid) {
1201        var el = $('#preview_' + elid)[0];
1202        var el_index = $('.intpreview').index(el);
1203
1204        $('.hiddeninput_' + el_index).remove();
1205        $(el).remove();
1206        all_integration--;
1207
1208        if ($('#miranus_integration_container .intdiv').length === 0) {
1209            $('#miranus_integration_container').hide();
1210        }
1211
1212        return true;
1213    },
1214
1215
1216    currentConfirmvals: {},
1217    deleteIntegration: function (iid, targetId, confirmed = false) {
1218
1219        if (!confirmed) {
1220            xobor.mbt.currentConfirmvals.iid = iid;
1221            xobor.mbt.currentConfirmvals.targetId = targetId;
1222            return xobor.mbt.modalConfirm("Integration löschen", "Möchten Sie diese Verknüpfung wirklich löschen?", function () { xobor.mbt.deleteIntegration(xobor.mbt.currentConfirmvals.iid, xobor.mbt.currentConfirmvals.targetId, 1) });
1223        }
1224
1225        if (typeof (iid) == 'undefined') {
1226            return false;
1227        } else {
1228            /* Integration existiert bereits */
1229            if (typeof (targetId) == 'undefined') {
1230                var target_id = false;
1231            }
1232
1233            $.ajax({
1234                type: "POST",
1235                url: xobor.mbt.actionurls.deleteIntegration,
1236                data: { del: true, target_id: targetId, i_id: iid },
1237                success: function (result) {
1238                    if ($('#int_' + iid).closest('.integrations').find('.integration').length === 1) {
1239                        $('#int_' + iid).closest('.xnonquoteable').find('.integration_container_header').remove();
1240                        $('#int_' + iid).closest('.integrations').remove();
1241                    } else {
1242                        $('#int_' + iid).closest('.integration').remove();
1243                    }
1244                }
1245            });
1246        }
1247
1248    },
1249    iconbar: {
1250        insertIntegration: function (el) {
1251            var abc = new Array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');
1252            var char_index = $('.intpreview').index(el);
1253            return xobor.mbt.iconbar.insertBBCode("[widget=" + abc[char_index] + "]");
1254        },
1255        insertBBCode: function (tag1, tag2) {
1256
1257            if (!xobor.mbt.currenticonbarcontainer) {
1258                //versuche die aktuelle Textarea zu finden.
1259                if ($('textarea').length === 1) {
1260                    xobor.mbt.currenticonbarcontainer = $('textarea').first();
1261                } else if ($('#messagetext').length === 1) {
1262                    xobor.mbt.currenticonbarcontainer = $('#messagetext');
1263                }
1264                else {
1265                    var errortext = "Der Iconbar konnte keine Textarea zugewiesen werden.";
1266                    xobor.mbt.shownotice({ title: 'Fehler', text: errortext, type: 'error' });
1267                }
1268            }
1269
1270            /* Character Encoding Fix */
1271
1272            $tag1 = $("<div>").html(tag1).html();
1273            $tag2 = $("<div>").html(tag2).html();
1274            $tag1 = $tag1.replace(/&amp;/g, "&");
1275            $tag2 = $tag2.replace(/&amp;/g, "&");
1276
1277
1278            if (xobor.mbt.currenticonbarcontainer) {
1279                xobor.mbt.currenticonbarcontainer.insertAtCaret($tag1, $tag2);
1280            }
1281        },
1282        loadIcons: function (sel) {
1283            if ($('.modal').find(sel).hasClass('nofix')) {
1284                $.each($('.modal').find(sel).find('.xob_icon_cont img'), function () {
1285                    $(this).attr('src', $(this).data('orig'));
1286                });
1287                $('.modal').find(sel).removeClass('nofix').addClass('fixed');
1288
1289            }
1290        }
1291    },
1292    handlePicWidthChange: function () {
1293
1294    },
1295
1296
1297
1298    addallimagestopost: function () {
1299        return this.addimagetopost('all', null);
1300    },
1301    addimagetopost: function (id, title, isvideo) {
1302        let $img = $('#upload_' + id);
1303        $img.addClass("addedtopost");
1304
1305        $('#insertpicmodal').remove();
1306
1307        let $newmodalcont = $("<div>" + $('#insert_pic_template').html() + "</div>");
1308
1309        let filedata = false;
1310        let bulk = false;
1311        let onclickstring = "";
1312
1313        if (id == 'all') {
1314
1315            bulk = true;
1316            for (var f in tempfiles) {
1317                let fid = tempfiles[f]['tempname'].replace(/\.[^/.]+$/, "");
1318                if (onclickstring !== "") { onclickstring += " "; }
1319                onclickstring += "insertCustomPicTag('" + id + "','" + xobor.mbt.convert2entity(tempfiles[f]['filename']) + "');";
1320                filedata = tempfiles[f];
1321                /*
1322                if(tempfiles[f]['isimg']){
1323                    onclickstring += "insertCustomPicTag('"+id+"','"+xobor.mbt.convert2entity(tempfiles[f]['filename'])+"');";
1324                    filedata = tempfiles[f];
1325                }
1326                if(tempfiles[f]['isvideo']){
1327                    onclickstring += "xobor.mbt.iconbar.insertBBCode('[[File:"+filedata.filename+"]]')";
1328                    filedata = tempfiles[f];
1329                }*/
1330            }
1331
1332        } else if (Number.isInteger(id)) {
1333            filedata = tempfiles[id];
1334        } else {
1335            for (var f in tempfiles) {
1336                try {
1337                    if (tempfiles[f].filelink.indexOf(id) > -1) { filedata = tempfiles[f]; }
1338                } catch (e) {
1339                    console.log(tempfiles, id);
1340                }
1341            }
1342        }
1343
1344
1345        //if(isvideo) return xobor.mbt.iconbar.insertBBCode('[[File:'+filedata.filename+']]')
1346
1347
1348
1349        $newmodalcont.find('#img__width').attr('id', 'img_' + id + '_width').html(filedata.size_x);
1350        $newmodalcont.find('#img__height').attr('id', 'img_' + id + '_height').html(filedata.size_y);
1351        $newmodalcont.find('.insert_pic_div').attr('id', 'pic_insert_' + id);
1352
1353        $newmodalcont.find('.insert_pic_width').attr('onclick', 'handlePicWidthChange(\'' + id + '\')');
1354
1355        if (bulk) {
1356            $newmodalcont.find('.closemodal').attr('onclick', onclickstring);
1357        } else {
1358            $newmodalcont.find('.closemodal').attr('onclick', 'insertCustomPicTag(\'' + id + '\',\'' + title + '\')');
1359        }
1360
1361
1362        $newmodalcont.find('.insert_pic_div').removeClass('insert_pic_div').addClass('insert_pic_div_active');
1363
1364
1365        $('<div id="insertpicmodal" class="modalcont d-none">\n' +
1366            $newmodalcont.html() +
1367            '</div>').appendTo('body');
1368
1369
1370        var opts = { hide_buttons: 1 };
1371        xobor.mbt.modal("#insertpicmodal", $('#insert_pic_template').attr('title'), opts);
1372        /*
1373        tag = "[[File:"+$img.data('filename')+"|none|auto]]";
1374        xobor.mbt.iconbar.insertBBCode(tag);*/
1375    },
1376
1377    convert2entity: function (utf8_string) {
1378        /* Wir haben utf8 und convertieren nichts mehr !*/
1379        return utf8_string;
1380        /*
1381        var html_entity = "";
1382        if (!utf8_string) { return ""; }
1383
1384        if (typeof (utf8_string == 'array')) {
1385            utf8_string = { arr: utf8_string };
1386            doarray = 1;
1387        }
1388        if (typeof (utf8_string == 'object')) {
1389            utf8_string = JSON.stringify(utf8_string);
1390            dojson = 1;
1391        }
1392
1393
1394        for (i = 0; i <= utf8_string.length; i++) {
1395            if (utf8_string.charCodeAt(i) > 127) {
1396                html_entity += "&#" + utf8_string.charCodeAt(i) + ";";
1397            }
1398            else {
1399                html_entity += utf8_string.charAt(i);
1400            }
1401        }
1402        if (dojson) { html_entity = JSON.parse(html_entity); }
1403        if (doarray) { html_entity = html_entity.arr; }
1404        return html_entity;*/
1405
1406
1407    },
1408    convert2entity2: function (utf8_string) {
1409        var html_entity = "";
1410        for (var i = 0; i < utf8_string.length; i++) {
1411            var code = utf8_string.charCodeAt(i);
1412            var hi, low;
1413            if (code < 128) {
1414                html_entity += utf8_string.charAt(i);
1415            }
1416            else if (0xD800 <= code && code <= 0xDBFF) {
1417                hi = code;
1418                low = utf8_string.charCodeAt(i + 1);
1419                if (isNaN(low)) {
1420                    throw 'High surrogate not followed by ' +
1421                    'low surrogate in  convert2entity()';
1422                }
1423                i++;
1424                code = ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;
1425                html_entity += "&#x" + code.toString(16).toUpperCase() + ";";
1426            }
1427            else {
1428                html_entity += "&#" + utf8_string.charCodeAt(i) + ";";
1429            }
1430        }
1431        return html_entity;
1432    },
1433    parseEmoji: function (str) {
1434        return str.replace(/(&#\d+;){2}/g, function (match) {
1435            match = match.replace(/&#/g, '').split(';');
1436            var binFirst = (parseInt('0x' + parseInt(match[0]).toString(16)) - 0xd800).toString(2);
1437            var binSecond = (parseInt('0x' + parseInt(match[1]).toString(16)) - 0xdc00).toString(2);
1438            binFirst = '0000000000'.substr(binFirst.length) + binFirst;
1439            binSecond = '0000000000'.substr(binSecond.length) + binSecond;
1440            return '&#x' + (('0x' + (parseInt(binFirst + binSecond, 2).toString(16))) - (-0x10000)).toString(16) + ';';
1441        });
1442
1443
1444    },
1445    fixhover: function (el) {
1446        $el2 = $(el).clone();
1447        $(el).replaceWith($el2);
1448    },
1449
1450    togglemodal: function (what) {
1451        whatmodal = what ? what : 'user';
1452
1453        if ($('body').hasClass('fullpagemodal')) {
1454            //modal active, hide:
1455            xobor.mbt.hidemodal(whatmodal);
1456        } else {
1457            xobor.mbt.showmodal(whatmodal);
1458        }
1459    },
1460    removeWarning: function (target_id, ttype, iid) {
1461
1462
1463
1464        var params = { 'target_id': target_id, 'target_type': ttype, 'integration_id': iid };
1465
1466
1467        $.post(xobor.mbt.actionurls.unwarnurl, params, function (rdata) {
1468            //rdata = JSON.parse(res);
1469            if (rdata.done) { location.reload(); }
1470            else {
1471                if (rdata.errormsg) {
1472                    if (rdata.errormsg == "notactive") { alert("{[notactive]}") }
1473                    if (rdata.errormsg == "norights") { alert("{[norights]}") }
1474                    if (rdata.errormsg == "notfound") { alert("{[notfound]}") }
1475                }
1476            }
1477        });
1478    },
1479
1480    doWarning() {
1481
1482        if ($('.modalsavebutton').hasClass('loading')) return false;
1483
1484        var targetid = document.getElementById("hidden_targetid").value;
1485        var ttype = document.getElementById("hidden_targettype").value;
1486        var selVal = document.getElementById("warntype_select").selectedIndex;
1487        var warntype = document.getElementById("warntype_select").options[selVal].value;
1488        var doPn = document.getElementById("dopn").value;
1489        var custPn = document.getElementById("custpn").value;
1490
1491        var params = { "target_id": targetid, "target_type": ttype, "warning_type": warntype, "dopn": doPn }
1492
1493        var custwarning = false;
1494        if (warntype == "custom") {
1495            custwarning = document.getElementById("custwarning").value;
1496            if (custwarning == "") { try { document.getElementById("custwarning_error").style.display = 'block'; return true; } catch (e) { } }
1497            custwarning = xobor.mbt.convert2entity(custwarning);
1498            params.warning_string = custwarning;
1499        }
1500
1501        var pnText = "";
1502        var skipescape = 0;
1503        if (custPn) { pnText = $('#custpntext').val(); }
1504        else {
1505            if (custwarning) { pnText = custwarning; skipescape = 1; }
1506            else { pnText = document.getElementById("warnoptdesc_" + warntype).innerHTML; }
1507        }
1508
1509        if (!skipescape) { pnText = xobor.mbt.convert2entity(pnText); }
1510        params.pn_string = pnText;
1511
1512
1513
1514
1515        $.post(xobor.mbt.actionurls.warnurl, params, function (rdata) {
1516            //rdata = JSON.parse(res);
1517            if (rdata.done) { location.reload(); }
1518            else {
1519                $('.modalsavebutton').removeClass('loading');
1520
1521                if (rdata.errormsg) {
1522                    if (rdata.errormsg == "notactive") { alert("{[notactive]}") }
1523                    if (rdata.errormsg == "norights") { alert("{[norights]}") }
1524                    if (rdata.errormsg == "notfound") { alert("{[notfound]}") }
1525                }
1526            }
1527        });
1528
1529    },
1530
1531    showWarningModal: function (targetid, targettype) {
1532        document.getElementById("hidden_targetid").value = targetid;
1533        document.getElementById("hidden_targettype").value = targettype;
1534
1535        $('#warnmodal').css('display', 'block');
1536
1537        let options = {};
1538        options.successfunction = function () {
1539            xobor.mbt.doWarning();
1540        };
1541
1542        this.modal("#warnmodal", "", options);
1543
1544        //prüfen, ob treshold erreicht wird:
1545        try {
1546            document.getElementById("warnmodal").className = "";
1547            if (document.getElementById("warn_treshold_" + targetid)) {
1548                document.getElementById("warnmodal").className = "treshold";
1549            }
1550        }
1551        catch (e) { console.log(e); }
1552
1553    },
1554
1555    showmodal: function (what) {
1556
1557        $('body').addClass(what + 'modal');
1558        $('body').addClass('showpagemodal');
1559
1560        if (what !== "chat") {
1561            $('body').addClass('modal').show();
1562        }
1563
1564
1565        var topvalue = $(window).scrollTop();
1566        $('#' + what + 'modal').css('top', topvalue + 'px');
1567        $('.fullpagemodal').hide();
1568
1569        $('#' + what + 'modal').show();
1570
1571        if (what == 'user') {
1572            $('#usermodal').show().addClass('animate__fadeInRight').addClass('animate__animated').addClass('animate__faster');
1573        }
1574
1575        $('.overlay.fullpagemodal').on('click', function (e, what) {
1576            if ($(this).attr('id') == 'chatmodal') { return; }
1577            e.stopPropagation();
1578            xobor.mbt.hidemodal(what);
1579        })
1580
1581    },
1582    hidemodal: function (what) {
1583
1584        $('#' + what + 'modal').fadeOut(300);
1585        $('body').removeClass(what + 'modal');
1586        $('body').removeClass('showpagemodal');
1587        $('body').removeClass('modal');
1588        if (what == 'user') {
1589            $('#' + what + 'modal').addClass('animate__fadeOutRight').addClass('animate__animated').addClass('animate__faster');
1590        } else {
1591            $('#' + what + 'modal').hide()
1592        }
1593    },
1594
1595
1596    closemodal: function (id) {
1597        $('#' + id).modal('hide');
1598    },
1599
1600    toggleusermodal: function () {
1601        //return xobor.mbt.togglemodal('user');
1602        if ($('body').hasClass('usermodal')) {
1603            //modal active, hide:
1604            xobor.mbt.closeusermodal();
1605        } else {
1606            xobor.mbt.showusermodal();
1607            $('body').addClass('usermodal');
1608        }
1609
1610    },
1611    showusermodal: function () {
1612        $('body').addClass('usermodal');
1613        var topvalue = $(window).scrollTop();
1614        $('#usermodal').css('top', topvalue + 'px');
1615
1616    },
1617    closeusermodal: function () {
1618
1619        $('#usermodal').hide();
1620        $('body').removeClass('usermodal').removeClass('showpagemodal').removeClass('modal');
1621    },
1622
1623    scriptsLoaded: {},
1624    loadScript: function (script, name) {
1625
1626
1627        if (typeof (sname) == 'undefined') {
1628            var doit = 0;
1629            switch (script) {
1630                case 'legacy':
1631                    load_url = xobor.mbt.jsurls.legacy_js;
1632                    doit = xobor.mbt.scriptsLoaded.legacy === undefined ? 1 : 0;
1633                    xobor.mbt.scriptsLoaded.legacy = 1;
1634                    break;
1635                case 'jquery': load_url = jq_source; doit = jq_added ? 0 : 1; jq_added = 1; break;
1636                case 'titletags': load_url = title_source; doit = title_added ? 0 : 1; title_added = 1; break;
1637                case 'jqueryui': load_url = jqui_source; doit = jqui_added ? 0 : 1; jqui_added = 1; break;
1638                case 'contextmenu': load_url = context_source; doit = context_added ? 0 : 1; context_added = 1; break;
1639                case 'integrations': load_url = xobor.mbt.jsurls.integrations_js;
1640                    doit = xobor.mbt.scriptsLoaded.integrations === undefined ? 1 : 0;
1641                    xobor.mbt.scriptsLoaded.integrations = 1;
1642                    break;
1643                default: xobor.log.warning('No Source for Script ' + script);
1644            }
1645            if (doit) {
1646                xobor.log.dev('Add Script ' + script, load_url);
1647                var e = document.createElement('script');
1648                e.src = load_url;
1649                e.async = false;
1650                document.documentElement.getElementsByTagName("HEAD")[0].appendChild(e);
1651            } else {
1652
1653            }
1654        }
1655        else {
1656            title = sname.toLowerCase();
1657            source = script;
1658            if (title == "jquery") {
1659                try { $('<div>'); return true; } catch (e) { }
1660            }
1661            load_url = source;
1662            if (xscriptsloaded.indexOf(title) < 0) {
1663                xscriptsloaded.push(title);
1664                var e = document.createElement('script');
1665                e.src = load_url;
1666                e.async = false;
1667                docstate = document.readyState;
1668                document.documentElement.getElementsByTagName("HEAD")[0].appendChild(e);
1669            }
1670        }
1671    },
1672    updateActivities: function (initid) {
1673
1674
1675        var last_id = initid ? initid : $('#activity_feed .feedentry').not('.feedaddon').first().attr('id');
1676
1677
1678        if (last_id === null) {
1679            console.log("could not find feed entry id");
1680            return true;
1681        }
1682
1683        var data = { "method": "getActivities", "last_id": last_id };
1684        $.post("/ajax/handler.php", data, function (res) {
1685
1686            if (res.done && res.actions) {
1687                $(res.actions).insertBefore("#" + last_id);
1688                $(".feedentry.updated").find('.feedavatar').addClass('wow').addClass('animate__wobble').addClass('animate__animated');
1689            } else if (res.done) {
1690                xobor.log.dev("No updates");
1691            } else {
1692                xobor.log.dev("Feed Update Error");
1693            }
1694
1695        });
1696
1697        return true;
1698    },
1699
1700    feedabo:
1701        subscribe = function () {
1702            var url = xobor.mbt.actionurls.feedsubscribe;
1703            $.get(url, function (res) {
1704                if (res.done) {
1705                    $('#not_subscribed_to_feed').addClass('hidden');
1706                    $('#subscribed_to_feed').removeClass('hidden');
1707                } else {
1708                    xobor.mbt.shownotice("Fehler: " + res.error);
1709                }
1710            });
1711        }
1712    ,
1713    trackHit: function (target, id) {
1714        var url = xobor.mbt.actionurls.hitcounter + '&what=' + target + "&whatid=" + id;
1715        $.get(url, function (res) {
1716            if (res.done) {
1717                /* Ignore */
1718            } else {
1719                /* Ignore */
1720            }
1721        });
1722    }
1723});
1724
1725xobor.mbt = $.extend(xobor.mbt, {
1726    setRatingsForContent: function (id) {
1727        return this.ratingaction(id, "getRatingHTML");
1728    },
1729    ratingaction: function (id, what) {
1730
1731        $('#' + id + "_div").hide();
1732        $("<div class='ratingbutton ratingloader'><i class='fas fa-spinner fa-spin'></i></div>").insertBefore($('#' + id + "_div"));
1733
1734
1735
1736        var r_type, c_type, c_id, re, xor_id;
1737
1738        var action = what ? what : 'giveRating';
1739        r_type = $("#" + id + '_rtype').text();
1740        c_type = $("#" + id + '_ctype').text();
1741        c_id = $("#" + id + '_cid').text();
1742        i_id = $("#" + id + '_iid').text();
1743
1744        re = 1;
1745
1746        try { xor_id = $('#' + id + '_xor_id').text(); } catch (e) {/*no xor*/ xor_id = 0; }
1747
1748        var data = {
1749            "action": action,
1750            "r_type": r_type,
1751            "c_type": c_type,
1752            "c_id": c_id,
1753            "re": re,
1754            "i_id": i_id,
1755            "xor_id": xor_id,
1756        }
1757
1758
1759        $.post(xobor.mbt.actionurls.ratinghandler, data, function (res) {
1760            res = JSON.parse(res);
1761            if (res.success) {
1762                //1_2_6386090_div
1763                var idstring = r_type + "_" + c_type + "_" + c_id;
1764
1765
1766                var $targetbase = $('body');
1767                if ($('.modal-content:visible').length) {
1768                    $targetbase = $('.modal-content');
1769                }
1770
1771                var txt = document.createElement("textarea");
1772                txt.innerHTML = res.html;
1773                var newhtml = txt.value;
1774
1775
1776
1777                $targetbase.find('#' + idstring + '_div').closest('.xratings').parent().html(newhtml);
1778                if (c_type == 11) {
1779                    /*Rating in der Bildergalerie - hier m&uuml;ssen wir neben dem modal-inhalt auch die urspr&uuml;ngliche picinfo neu laden*/
1780                    $('#pic_' + c_id + "_info").find('#' + idstring + '_div').closest('.xratings').parent().html(newhtml);
1781
1782                    /*
1783                    $('.ratingcol').remove();
1784                    $(newhtml).find('.ratingbutton').each(function(){
1785                        $("<div class='col col-auto mb-2 ratingcol'>" + this.outerHTML + "</div>").prependTo('.ekko-lightbox-sidebar');
1786                    });*/
1787                }
1788                $('.ratingloader').remove();
1789            }
1790            else {
1791                $('.ratingloader').remove();
1792                $('#' + id + "_div").show();
1793
1794                if (res.errormsg) {
1795                    if (res.errormsg == 'own content') {
1796                        temperr = 'Sie k&ouml;nnen Ihre eigenen Inhalte nicht bewerten';
1797                        $temp = $('<div>').html(temperr);
1798                        alert($temp.html());
1799                    } else {
1800                        alert(res.errormsg)
1801                    }
1802                }
1803            }
1804        });
1805
1806    },
1807    prepareQuote: function (quote) {
1808        tempQuote = quote.replace(/\n/g, "%xbreak%").replace(/\r/g, ""); //ie8 fix pt 1
1809        prepped_quote = $('<div>').html(tempQuote).html().replace(/>/g, ">").replace(/</g, "<").replace(/</g, "<").replace(/&/g, "&");
1810        prepped_quote = prepped_quote.replace(/%xbreak%/g, "\n"); //IE8 fix pt2
1811        return prepped_quote;
1812    },
1813    replyquotes: {},
1814    addReplyQuote: function (quoteid, quotecontent, quoteheader) {
1815
1816        this.replyquotes[quoteid] = { 'text': this.prepareQuote(quotecontent), 'header': quoteheader };
1817
1818    },
1819    insertReplyQuote: function (quoteid) {
1820        xobor.mbt.iconbar.insertBBCode('[quote=' + this.replyquotes[quoteid].header + ']' + this.replyquotes[quoteid].text + '[/quote]');
1821    },
1822    decodeHtml: function (html) {
1823        var txt = document.createElement("textarea");
1824        txt.innerHTML = html;
1825        return txt.value;
1826    },
1827    usersuggest: {
1828        resultcontainer: "#usersuggestresults",
1829        get: function (str) { },
1830        count: 0,
1831        drawDiv: function (str, data) {
1832
1833            let uname = xobor.mbt.decodeHtml(data.uname);
1834
1835            xobor.log.add(4, "adduser", data);
1836            iid = 'usri' + xobor.mbt.usersuggest.count;
1837            removelink = "<a class='usersuggest_remove' href='javascript:void(0);' onclick='$(\"#" + iid + "\").remove();$(\"#" + iid + "_vis\").remove();'><span class='xob xob-remove'></span> l&ouml;schen</a>";
1838
1839
1840            var styletag = data.usercolor ? 'style="color:' + data.usercolor + ';"' : "";
1841
1842            var imgtag = data.avatar + "" == "" ? '<span class="img-responsive img-circle avatar avatar_round_small noimage">' + data.username.substring(0, 2) + '</span>' : '<img class="img-responsive img-circle avatar avatar_round_small" src="' + data.avatar + '">';
1843
1844            userdivtemplate = '<div class="userdiv userdiv_small suggested_user float-left" id="' + iid + '_vis">' +
1845                '<table class="table table-borderless">' +
1846                '<tbody><tr><td>' + imgtag + '</td></tr>' +
1847                '<tr><td> <div class="muser">' +
1848                '<span><a href="javascript:void(0)" class="userlink user_' + data.id + '" id="usersuggestlink_' + data.id + '" ' + styletag + '>' + uname + '</a></span>' +
1849                '</div>' + '<div>' + removelink + '</div>'
1850            '</td></tr></tbody></table>' +
1851                '</div>';
1852
1853            return $(userdivtemplate);
1854
1855            //return $("<div class='suggested_user' id='"+iid+"_vis'>"+str+" "+removelink+"</div>");
1856        },
1857        addresult: function (res) {
1858            let name = xobor.mbt.decodeHtml(res.text);
1859
1860            xobor.mbt.usersuggest.count++;
1861
1862            //Add result container if needed:
1863            var rescont = xobor.mbt.usersuggest.resultcontainer;
1864            if (!$(rescont).length) {
1865                if (rescont != "#usersuggestresults") { alert("Autosuggest cannot find custom reslut container " + rescont); return false; }
1866                else {
1867                    $('<div class="well clearfix mt-2"  id="usersuggestresults"></div>').insertAfter('.autosuggest').first();
1868                }
1869            }
1870
1871            $('<input type="hidden" id="usri' + xobor.mbt.usersuggest.count + '" class="userinput" name="name[]" value="" />').appendTo(rescont);
1872            $('<input type="hidden" id="usri' + xobor.mbt.usersuggest.count + '_id" class="userinput" name="uid[]" value="" />').appendTo(rescont);
1873
1874
1875            xobor.mbt.usersuggest.drawDiv(name, res.data).appendTo(rescont);
1876            $("#usri" + xobor.mbt.usersuggest.count).val(name);
1877            $("#usri" + xobor.mbt.usersuggest.count + '_id').val(res.id);
1878
1879            //clear input:
1880            $('.autosuggest').val('').attr('placeholder', 'weiteren Empfaenger eingeben');
1881
1882
1883
1884        },
1885    },
1886    autosave: {
1887        lasttitle: "",
1888        lasttext: "",
1889        temptitle: "",
1890        temptext: "",
1891        forum: 0,
1892        thread: 0,
1893        dosave: 0,
1894        docheck: 0,
1895        timeout: false,
1896        newmsgs: 0,
1897        defaulttimeout: 30000,
1898        text_element: null,
1899        title_element: null,
1900        load: function () {
1901            _this = xobor.mbt.autosave;
1902            if (_this.temptitle == "" && _this.temptext == "") {
1903
1904                return;
1905            } else {
1906
1907                temptext = _this.temptext.replace(/\n/g, "%xbreak%").replace(/\r/g, ""); //ie8 fix pt 1
1908                temptext = temptext.replace(new RegExp('[<]', 'g'), "%xlt%").replace(new RegExp('[>]', 'g'), "%xgt%");
1909
1910                oldtext = $("<div>").html(temptext).text();
1911                oldtext = oldtext.replace(/%xbreak%/g, "\n"); //IE8 fix pt2
1912
1913                oldtext = oldtext.replace(/%xgt%/g, ">");
1914                oldtext = oldtext.replace(/%xlt%/g, "<");
1915
1916
1917
1918
1919                temptitle = _this.temptitle.replace(/\n/g, "%xbreak%").replace(/\r/g, ""); //ie8 fix pt 1
1920                oldtitle = $("<div>").html(temptitle).text();
1921                oldtitle = oldtitle.replace(/%xbreak%/g, "\n"); //IE8 fix pt2
1922
1923
1924
1925                if (!$.trim(oldtitle) == "") { _this.title_element.val(oldtitle); }
1926                if (!$.trim(oldtext) == "") { _this.text_element.val(oldtext); }
1927                _this.text_element.select();
1928
1929            }
1930        },
1931        save: function () {
1932            _this = xobor.mbt.autosave;
1933            clearTimeout(_this.timeout);
1934            _this.text_element.closest('form').removeClass("autosaveactive").addClass("autosaveactive");
1935            autocheck = _this.docheck ? 1 : 0;
1936
1937            if (_this.dosave) {
1938                autosave = 1;
1939
1940                title = xobor.mbt.convert2entity(_this.title_element.val());
1941                msg = xobor.mbt.convert2entity(_this.text_element.val());
1942
1943                if (title == _this.lasttitle && msg == _this.lasttext) {
1944                    //kein autosave n&ouml;tig...
1945
1946                    msg = ""; title = ""; autosave = 0;
1947                }
1948            } else {
1949                msg = ""; title = "";
1950                autosave = 0;
1951            }
1952
1953            _this.temptitle = title;
1954            _this.temptext = msg;
1955
1956            if (autosave || autocheck) {
1957                if (xobor.mbt.autosave.forum === "pn") {
1958                    xobor.mbt.autosave.thread = [];
1959                    $.each($('.userinput'), function () { xobor.mbt.autosave.thread.push(($(this).val())) });
1960                }
1961                data = { "save": autosave, "check": autocheck, "title": title, "text": msg, "thread": xobor.mbt.autosave.thread, "forum": xobor.mbt.autosave.forum };
1962
1963
1964
1965                $.ajax({
1966                    url: xobor.mbt.actionurls.autosave, processData: true, contentType: "application/x-www-form-urlencoded; charset:utf-8", data: data, dataType: 'json', type: "POST",
1967                    success: function (res) {
1968                        xobor.mbt.autosave.lasttitle = xobor.mbt.autosave.temptitle;
1969                        xobor.mbt.autosave.temptext = xobor.mbt.autosave.temptext;
1970
1971                        if (res.count && res.count !== xobor.mbt.autosave.newmsgs && res.count !== "error") {
1972                            xobor.mbt.autosave.newmsgs = res.count;
1973                            $('#newpostsinfo').removeClass('hidden').find('.pcount').html(res.count);
1974                            $('#newpostsinfo').find('.plink').attr('href', res.lastmsglink);
1975
1976                        }
1977                        xobor.mbt.autosave.timeout = setTimeout("xobor.mbt.autosave.save()", xobor.mbt.autosave.defaulttimeout);
1978                        setTimeout("xobor.mbt.autosave.text_element.closest('form').removeClass('autosaveactive')", 1000);
1979                    }
1980                });
1981            } else {
1982                setTimeout("xobor.mbt.autosave.text_element.closest('form').removeClass('autosaveactive')", 100);
1983                xobor.mbt.autosave.timeout = setTimeout("xobor.mbt.autosave.save()", xobor.mbt.autosave.defaulttimeout);
1984            }
1985        },
1986        clear: function (forum, user) {
1987
1988            var clearmail = (forum == 'pn') ? true : false;
1989
1990            $('.autosaveinfo').remove();
1991            //xobor.mbt.autosave.title_element.val("");
1992            xobor.mbt.autosave.text_element.val("").select();
1993
1994            if (clearmail) {
1995                var recs = [user];
1996                data = { "clear": 1, "thread": recs, "forum": "pn" };
1997            }
1998            else {
1999                data = { "clear": 1, "thread": xobor.mbt.autosave.thread, "forum": xobor.mbt.autosave.forum };
2000            }
2001            $.ajax({
2002                url: xobor.mbt.actionurls.autosave, processData: true, contentType: "application/x-www-form-urlencoded; charset:utf-8", data: data, dataType: 'json', type: "POST",
2003                success: function (res) { if (res.cleared) {/*done*/ } }
2004            });
2005        },
2006        init: function (forum, thread, save, check) {
2007
2008            xobor.mbt.autosave.forum = forum;
2009            xobor.mbt.autosave.thread = thread;
2010            xobor.mbt.autosave.dosave = save;
2011            xobor.mbt.autosave.docheck = check;
2012
2013            if (forum === "pn") {
2014                xobor.mbt.autosave.text_element = $("#text");
2015                xobor.mbt.autosave.title_element = $("#title");
2016            } else {
2017                xobor.mbt.autosave.text_element = $("#messagetext");
2018                xobor.mbt.autosave.title_element = $("#titel");
2019            }
2020
2021            if (tempautosavetext || tempautosavetitle) {
2022                if (tempautosavetext) {
2023                    xobor.mbt.autosave.temptext = tempautosavetext;
2024                }
2025
2026                if (tempautosavetitle) {
2027                    xobor.mbt.autosave.temptitle = tempautosavetitle;
2028                }
2029
2030
2031                xobor.mbt.autosave.load();
2032            }
2033
2034            xobor.mbt.autosave.timeout = setTimeout("xobor.mbt.autosave.save()", xobor.mbt.autosave.defaulttimeout);
2035        }
2036    }
2037
2038});
2039
2040xobor.mbt = $.extend(xobor.mbt, {
2041
2042    downloadfile: async function (filepath, filename) {
2043        filepath = this.resolveFileLink(filepath);
2044        const a = document.createElement("a");
2045        a.href = await this.toDataURL(filepath);
2046        a.download = filename;
2047        document.body.appendChild(a);
2048        a.click();
2049        document.body.removeChild(a);
2050    },
2051    toDataURL: async function (url) {
2052        const blob = await fetch(url).then(res => res.blob());
2053        return URL.createObjectURL(blob);
2054    },
2055    // In werbefinanzierten Foren zeigen Dateilinks auf den Frameset-Wrapper
2056    // file.php?url=<urlencodierte Datei-URL>&r=..&content=.. (relativ oder absolut).
2057    // Für den Download wird die eigentliche Datei-URL aus dem url-Parameter extrahiert;
2058    // alle anderen Links werden unverändert zurückgegeben.
2059    // Absolute http://-Links werden in jedem Fall auf https:// angehoben, damit der
2060    // fetch() im Download nicht an der Mixed-Content-Sperre scheitert.
2061    resolveFileLink: function (filepath) {
2062        if (typeof filepath !== "string") { return filepath; }
2063        var forceHttps = function (url) { return url.replace(/^http:\/\//i, "https://"); };
2064        var parsed;
2065        try {
2066            parsed = new URL(filepath, window.location.href);
2067        } catch (e) {
2068            return forceHttps(filepath);
2069        }
2070        if (!/(^|\/)file\.php$/.test(parsed.pathname)) { return forceHttps(filepath); }
2071
2072        var real = parsed.searchParams.get("url");
2073        if (!real) { return forceHttps(filepath); }
2074
2075        // Mehrfach kodierte Werte (z.B. http%253A%252F%252F...) bis zu einer echten URL dekodieren
2076        var i = 0;
2077        while (i < 5 && !/^(https?:)?\/\//i.test(real) && real.indexOf("%") !== -1) {
2078            try {
2079                var dec = decodeURIComponent(real);
2080                if (dec === real) { break; }
2081                real = dec;
2082            } catch (e) { break; }
2083            i++;
2084        }
2085        return forceHttps(real);
2086    },
2087    deltempfile: function (tempfilename) {
2088        noextname = tempfilename.split('.').slice(0, -1).join('.');
2089        $('#upload_' + noextname).remove();
2090        if ($('.image_attachment').length === 0) { $('#image_attachments').hide(); }
2091        if ($('.other_attachment').length === 0) { $('#other_attachments').hide(); }
2092        $.post(xobor.mbt.actionurls.uploadhandler, { 'deletesinglefile': 1, 'html5': 1, 'tempfile': tempfilename }, function (res, noextname) {
2093            console.log(res, noextname);
2094
2095        });
2096    },
2097    delexistingfile: function (fileid) {
2098
2099        $('#upload_' + fileid).addClass('todelete');
2100        $('#delfile_' + fileid).removeAttr("disabled");
2101        if ($('.image_attachment').length === 0) { $('#image_attachments').hide(); }
2102        if ($('.other_attachment').length === 0) { $('#other_attachments').hide(); }
2103    },
2104    undelexistingfile: function (fileid) {
2105        $('#upload_' + fileid).removeClass('todelete');
2106        $('#delfile_' + fileid).attr("disabled", true);
2107        if ($('.image_attachment').length !== 0) { $('#image_attachments').show(); }
2108        if ($('.other_attachment').length !== 0) { $('#other_attachments').show(); }
2109    },
2110    skeletons: {
2111        uploadFileDiv: function (file) {
2112
2113            if (typeof file.filelink === "undefined") {
2114                file.filelink = file.tempname;
2115            }
2116
2117            noextname = file.filelink.split('.').slice(0, -1).join('.');
2118
2119            var onclickfunc;
2120            var uniqueid;
2121            var istempfile = (file.tempfile || file.tempname) ? true : false;
2122            var tempclass = "";
2123
2124
2125
2126            if (istempfile) {
2127                onclickfunc = 'xobor.mbt.deltempfile(\'' + file.filelink + '\')';
2128                uniqueid = noextname;
2129                tempclass = "tempfile";
2130
2131                filelink = xobor.mbt.urls.tempPreviewPath + "?file=" + file.filelink + "&x=" + file.size_x + "&y=" + file.size_y + "&sec=" + file.sec;
2132                if (file.isvideo) { filelink += "&pic=1"; }
2133
2134                if (xobor.mbt.devmode) {
2135                    //filelink = "http://files.homepagemodules.de/b2001010/resize/"+ file.size_x+"x"+ file.size_y+"/pictures_u1341_FIzVajPB.jpg";
2136                }
2137            }
2138            else {
2139
2140                filelink = file.filethumb ? file.filethumb : file.filelink;
2141                onclickfunc = 'xobor.mbt.delexistingfile(\'' + file.id + '\')';
2142                uniqueid = file.id;
2143                tempclass = "existingfile";
2144            }
2145
2146
2147
2148            inserticon = "<span title='Bild in Beitrag einf&uuml;gen' data-toggle='tooltip' onclick='xobor.mbt.addimagetopost(\"" + uniqueid + "\",\"" + file.filename + "\")' class='xob-share-square'></span>";
2149
2150
2151
2152            todelclass = file.delete ? "todelete" : "";
2153            delinputdisabled = file.delete ? "" : "disabled";
2154
2155            var delinput = "";
2156            if (file.temp) {
2157                delinput = '<input type="hidden" ' + delinputdisabled + ' name="delfile[' + file.filelink + ']" id="delfile_' + uniqueid + '" value="1">';
2158            } else {
2159                delinput = '<input type="hidden" ' + delinputdisabled + ' name="file[' + file.id + ']" id="delfile_' + uniqueid + '" value="1">';
2160            }
2161
2162
2163
2164
2165
2166
2167            var default_insert_text = 'Einf&uuml;gen';
2168            var default_del_text = 'L&ouml;schen';
2169
2170            /*Dirty Hack um die Sprache herauszufinden...   */
2171            try {
2172                if (
2173                    ($('#doattach').length && $('#doattach').text().trim() == "Attach files")
2174                    ||
2175                    ($('input[name="preview"]').length && typeof ($('input[name="preview"]').val()) !== 'undefined' && $('input[name="preview"]').val().trim() == "Preview")
2176                    ||
2177                    ($('#new_previewtext').length && $('#new_previewtext').parent().find('label').text() == "Preview text")
2178                ) {
2179                    var default_insert_text = 'Insert';
2180                    var default_del_text = 'Delete';
2181                }
2182            } catch (e) { }
2183
2184
2185            var inserttext = $('#insert_pic_template').data('inserttext') ? $('#insert_pic_template').data('inserttext') : default_insert_text;
2186            var deltext = $('#insert_pic_template').data('deltext') ? $('#insert_pic_template').data('deltext') : default_del_text;
2187
2188
2189
2190            if (file.isimg || file.isvideo) {
2191
2192                let videoclass = file.isvideo ? 'video_attachment' : '';
2193
2194                filediv = '<div id="upload_' + uniqueid + '"  class="image_attachment ' + videoclass + ' card float-left mr-1 mb-1 ' + todelclass + ' ' + tempclass + '" style="width: 14rem;" ';
2195
2196                filediv += " data-filename='" + file.filename + "' ";
2197                filediv += " data-size_x='" + file.size_x + "' ";
2198                filediv += " data-size_y='" + file.size_y + "' ";
2199                filediv += " data-tempname='" + file.filelink + "' ";
2200                filediv += " data-id='" + file.id + "' ";
2201                filediv += " data-sec='" + file.sec + "' ";
2202
2203                filediv += '>' +
2204                    '<img class="card-img-top" src="' + filelink + '" alt="Vorschau">' +
2205                    '<div class="card-body text-center">' +
2206                    '<p class="card-text">' + file.filename + '</p>' +
2207                    '<div class="imageactions"><a href="javascript:void(0)" class="btn btn-primary"  onclick="xobor.mbt.addimagetopost(\'' + uniqueid + '\',\'' + file.filename + '\',' + file.isvideo + ')">' + inserttext + '</a>' +
2208                    '<a href="javascript:void(0)" class="btn btn-link"  onclick="' + onclickfunc + '">' + deltext + '</a></div>' +
2209                    '<div class="delimage"><span>' + $('#insert_pic_template').data('todeltext') + ' ' +
2210                    '<a href="javascript:void(0)" class=""  onclick="xobor.mbt.undelexistingfile(\'' + file.id + '\')">X</a></span></div>' +
2211                    '</div>';
2212
2213                filediv += '<input type="hidden" name="existingfile[]" value="' + file.filename + '">';
2214                filediv += '<input type="hidden" name="tempfiles[' + file.filelink + ']" value="' + file.filename + '">';
2215                filediv += '<input type="hidden" name="tempsize_x[' + file.filelink + ']" value="' + file.size_x + '">';
2216                filediv += '<input type="hidden" name="tempsize_y[' + file.filelink + ']" value="' + file.size_y + '">';
2217
2218
2219                filediv += delinput;
2220
2221                filediv += '</div>';
2222
2223            }
2224            else {
2225                filediv = "<div id=\"upload_" + uniqueid + "\"  class=\"other_attachment\">" + file.filename + ' (<a href="javascript:void(0)"  onclick="' + onclickfunc + '">' + deltext + '</a>)' + delinput + "</div>";
2226            }
2227
2228
2229            return $(filediv);
2230
2231        },
2232        userdiv_small: function (user, dousertitle) {
2233            if (!user) {
2234
2235            } else {
2236                var usercolor = user.usercolor ? 'style="color:' + user.usercolor + '"' : '';
2237                var userlink = user.user_link;
2238                var username = user.uname ? user.uname : xobor.helper.translations.name_guest;
2239                var avatar = user.avatar ? user.avatar : xobor.mbt.globals.noavatar_image;
2240
2241                userdiv = '<div class="userdiv">' +
2242                    '<table class="table table-borderless"><tbody><tr><td><img src="' + avatar + '" class="img-responsive img-circle avatar avatar_round_small"></td></tr><tr><td><div class="muser">' +
2243                    '<span><a ' + usercolor + ' href=""><strong>' + username + '</strong></a></span>' +
2244                    '</div>';
2245                if (dousertitle) {
2246                    userdiv += '<div class="mtitle">' + usertitle + '</div>';
2247                }
2248                userdiv += '</td></tr></tbody></table>' +
2249                    '</div>';
2250
2251                return userdiv;
2252
2253
2254            }
2255        },
2256        userdiv_inline: function (user, dousertitle) {
2257            if (!user) {
2258
2259            } else {
2260                var usercolor = user.usercolor ? 'style="color:' + user.usercolor + '"' : '';
2261                var userlink = user.user_link;
2262                var username = user.uname;
2263                var avatar = user.avatar ? user.avatar : xobor.mbt.globals.noavatar_image;
2264                var doavatar = false;
2265                userdiv = '<div class="userdiv"><table class="table table-borderless"><tbody><tr>';
2266
2267                if (doavatar) {
2268                    userdiv += '<td><img src="' + avatar + '" class="img-responsive img-circle avatar avatar_round_small"></td>';
2269                }
2270
2271                userdiv += '<td><div class="muser">' +
2272                    '<span><a ' + usercolor + ' href=""><strong>' + username + '</strong></a></span>' +
2273                    '</div>';
2274
2275                if (dousertitle) {
2276                    userdiv += '<div class="mtitle">' + usertitle + '</div>';
2277                }
2278                userdiv += '</td></tr></tbody></table>' +
2279                    '</div>';
2280
2281                return userdiv;
2282
2283            }
2284        }
2285    }
2286});
2287
2288
2289
2290
2291xobor.localstorage = {
2292    localstorageprefix: 'xobor_mbt_',
2293    get: function (key) {
2294        if (typeof (Storage) !== "undefined" && this.localstorageprefix) {
2295            var data = localStorage.getItem(this.localstorageprefix + key);
2296            try {
2297                var returnval = JSON.parse(data);
2298                if (returnval) {
2299                    return returnval;
2300                } else {
2301                    return false;
2302                }
2303            } catch (e) {
2304                var returnval = data;
2305                if (returnval) {
2306                    return returnval;
2307                } else {
2308                    return false;
2309                }
2310            }
2311
2312        }
2313    },
2314    set: function (key, val) {
2315        if (typeof (Storage) !== "undefined" && this.localstorageprefix) {
2316            localStorage.setItem(this.localstorageprefix + key, JSON.stringify(val));
2317            return true;
2318        }
2319        return false;
2320    },
2321    del: function (key) {
2322        if (typeof (Storage) !== "undefined" && this.localstorageprefix) {
2323            localStorage.removeItem(this.localstorageprefix + key);
2324            return true;
2325        }
2326        return false;
2327    }
2328},
2329    xobor.sessionstorage = {
2330        sessionstorageprefix: 'xobor_mbt_',
2331        get: function (key) {
2332            if (typeof (Storage) !== "undefined" && this.sessionstorageprefix) {
2333                var data = sessionStorage.getItem(this.sessionstorageprefix + key);
2334                try {
2335                    var returnval = JSON.parse(data);
2336                    if (returnval) {
2337                        return returnval;
2338                    } else {
2339                        return false;
2340                    }
2341                } catch (e) {
2342                    var returnval = data;
2343                    if (returnval) {
2344                        return returnval;
2345                    } else {
2346                        return false;
2347                    }
2348                }
2349
2350            }
2351        },
2352        set: function (key, val) {
2353            if (typeof (Storage) !== "undefined" && this.sessionstorageprefix) {
2354                sessionStorage.setItem(this.sessionstorageprefix + key, JSON.stringify(val));
2355                return true;
2356            }
2357            return false;
2358        },
2359        del: function (key) {
2360            if (typeof (Storage) !== "undefined" && this.sessionstorageprefix) {
2361                sessionStorage.removeItem(this.sessionstorageprefix + key);
2362                return true;
2363            }
2364            return false;
2365        }
2366    };
2367
2368

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.