1. Nachrichten
  2. Forum
    1. Unerledigte Themen
    2. Forenregeln
  3. Spenden
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Forum
  • Erweiterte Suche
  1. camp-firefox.de
  2. Mira_Belle

Beiträge von Mira_Belle

  • Einige Skripte funktionieren seit ff 138 nicht mehr

    • Mira_Belle
    • 6. Mai 2025 um 11:09
    Zitat von Sören Hentzschel
    Zitat von Mira_Belle

    Es werden grundsätzlich folgende Aufrufe blockiert:

    • eval()
    • new Function()
    • setTimeout(string)
    • setInterval(string)

    Die ersten beiden, ja. Aber mit Sicherheit nicht setTimeout und setInterval.

    Dann hat mich chaty belogen, die Sau!

  • MouseGestures goDoCommand('cmd_scrollTop')Does not work

    • Mira_Belle
    • 6. Mai 2025 um 11:08
    Zitat von pleassssse

    yes ,the same problem occurs

    Ok, sorry, but I can't help you any further at the moment.
    I'll keep my fingers crossed that a professional can help you further.

  • Einige Skripte funktionieren seit ff 138 nicht mehr

    • Mira_Belle
    • 6. Mai 2025 um 11:00

    Yes!
    Ich habe meine französiche Freundind gefragt ob sie mir helfen könnte,
    das Skript so umzuschreiben, dass es auch ohne
    security.allow_unsafe_dangerous_privileged_evil_eval => "true"
    funktionieren würde.

    War nicht ganz so trivial, aber nach einigen Versuchen haben wir es hinbekommen.

    JavaScript
    location.href.endsWith("://browser/content/browser.xhtml") && (async () => {
        await delayedStartupPromise;
    
        var addEventListener = (...args) => {
            var trg = args[3];
            if (!trg) trg = args[3] = window;
            trg.addEventListener(...args);
            this.handlers.push(args);
        };
    
        var initFunction = async function(_id, xhtmlns, addDestructor, addEventListener, gClipboard, LOG) {
            // Hier ist der Code, der ursprünglich als String in new Function() übergeben wurde
            var langFrom_google_text = "auto"; //auto
            var langTo_google_text = "de";
    
            // Assign icons
            var mainicon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADKElEQVR42p2TX2hTdxTHPzfJTW6T3qQmapvWabUbog+udp3kYeLQ4f6wiZQNtjlXHyZaBYe6TekYVGRQYexFscOtuD7UdWxzMtAXEbZStKIbDsaUCbVj9o8mTW+aNrlJbu5vJ8Ex2OMO/Lj87jnne873nO9PSyTV3tkAfYi5NhQ1MB1Ijc3ijN+D7CQh28YK+GHDMyxpjlJTkmAdQi5dWvOsUrYkGB5QC5Kcg/aFBxxqqycmcY38a/1yTqYgMw8ByfFKjtZ4V6myCeW8IApyfOw2155fw1DG4dOJJK1r45x5BPDUpZuMr2uXSuAvgBMQgOitjLJNn7iDSJP0rIJ35dt19TeGoi0Es1MMP72KFvm3+88phuYM3HCd3ObQizpa/cW7Kh020E0Tz1yOUxvjdIr7o6t/cLpkEJqZp7s5zN62ZewfnWLQ9VIIBqodBdI5tIbBG8oKhSAaJZDN8tpSP5+3L8eVgLbeAdKal7NH3mKL3FcOXCfV1ITjc7FLFrWZIlpt/4+qEA7hLRrCwk/RusOXu7ax8xHvGTkVgi/89As/T8ia9EUyghKOWSaYyqNx8oIiuEgcshetsooceibJinvTfNH1DpseD3LHSZE4eprs6k24NQaevI1fF8q5FJqv9xvlmFLdkKZlhb77E8TdIlFD54OOl3mzdXm1k+sP0jzbdwF7cRhsj8ysAWYnpYPeQfXPnn3JJG8/sZT+PW8gkuDbkWEiRh3b29dV/edujNE5dB4nHJSCUrQsTdP9mUKrCKHA5piHK+918quVp/VoD9W9uhGejNRx6+N9VZAmoTJZmhbK4vR7BGDPCQEQ/qU8R15aT2/Hi/R8PcyxyyMyVBmaXwIfPiTVf5yYHiF28ARpOyuqk3nJ4DV2HFc4SamUZ3vrGr7vPlitFNraQc4SzZZt6ptWMv3DAOdGrrGj7yvR+2KYr5A0BeCVAwqvBQuyMG+MTzp3cvj15/ivfXfzNq++/yFEIlD7GFjZ6uPRaE4oGuNQI68jIINJu0QbTFoadIJlL7lSgb8sxbSVEb8geUUVtkh55r50MY5Wec6jibV9/A9LjP7e9TdFQScjW9P1XAAAAABJRU5ErkJggg==";
    
            function GetXmlHttpObject() {
                if (window.XMLHttpRequest) { return new XMLHttpRequest(); }
                if (window.ActiveXObject) { return new ActiveXObject("Microsoft.XMLHTTP"); }
                return null;
            }
    
            var lc = navigator.lastClick = {};
            addEventListener("mouseup", e => {
                if (e.button) return;
                lc.X = e.screenX - mozInnerScreenX;
                lc.Y = e.screenY - mozInnerScreenY;
            }, false, gBrowser.tabpanels || 1);
    
            var createWindow = function(text, status, title, id, pos, size) {
                var win = window, doc = win.document, wId = 'ujs_window' + (id || ''), w = doc.getElementById(wId);
                var keyDown = function(e) {
                    if (!e.shiftKey && !e.ctrlKey && !e.altKey && e.keyCode == 27) doc.getElementById(wId).closeWin();
                };
                if (w) w.closeWin();
    
                gBrowser.addEventListener("click", function c() {
                    this.removeEventListener("click", c);
                    try { doc.getElementById(wId).closeWin(); } catch (e) {};
                }, true);
    
                w = doc.createElementNS(xhtmlns, 'div');
                w.setAttribute('style', 'position:fixed;display:block;visibility:hidden;left:0;top:0;width:auto;height:auto;border:1px solid gray;padding:2px;margin:0;z-index:99999;overflow:hidden;cursor:move;' + (typeof w.style.borderRadius === 'string' ? 'background-color:#eaeaea;padding-top:0px;border-radius:4px;box-shadow:0 0 15px rgba(0,0,0,.4);' : 'background:-o-skin("Window Skin");'));
                w.id = wId;
                w.closeWin = function() {
                    doc.removeEventListener('keydown', keyDown, false);
                    this.parentNode.removeChild(this);
                };
                w.addEle = function(str, style) {
                    var ele = doc.createElementNS(xhtmlns, 'div');
                    ele.setAttribute('style', style);
                    if (str) {
                        ele.innerHTML = str;
                        for (var el, all = ele.getElementsByTagName('*'), i = all.length; i--;) {
                            el = all[i];
                            if (/^(script|frame|iframe|applet|embed|object)$/i.test(el.nodeName)) {
                                el.parentNode.removeChild(el);
                            } else {
                                for (var att = el.attributes, j = att.length; j--;) {
                                    if (/^on[a-z]+$/i.test(att[j].name)) att[j].value = '';
                                }
                            }
                        }
                    }
                    return this.appendChild(ele);
                };
                w.addEle1 = function(str, style) {
                    var ele = doc.createElementNS(xhtmlns, 'textarea');
                    ele.setAttribute('style', style);
                    if (str) {
                        ele.innerHTML = str;
                        for (var el, all = ele.getElementsByTagName('*'), i = all.length; i--;) {
                            el = all[i];
                            if (/^(script|frame|iframe|applet|embed|object)$/i.test(el.nodeName)) {
                                el.parentNode.removeChild(el);
                            } else {
                                for (var att = el.attributes, j = att.length; j--;) {
                                    if (/^on[a-z]+$/i.test(att[j].name)) att[j].value = '';
                                }
                            }
                        }
                    }
                    return this.appendChild(ele);
                };
                var img = doc.createElementNS(xhtmlns, 'div');
                img.setAttribute('style', 'display:block;float:right;width:22px;height:22px;padding:0;margin-top:2px;margin-right:1px;border:none;cursor:pointer;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAIAAABL1vtsAAAACXBIWXMAAArEAAAKxAFmbYLUAAABc0lEQVQ4y2P84mzGQBlgYaAYoBjBrKn79/plgnrQlCGM4Jwwj0lC6kdjKX5TmDV1Oeq7/7149r0gCcUIZk1dJgkpBgYGjvruXyvm/96wErt+fWOOylYGBgYmCSm4WxjhwQkxHsL+vW39r0Uz0f3s6M6eVsDAyMjAwIDsWEbkGGHW1OWoaGFgZ8c0BaH///8fHbV/L56BSzGiRSqztj5HWROaKcj6f86e+GffDmQtjJjpAs2Uf48f4NGP3Qg0U6AAh36cRkBNqWhmYGWDcH/OmoBVP77UySgmwcDCCucyyciTlsCRw4/hz28GVjZWr0AGBgbMmMZuBFr4/3/5nKOskYGdA5cp6GGBNf6YtfUhpmBNdShGsFjas+dVYI0/ZFN+zZ/2e+cmLEYgEjiO+MNlCtQI5Azyc1L7n2MHsQYzk4o6Z8tECBtuCjQ4/16//O/FM4KZ/d+dm99r8jlbJv69eRXdFSQVOUwq6v/u3CScOuladgIAhMrZgyTDTBwAAAAASUVORK5CYII=");background:-o-skin("Caption Close Button Skin");');
                img.title = (win.navigator.language.indexOf('de') == 0) ? '\u0417\u0430\u043A\u0440\u044B\u0442\u044C' : 'Close';
                img.addEventListener('click', function() { this.parentNode.closeWin(); }, false);
                w.appendChild(img);
                var title = w.addEle(title, 'display:table;color:#000;font:17px Times New Roman;width:auto;height:auto;padding:0;margin:0 2px;cursor:text;');
                title.onclick = e => {
                    e.preventDefault();
                    var url = e.target.href;
                    var ctabpos = gBrowser.selectedTab._tPos + 1;
                    gBrowser.moveTabTo(gBrowser.selectedTab = gBrowser.addWebTab(url), ctabpos);
                    doc.getElementById(wId).closeWin();
                };
                var cnt = w.addEle1(text, 'display:block;border:1px solid #aaa;padding-bottom:3px;padding-left:3px;background-color:#f2ffe6;color:#8c0023;font:24px Times New Roman;width:600px;height:200px;overflow:auto;cursor:text;-moz-user-focus:normal;-moz-user-select:text;');
                cnt.contentEditable = "true";
                cnt.context = "contentAreaContextMenu";
                w.addEle(status, 'display:table;font:14px Times New Roman;font-weight:bold;color:blue;width:auto;height:auto;padding-top:2px;margin:0 3px;cursor:pointer;');
                w.addEventListener('mousedown', function(e) {
                    if (e.target == w) {
                        e.preventDefault();
                        var st = w.style;
                        var mouseMove = e => {
                            st.top = parseInt(st.top) + e.movementY + "px";
                            st.left = parseInt(st.left) + e.movementX + "px";
                        };
                        doc.addEventListener('mousemove', mouseMove, false);
                        doc.addEventListener('mouseup', function() { doc.removeEventListener('mousemove', mouseMove, false); }, false);
                    }
                }, false);
                doc.documentElement.appendChild(w);
    
                if (size) {
                    cnt.style.height = size.height;
                    cnt.style.width = size.width;
                } else {
                    for (var i = 3; i < 10; i++) {
                        if (cnt.scrollHeight > cnt.offsetHeight || cnt.scrollWidth > cnt.offsetWidth) {
                            cnt.style.height = 80 * i + 'px';
                            cnt.style.width = 160 * i + 'px';
                        } else break;
                    }
                };
                var docEle = (doc.compatMode == 'CSS1Compat' && win.postMessage) ? doc.documentElement : doc.body;
                var mX = docEle.clientWidth - w.offsetWidth, mY = docEle.clientHeight - w.offsetHeight;
                if (mX < 0) { cnt.style.width = parseInt(cnt.style.width) + mX + 'px'; mX = 0 };
                if (mY < 0) { cnt.style.height = parseInt(cnt.style.height) + mY + 'px'; mY = 0 };
                var hW = parseInt(w.offsetWidth / 2);
                w.style.left = (pos && pos.X < mX + hW ? (pos.X > hW ? pos.X - hW : 0) : mX) + 'px';
                w.style.top = (pos && pos.Y + 10 < mY ? pos.Y + 10 : mY) + 'px';
                w.style.visibility = 'visible';
                doc.addEventListener('keydown', keyDown, false);
                return w;
            };
    
            var getHash = function(txt) {
                var TKK = ((function() {
                    var a = 817046147;
                    var b = -335196159;
                    return 410049 + '.' + (a + b);
                })());
    
                function sM(a) {
                    var b;
                    if (null !== yr)
                        b = yr;
                    else {
                        b = wr(String.fromCharCode(84));
                        var c = wr(String.fromCharCode(75));
                        b = [b(), b()];
                        b[1] = c();
                        b = (yr = window[b.join(c())] || "") || "";
                    }
                    var d = wr(String.fromCharCode(116));
                    var c = wr(String.fromCharCode(107));
                    d = [d(), d()];
                    d[1] = c();
                    c = "&" + d.join("") + "=";
                    d = b.split(".");
                    b = Number(d[0]) || 0;
                    for (var e = [], f = 0, g = 0; g < a.length; g++) {
                        var l = a.charCodeAt(g);
                        128 > l ? e[f++] = l : (2048 > l ? e[f++] = l >> 6 | 192 : (55296 == (l & 64512) && g + 1 < a.length && 56320 == (a.charCodeAt(g + 1) & 64512) ? (l = 65536 + ((l & 1023) << 10) + (a.charCodeAt(++g) & 1023),
                            e[f++] = l >> 18 | 240,
                            e[f++] = l >> 12 & 63 | 128) : e[f++] = l >> 12 | 224,
                            e[f++] = l >> 6 & 63 | 128),
                            e[f++] = l & 63 | 128);
                    }
                    a = b;
                    for (f = 0; f < e.length; f++)
                        a += e[f],
                        a = xr(a, "+-a^+6");
                    a = xr(a, "+-3^+b+-f");
                    a ^= Number(d[1]) || 0;
                    0 > a && (a = (a & 2147483647) + 2147483648);
                    a %= 1E6;
                    return c + (a.toString() + "." + (a ^ b));
                }
                var yr = null;
                var wr = function(a) {
                    return function() {
                        return a;
                    };
                };
                var xr = function(a, b) {
                    for (var c = 0; c < b.length - 2; c += 3) {
                        var d = b.charAt(c + 2);
                        d = "a" <= d ? d.charCodeAt(0) - 87 : Number(d);
                        d = "+" == b.charAt(c + 1) ? a >>> d : a << d;
                        a = "+" == b.charAt(c) ? a + d & 4294967295 : a ^ d;
                    }
                    return a;
                };
                return sM(txt);
            };
    
            var ujs_google_translat = function(dir) {
                var lng = 'de';
                var txt = gClipboard.read();
                var l = dir.split('|');
                var encTxt = encodeURIComponent(txt);
                var winWait = function(lng) { createWindow('', (lng == 'de' ? 'Warten bis der Text übersetzt ist' : 'Wait, is going Translating') + '\u2026', 'Google Translate', '_gt', window.navigator.lastClick); };
                if (txt) {
                    winWait(lng);
                    var xhr = new XMLHttpRequest();
                    var url = 'https://translate.google.com/translate_a/single?client=gtx&sl=' + l[0] + '&tl=' + l[1] + '&hl=' + lng + '&eotf=0&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t' + getHash(txt);
                    var urlt = "http://translate.google.com/translate_t?text=" + encTxt + "&sl=" + l[0] + "&tl=" + l[1] + "&hl=" + lng + "&eotf=0&ujs=gtt";
                    xhr.open('POST', url, true);
                    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8');
                    xhr.onreadystatechange = function() {
                        try {
                            if (xhr.readyState == 4 && xhr.status == 200) {
                                var result = '', status = '', tmp = JSON.parse(xhr.responseText.replace(/\[(?=,)/g, '[0').replace(/,(?=,|\])/g, ',0').replace(/\\n/g, "<br />"));
                                for (var i = 0, n; n = tmp[0][i]; i++) {
                                    if (n[0]) result += n[0].toString();
                                };
                                status = tmp[8][0][0].toUpperCase() + ' -\u203A ' + l[1].toUpperCase();
                                createWindow(result, status, '<a href="' + urlt.replace(/&/g, '&amp;') + '" target="_blank" style="display:inline;padding:0;margin:0;text-decoration:none;border:none;color:#009;font:22px Times New Roman;">Google Translate</a>', '_gt', window.navigator.lastClick);
                            }
                        } catch (x) { LOG(x); };
                    };
                    xhr.send('q=' + encodeURIComponent(txt));
                };
            };
    
            var ujs_google_translate = function() {
                var lng = 'de';
                var txt = gContextMenu.selectionInfo.fullText;
                var encTxt = encodeURIComponent(txt);
                var winWait = function(lng) { createWindow('', (lng == 'de' ? 'Warten bis der Text übersetzt ist' : 'Wait, is going Translating') + '\u2026', 'Google Translate', '_gt', window.navigator.lastClick); };
                if (txt) {
                    winWait(lng);
                    var xhr = new XMLHttpRequest();
                    var url = 'https://translate.google.com/translate_a/single?client=gtx&sl=' + langFrom_google_text + '&tl=' + langTo_google_text + '&hl=' + lng + '&eotf=0&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t' + getHash(txt);
                    var urlt = "http://translate.google.com/translate_t?text=" + encTxt + "&sl=" + langFrom_google_text + "&tl=" + langTo_google_text + "&hl=" + lng + "&eotf=0&ujs=gtt";
                    xhr.open('POST', url, true);
                    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8');
                    xhr.onreadystatechange = function() {
                        try {
                            if (xhr.readyState == 4 && xhr.status == 200) {
                                var result = '', status = '', tmp = JSON.parse(xhr.responseText.replace(/\[(?=,)/g, '[0').replace(/,(?=,|\])/g, ',0').replace(/\\n/g, "<br />"));
                                for (var i = 0, n; n = tmp[0][i]; i++) {
                                    if (n[0]) result += n[0].toString();
                                };
                                status = tmp[8][0][0].toUpperCase() + ' -\u203A ' + langTo_google_text.toUpperCase();
                                createWindow(result, status, '<a href="' + urlt.replace(/&/g, '&amp;') + '" target="_blank" style="display:inline;padding:0;margin:0;text-decoration:none;border:none;color:#009;font:22px Times New Roman;">Google Translate</a>', '_gt', window.navigator.lastClick);
                            }
                        } catch (x) { LOG(x); };
                    };
                    xhr.send('q=' + encodeURIComponent(txt));
                };
            };
    
            (function() {
                if (document.getElementById("TranslateBufer")) return;
                var contextMenu = document.getElementById("contentAreaContextMenu");
                var Item = document.createXULElement("menuitem");
                Item.setAttribute("label", "Translate from clipboard");
                Item.setAttribute("class", "menuitem-iconic");
                Item.setAttribute("image", mainicon);
                Item.addEventListener("command", function() { ujs_google_translat('auto|de'); }, false);
                contextMenu.insertBefore(Item, document.getElementById("context-viewpartialsource-selection"));
                addDestructor(function() { contextMenu.removeChild(Item); });
            })();
    
            (function() {
                if (document.getElementById("TranslateSelected")) return;
                var contextMenu = document.getElementById("contentAreaContextMenu");
                var Item = document.createXULElement("menuitem");
                Item.setAttribute("id", "TranslateSelected");
                Item.setAttribute("label", "Translate selected text");
                Item.setAttribute("class", "menuitem-iconic");
                Item.setAttribute("image", mainicon);
                Item.addEventListener("command", function() { ujs_google_translate(); }, false);
                contextMenu.insertBefore(Item, document.getElementById("context-viewpartialsource-selection"));
                addDestructor(function() { contextMenu.removeChild(Item); });
    
                addEventListener("popupshowing", function() {
                    Item.hidden = !gContextMenu.isTextSelected;
                }, false, contextMenu);
            })();
        };
    
        // Initialize handlers array
        this.handlers = [];
    
        initFunction("cbinit-google-translate", "http://www.w3.org/1999/xhtml", () => {}, addEventListener, { read: readFromClipboard }, Cu.reportError);
        window.addEventListener("unload", this, { once: true });
    })();
    Alles anzeigen


    Bitte um Tests und natürlich um Rückmeldung(en).


    Zitat von milupo
    Zitat von Mira_Belle

    Ja, tatsächlich, funktioniert mit den "Schalter"

    Wenn es um das Skript von lenny2 aus Beitrag #13 geht, da muss der Schalter auf true gesetzt werden, denn in Zeile 156 wird die Funktion eval() verwendet. In Zeile 13 wird dann noch Function verwendet, das ebenfalls mit dem Wert false blockiert werden könnte.

    Es werden grundsätzlich folgende Aufrufe blockiert:

    • eval()
    • new Function()


  • Einige Skripte funktionieren seit ff 138 nicht mehr

    • Mira_Belle
    • 6. Mai 2025 um 09:52

    Ah! security.allow_unsafe_dangerous_privileged_evil_eval set to true

    Daher weht der Wind. Möchte ich nicht, da der Sicherheitslevel herabgesetzt wird.
    (Aber ich werde es auch testen) Moment. ....

    Ja, tatsächlich, funktioniert mit den "Schalter"
    security.allow_unsafe_dangerous_privileged_evil_eval auf true:!:

    Dann war es wohl ein Anwendungsfehler meinerseits. denke ich.

  • MouseGestures goDoCommand('cmd_scrollTop')Does not work

    • Mira_Belle
    • 5. Mai 2025 um 22:17

    have you also tried the “newer” version of alice?


    userChrome.js/138/MouseGestures2_e10s.uc.js at master · alice0775/userChrome.js
    Contribute to alice0775/userChrome.js development by creating an account on GitHub.
    github.com
  • AddOnLister.uc.js funktioniert in Fx 138 nicht mehr.

    • Mira_Belle
    • 5. Mai 2025 um 22:10

    Beitrag #17:!:
    Wer guckt denn da so weit hinten. :D

  • Einige Skripte funktionieren seit ff 138 nicht mehr

    • Mira_Belle
    • 5. Mai 2025 um 21:44

    Also, wie auch immer, das Skript von lenny2 funktioniert bei mir nicht.
    Werde aber erst die Tage dazu kommen, nach der Ursache zu suchen.

  • AddOnLister.uc.js funktioniert in Fx 138 nicht mehr.

    • Mira_Belle
    • 5. Mai 2025 um 21:42
    Zitat von Mira_Belle

    Gerade getestet in der Nightly, funktioniert auch so nicht. :/

    Alles i.O.
    Fehler lag bei mir, bzw. an den "Einstellungen" im Skript!
    Pfade stimmten nicht.

  • Einige Skripte funktionieren seit ff 138 nicht mehr

    • Mira_Belle
    • 5. Mai 2025 um 17:08

    Fehler in Zeile 35.
    function GetXmlHttpObject(){

    GetXmlHttpObject ist zwar deklariert, wird aber nie angesprochen.

    Und es funktioniert in der Nightly nicht!

    Und nun kommen wir zur Frage aller Fragen:!:
    security.allow_unsafe_dangerous_privileged_evil_eval auf "true" oder "false":?:

    So etwas sollte man in Zukunft dazu schreiben, denke ich.

  • Einige Skripte funktionieren seit ff 138 nicht mehr

    • Mira_Belle
    • 5. Mai 2025 um 12:21
    Zitat von Zitronella

    Mira_Belle Dankeschön, ich habe allerdings schon ein Skript für Deepl, welches ich gestern nach euren Posts entsprechend angepasst habe ;)

    Prima, das dürfte ja wahrscheinlich das Gleiche sein.
    Und dann auch mit header!

  • AddOnLister.uc.js funktioniert in Fx 138 nicht mehr.

    • Mira_Belle
    • 5. Mai 2025 um 11:11

    Gerade getestet in der Nightly, funktioniert auch so nicht. :/

  • AddOnLister.uc.js funktioniert in Fx 138 nicht mehr.

    • Mira_Belle
    • 5. Mai 2025 um 11:07

    Mag sein, besser, so wird es sein, aber es soll ja darum gehen Skript so umzuschreiben,
    ohne Sicherheitsfunktionen des Firefox auszuschalten.

  • about:about Button

    • Mira_Belle
    • 5. Mai 2025 um 11:00

    Wenn das Skript aus #2 oder #10 bei ihm, geldhuegel , nicht funktioniert, stimmt etwas mit seiner Installation nicht!
    Beide funktionieren hier sowohl in der 138.0.1 (64-Bit) als auch in der 140.0a1 (2025-05-02) (64-Bit).

  • AddOnLister.uc.js funktioniert in Fx 138 nicht mehr.

    • Mira_Belle
    • 5. Mai 2025 um 10:51

    Gerade in der Nightly getestet, stimmt, Button erscheint, ist aber ohne Funktion. :/

  • Einige Skripte funktionieren seit ff 138 nicht mehr

    • Mira_Belle
    • 5. Mai 2025 um 10:03

    Zitronella Ich hätte da auch noch das Übersetzungsskript für DeepL.
    Finde DeepL liefert bessere Übersetzungen.


    JavaScript
    // Translate_DeepL.uc.js
    // https://github.com/ardiman/userChrome.js/tree/master/contexttranslate
    // ex ContextTranslate.uc.js///
    // modifiziert by universum 123, Umlaute geändert by 2002Andreas
    // https://www.camp-firefox.de/forum/thema/126100/?postID=1107070#post1107070
    
    (function () {
    	if (location.href !== 'chrome://browser/content/browser.xhtml') return;
    	let translate = function () {
    		let browserMM = gBrowser.selectedBrowser.messageManager;
    		browserMM.addMessageListener('getSelection', function listener(message) {
    			let t = (message.data !== '');
    			let e = (document.charset || document.characterSet);
    			if (t) {
    				openWebLinkIn('https://www.deepl.com/translator#en/de/' + encodeURIComponent(message.data), 'tab');
    			} else {
    				openWebLinkIn('https://www.deepl.com/translate?u=' + encodeURIComponent(gBrowser.currentURI.spec) + '&hl=de-DE&ie=' + e + '&sl=auto&tl=de-DE', 'tab');
    			};
    			browserMM.removeMessageListener('getSelection', listener, true);
    		});
    		browserMM.loadFrameScript('data:,sendAsyncMessage("getSelection", content.document.getSelection().toString())', true);
    	}
    	let menuitem = document.createXULElement('menuitem');
    	menuitem.id = 'context-DeepLtranslate';
    	menuitem.setAttribute('label', '\u00dcbersetzen (DeepL)');
    	//menuitem.setAttribute('tooltiptext', 'Mit DeepL \u00fcbersetzen');
    	menuitem.classList.add('menuitem-iconic');
    	let ProfilePath = Services.dirsvc.get("ProfD", Ci.nsIFile).path.replace(/\\/g, "/");
    	let IconPath = '/chrome/icons/'; // Pfad in den entsprechenden Unterordner
    	let ButtonIcon = "DeepL_2.png"; // Name & Dateiendung des anzuzeigenden Symbols!
    	menuitem.style.listStyleImage = 'url("' + ("file:" + ProfilePath + IconPath + ButtonIcon) + '")';
    	menuitem.addEventListener('command', translate);
    
    	let refItem = document.getElementById('context-inspect');
    	refItem.parentNode.insertBefore(menuitem, refItem);
    })();
    Alles anzeigen

    Passendes Symbol kannst Du auch haben. => <=
    Es muss aber unter "...\chrome\icons" gespeichert werden.

  • Einige Skripte funktionieren seit ff 138 nicht mehr

    • Mira_Belle
    • 4. Mai 2025 um 23:30

    Warum werden, bzw. sind in den Skripten keine Header vorhanden?
    Würde es eventuell einfacher machen.

    JavaScript
    // ContextTranslate_Google.uc.js
    // https://github.com/ardiman/userChrome.js/tree/master/contexttranslate
    // ex ContextTranslate.uc.js///
    // modifiziert by universum 123, Umlaute geändert by 2002Andreas
    // https://www.camp-firefox.de/forum/thema/126100/?postID=1107070#post1107070
    
    (function () {
    	if (location != 'chrome://browser/content/browser.xhtml')
    		return;
    	let translate = function () {
    		let browserMM = gBrowser.selectedBrowser.messageManager;
    		browserMM.addMessageListener('getSelection', function listener(message) {
    			let t = (message.data !== '');
    			let e = (document.charset || document.characterSet);
    			if (t) {
                    openWebLinkIn('https://translate.google.com/?sl=en&tl=de&text=' + encodeURIComponent(message.data), 'tab');
    			} else {
    				openWebLinkIn('https://translate.google.com/translate?u=' + encodeURIComponent(gBrowser.currentURI.spec) + '&hl=de-DE&ie=' + e + '&sl=auto&tl=de-DE', 'tab');
    			};
    			browserMM.removeMessageListener('getSelection', listener, true);
    		});
    		browserMM.loadFrameScript('data:,sendAsyncMessage("getSelection", content.document.getSelection().toString())', true);
    	}
    	let menuitem = document.createXULElement('menuitem');
    	menuitem.id = 'context-googletranslate';
    	menuitem.setAttribute('label', '\u00dcbersetzen (Google)');
    	menuitem.classList.add('menuitem-iconic');
    	//Wer kein Icon möchte kann die nächsten beiden Zeilen auskommentieren/löschen
    	menuitem.style.listStyleImage = ' url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAwCAYAAABT9ym6AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMjHxIGmVAAAHYklEQVRoQ+2Y6U+UVxSH9Xs/NGnSv6et1h1REWOrUEaomiZt2tQqRQFFcNiRImg1rnVBbZUoorhRYNhGZweGfYcBoQ6bn0/Pue+9w7vcGRhpRz94kidDDHn5PZ5z7tyZFR/qfS4AWGkq9ZtiimZGY4vfQOzJBbZzYjjbioxsLVTYwvnu1MRH/NGRrfiSKRMT4IjwGgGBWoAjBKI5URn92/ijI1sxhbwTOhEhIRMREjKRjVnjtfzRkS2ZhLQbxBJEogvewDfpjo/54yNX6vB6icVEhIReZMOR7h388ZGrcCVkIgEJLvJOxksmEEpESIQSeSfjtagAwSVk3dCIcAnWlcN9sfxPRKZCChASicW6sRkxlb4Gm70LenuHYWTUBz6fD8bHx9mrYGxsjDE6OmpgZGQkwPDw8Fh//9BXPLK8pOEFXCCYRLBukAhx+6Eb2r19GIaCj8PExASTEeiF1Mjkurp6vuaxjbWYwJIkCJ0EcfyPPmhsckJ3zwCG04rIOrOYyMDAwDCPbSx9aD0U3vT7PFyvm4XW/mmYnPLD1D9+aMefr9fPQsKZeWk3iPiSSairt4Pd3gpDw6PSboQjQvDYxpKFJ0QHcu7NwcTUNPj9finjk344envOIBGVr0Dj1WJ1Q2urF2d9ZFkitC88trFEYBkk8VoVumNwGu5ZZxn0M/1b56Af9mDH1CJCgqDxsjQ4wOlqBa+3kwWKqAiNk+gEjVJh5axmL+jn/HuzEF+mlVCLbELifhPj5YG29g5c2C4WKJQEsSwR9SJfw50QnSh9hKOD/6YBAwtkEkKEuF1F4+UCj6cdOjo6mQweqWF1gwgpog6vhhabJAZ800zybSWIwHg5lfHq7OyE7u5uJvO/ilBYOp1I5LlrxiAgOqXnsWPGILEpTxmv2jo72GzKeHV0KCOWmJoDSUcLlyRCEiFFAiF1aES4wGIiNe4Zg4TgVpUrMF5e74LIntRcTWdkEsRbi3j6lNEaFKPFJWiECu7PBjhdvbBLd5pmg4psPfwMdh/IgfhkM5gOZ8OeIwSKIIko8+2xAtibUYSvCyQdKwxDhAfUc7V2IWBZ9ZxmFwQ0RmefLPyeuWJOKrERicoahDgUSUhGAexEYmo2JKblQhKRjiJH85iMWkKICIm3EqFjdfyVEpCO3+Iq5eQSAgQFFyM4OObHN9J5qYTg1gMXNLe4wO1uC4wXQYtP5J67ijtTAPee1gU68VYi+v/xrDvaN8SuoWmofDED960z0D6gfbc/jr8bSmJD7jxkXOmDeosNXtpc0Nbm1YjYXW7sTD52Jh+8Xd1SiZAi+vB6SMbHOyPjFXakEHdFLSCTIHYVT8KveRcg/qAZii/fCpxeJFJy5SZb/KKL5Xj172UHwLJFxOgIdpfOw5W/Z8HdO43BlYtjG3akvH4GEs9qBYJJEOuRszcbIe5gDphSsqGmoZmJ1DZZ2cJTR6w2B/T09EBfXx8MDQ0tXUQfOhiBJVbDgy9Vgjh2pRdyym5A3KETcCCnDOxONxzIPcVOr3PlFUyCoK4Qehke21iy0AJpeAEPLhMIJkHsKp6Cp8+t8GNmCSTgMbz/WD6YUOJQwWnowHd8ISJk1J2hceOxjSUNGQwMKGOpEoycebiJp9eDJxZISMHjGEcsMS0PrC/tbFdIQLwKkf7+fiazPBEMFoxQAsEkiPSLPZBedBHHy8xEEvDNsfhyOduXYCLE4OBgCBEMEC56gXAkiGjzCOz8yQyJKXlwreIh7GPjlQ0nL5XjhVI5xWQiBI9tLFlQGbLwRDgCxDrOVwfPQcWDWnb3el7fjDIFbFcKL9xgMv+JiCywHr1AOBLEgTPteLW3g4Nf7Z9bmnDxC5lM3vnrbMyEiCCkiCxkMGThCYMAwcPLJNZmY0eKpvBqbwtc7ekzSg3K7MsoYDuTe/6apiuLiqw74ffJQhOy0GrCFRASgvJKJzQ1OzWfHGsszbAXrymX/rwfEFGPGI9trA0nxuJkIYMhDU9gyHAk1iDpl3rx7mUHp4sukYoILTrdu8TC63eFx5bX6pTepDWZU7712dMgY10ozEbWmv0a1pzQ8iVnZ8E41NU7wGb3aETEq+z04pEjU7+kPsv8fEsFEJ9F39WymRN1Fw5lVIOl0QEOBy38wrVe8M5F9v/816dfxFSChm0qtlZCatYzdmpZX9DHXy/bEVp4EhCvehGC/4nIVcL31ZOrdlQBI1bF9ipIy6mBxiYHXktc4HK1ss8mdKUnAYFeRMjwx0eu0rJrU1djcA0ocTS7BhoabWC10kjRV6nKlxEUXi2jFlF3hT8+cpWc/OST1bEPUUBhVUwVpKNEY5MdXrxwMglPaxu0tyvdEOhF9OPFHx/ZSvjh8SSNEkmkqTpht+Pndg+NFHXDy9CL6LtCIti5Mf7oyFZK5rNU0QlLw0toaaHvgHEv3B4cqTYUoY4oMmoR8aoXefS4ycQfHdmi8UozP4Ha2mawWFpQ5CW+Z9BuOHHJ6dsUHC8PSbUaUEvi7/uqHjXswUeuVJ78od7HWrHiXwQB769LvTEjAAAAAElFTkSuQmCC")';
    	menuitem.addEventListener('command', translate);
        let refItem = document.getElementById('context-inspect');
    	refItem.parentNode.insertBefore(menuitem, refItem);
    })();
    Alles anzeigen
  • AddOnLister.uc.js funktioniert in Fx 138 nicht mehr.

    • Mira_Belle
    • 4. Mai 2025 um 20:28

    milupo Ich war mal so frei und habe Deinem Skript eine neue Versionsnummer verpasst!

    JavaScript
    // ==UserScript==
    // @name           AddOnLister.uc.js
    // @compatibility  Firefox 36.*, 37.*, 60.*, 63.*, 138.+
    // @include        main
    // @version        1.0.20250504
    // ==/UserScript==
    
    var ADONLI = {
    
    // ----- Start Konfiguration
        // folgende Add-ons nicht auflisten Beispiel: ["InfoLister","AddOnLister.uc.js"]
        BLACKLIST:            [],
        // einige Tests der Konfiguration durchführen (true oder false)?
        CHECKCONFIG:        true,
        // ans eigene System anpassen - Pfad mit Verzeichnistrenner abschliessen. Unter Windows den \ bitte verdoppeln
        EXPORTPATH:            "D:\\Addonlister\\",
        //Dateinamen ohne(!) Erweiterung eingeben - diese wird weiter unten im Wert "fileext" pro Ausgabeformat definiert
        EXPORTFILE:            "addonlister",
        // Ausgabeformat bbcode, html oder custom
        FORMAT:                "html",
        // Erstellungsdatum anzeigen (true oder false)
        SHOWDATE:            true,
        // Useragent anzeigen (true oder false)
        SHOWUSERAGENT:        true,
        // Versuche folgende userChromeJS-Skripte *nicht* mit GitHub zu verlinken, weil nicht gewünscht oder möglich. ["*"] für gar keine Verlinkung
        GITHUBBLACKLIST:    ["about-config.uc.js", "about-plugins.uc.js" ,"AddonsSidebar.uc.xul", "autopopupablepatch1.uc.js", "autopopupablepatch3.uc.js", "Chronik-Lesezeichen.uc.js", "Close-other-tabs.uc.js", "ContextHistory.uc.xul", "CustomAppMenu.uc.js", "Download-button.uc.js", "Einstellungen-Customize.uc.js", "element_inspector.uc.js", "Entwickler-Werkzeug.uc.js", "expandsidebar40.uc.js", "favicon-about-plugins.uc.js", "feedbutton-urlbar.uc.js",    "Fehlerkonsole.uc.js", "Link-per-Email.uc.js", "liste-leeren.uc.js", "memorymonitor.uc.js", "open-folder.uc.js", "OpenDownloadFolderButtonM.uc.js", "OpenLibraryContextMenu.uc.xul", "Preferences.uc.js", "RestartFirefox_plus.uc.js", "savefoldermodoki.uc.xul", "scrollTotop-bottom.uc.js", "searchplugin-4-aboutconfig.uc.js", "speedupErrorConsole.uc.js", "Statusbar-Date.uc.js", "Stylish-Fenster-Sidebar.uc.js", "Tabmixplus-Einstelungen-in-Tabkontext.uc.js", "Tabmixplus-Options.uc.js", "ucjs_PrivateToolMenus-APP.uc.js", "ucjs_statusbar_zoom_panel_1.3.uc.js", "WebDeveloper-Menu.uc.js"],
        // In der folgenden Zeile  den Pfad zum Texteditor eintragen (unter Ubuntu 10.04 z.B.: '/usr/bin/gedit'). Bei Fehleintrag wird view_source.editor.path ausgelesen:
        TEXTOPENEXE :        'D:\\Programme\\Notepad++-8.7.5\\notepad++.exe',
        // Aufzulistende Add-On-Typen festlegen - möglich sind: ["extension","theme","plugin","dictionary","service","userstyle","greasemonkey-user-script","userchromejs"]
        WHICHTYPES:            ["extension","theme","plugin","dictionary","userchromejs"],
    // ----- Ende Konfiguration
    
    // ----- Start Expertenkonfiguration
        ICON_URL:    "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACGUlEQVR42mL8//8/AzJYtWy+G5ByB2IrINaECl8H4mNAvDMsKnEXsnqAAGIEGXDv1nmGM2cuKAD5OUCcAcTcDNjBVyCeAcRTTEwMHiipGTIABBALSBSquRmIY5iZmT8ICvI/FxQU4OHm5mID6/r67df79x++vH//kfPv37/FQCFxoJ5aoAEPAAKIBWoyyOYYdnb2Z9LSkqxCQgKSyNby8/OxAzEvH9+H10+fPn/28+fPGKDwSyAuAQggZi01eZCfu4E2f5OVlWYAahaFaTx95jyDnaM3Ax8fL4OhgS4DJycHNysr649Pnz7/Bnrd/OrlC2cAAogJGmDcQGd/Q9YMAv8YORmSkpIY+Hh54GIgNSC10HByBwggFmhoMwD9LIgeYrKSAgz+Ps4MOtqaKOIgtW/evAMxrQACiAkWVcAAY0JWBHQmg7d/ONgb6ABJrSZAADHhiC6G3Xv2gw1xdXFgwAcAAogJmkhAUfUPWeL+w8cMamoqDDLSUgxMbKi+Q1J7HSCAmKApjAEYz++RFV2/fouBg52dYeXqDQzHj+xGMQBJ7TGAAAIZsBNkKDCRcL179+E1TJGXpysDCysbw4dPPxjMzUzgmkFqQGqhqXInQACBkzIw/fcAOcVICUkUm39BmoEJ6TcwIUkBub3AfFECEECwlDgFlDxBKezhw8cfPn36hC8pgwxfAtXDABBAFGcmgABipDQ7AwQYAOqo3UvZE3l2AAAAAElFTkSuQmCC",
        MYTPLS:{
            'html':    //für Darstellung als vollständiges html5-Dokument
                {
                'fileext':'html',
                'opendatauri': false,
                'intro':'<!DOCTYPE html>\n<html>\n<head>\n<meta charset="UTF-8">\n'
                    +'<title>Meine Firefox-Informationen</title>\n</head>\n<body>\n<h1>Meine Firefox-Informationen</h1>\n',
                'tpllastupd':'<div>\nLetzte Aktualisierung: %%lastupd%%\n</div>',
                'tpluseragent':'<div>\nUser Agent: %%useragent%%\n</div>',
                'tpladdongrp_title':{
                                    'extension':'<div id="extensions">\n<h2>Erweiterungen <small>(aktiviert: %%countactive%%, deaktiviert: %%countinactive%%, gesamt: %%count%%)</small></h2>',
                                    'theme':'<div id="themes">\n<h2>Themes <small>(%%count%%)</small></h2>',
                                    'plugin':'<div id="plugins">\n<h2>Plugins <small>(%%count%%)</small></h2>',
                                    'dictionary':'<div id="dictionaries">\n<h2>Wörterbücher <small>(%%count%%)</small></h2>',
                                    'service':'<div id="services">\n<h2>Dienste <small>(%%count%%)</small></h2>',
                                    'userstyle':'<div id="userstyles">\n<h2>Userstyles <small>(%%count%%)</small></h2>',
                                    'greasemonkey-user-script':'<div id="gmscripts">\n<h2>Greasemonkey <small>(aktiviert: %%countactive%%, deaktiviert: %%countinactive%%, gesamt: %%count%%)</small></h2>',
                                    'userchromejs':'<div id="userchromejs">\n<h2>userChromeJS <small>(%%count%%)</small></h2>'
                                    },
                'tpladdongrp_intro':{
                                    'default':'',
                                    'greasemonkey-user-script':'<p>Greasemonkey-Skripte können Webseiten um diverse Funktionen erweitern.</p>',
                                    'userchromejs':'<p>Durch die Erweiterung <a href="http://userchromejs.mozdev.org/">userChromeJS</a> eingebundene Skripte ergänzen den Firefox um diverse Funktionen.</p>'
                                    },
                'tpladdongrp_list_intro':{
                                    'default':'<ul>'
                                    },
                'tpladdon':'<li class="%%class%%"><a href="%%homepageURL%%">%%name%%</a> %%version%%: %%description%%%%disabled%%</li>\n',
                'tpladdon_without_url':'<li class="%%class%%">%%name%% %%version%%: %%description%%%%disabled%%</li>\n',
                'activeclass':'addonactive',
                'inactiveclass':'addoninactive',
                'disabledtext':'<small><span style="color:#ff0000;">[deaktiviert]</span></small>',
                'tpladdongrp_list_outro':'</ul>\n',
                'tpladdongrp_outro':'</div>\n\n',
                'outro':'</body>\n</html>'
                },
            'bbcode':    //für Postings in Foren, die bbcode unterstützen
                {
                'fileext':'txt',
                'opendatauri': true,
                'intro':'Meine Firefox-Informationen\n\n',
                'tpllastupd':'Letzte Aktualisierung: %%lastupd%%',
                'tpluseragent':'User Agent: %%useragent%%\n',
                'tpladdongrp_title':{
                                    'extension':'[b]Erweiterungen[/b] (aktiviert: %%countactive%%, deaktiviert: %%countinactive%%, gesamt: %%count%%)',
                                    'theme':'[b]Themes[/b] (%%count%%)',
                                    'plugin':'[b]Plugins[/b] (%%count%%)',
                                    'dictionary':'[b]Wörterbücher[/b] (%%count%%)',
                                    'service':'[b]Dienste[/b] (%%count%%)',
                                    'userstyle':'[b]Userstyles[/b] (%%count%%)',
                                    'greasemonkey-user-script':'[b]Greasemonkey[/b] (aktiviert: %%countactive%%, deaktiviert: %%countinactive%%, gesamt: %%count%%)',
                                    'userchromejs':'[b]userChromeJS[/b] (%%count%%)'
                                    },
                'tpladdongrp_intro':{
                                    'default':'',
                                    'greasemonkey-user-script':'Greasemonkey-Skripte können Webseiten um diverse Funktionen erweitern.',
                                    'userchromejs':'Durch die Erweiterung [url=http://userchromejs.mozdev.org/]userChromeJS[/url] eingebundene Skripte ergänzen den Firefox um diverse Funktionen.'
                                    },
                'tpladdongrp_list_intro':{
                                    'default':'[list]'
                                    },
                'tpladdon':'[*][url=%%homepageURL%%]%%name%%[/url] %%version%%: %%description%%%%disabled%%\n',
                'tpladdon_without_url':'[*]%%name%% %%version%%: %%description%%%%disabled%%\n',
                'activeclass':'addonactive',
                'inactiveclass':'addoninactive',
                'disabledtext':' [color=red][deaktiviert][/color]',
                'tpladdongrp_list_outro':'[/list]\n',
                'tpladdongrp_outro':'\n',
                'outro':''
                },
            'custom':    //Beispiel - für Darstellung als "include" in einem anderen (x)html-Dokument
                {
                'fileext':'txt',
                'opendatauri': true,
                'intro':'<p id="bsbuttons">\n'
                    +'<a class="tab active" href="http://www.ardiman.de/sonstiges/fxconfig.html?mode=windows">Windows 7</a>\n'
                    +'<a class="tab" href="http://www.ardiman.de/sonstiges/fxconfig.html?mode=ubuntu">XUbuntu</a>\n'
                    +'</p>\n'
                    +'<div id="buttons">\n'
                    +'<a class="tab" href="http://www.ardiman.de/sonstiges/fxconfig.html#extensions">Erweiterungen</a>\n'
                    +'<a class="tab" href="http://www.ardiman.de/sonstiges/fxconfig.html#themes">Themes</a>\n'
                    +'<a class="tab" href="http://www.ardiman.de/sonstiges/fxconfig.html#plugins">Plugins</a>\n'
                    //+'<a class="tab" href="http://www.ardiman.de/sonstiges/fxconfig.html#dictionaries">Wörterbücher</a>\n'
                    //+'<a class="tab" href="http://www.ardiman.de/sonstiges/fxconfig.html#services">Dienste</a>\n'
                    //+'<a class="tab" href="http://www.ardiman.de/sonstiges/fxconfig.html#userstyles">Userstyles</a>\n'
                    +'<a class="tab" href="http://www.ardiman.de/sonstiges/fxconfig.html#gmscripts">Greasemonkey</a>\n'
                    +'<a class="tab" href="http://www.ardiman.de/sonstiges/fxconfig.html#userchromejs">userChromeJS</a>\n'
                    +'<br/></div>\n',
                'tpllastupd':'<div class="lastupd">\nLetzte Aktualisierung: %%lastupd%%\n</div>',
                'tpluseragent':'<div class="useragent">\nUser Agent: %%useragent%%\n</div>',
                'tpladdongrp_title':{
                                    'extension':'<div id="extensions" class="tab-element">\n<h2><img alt="" style="float: right; margin: 0.5ex 1ex 0 0;" width="16" height="16" src="/assets/images/fx_extensions.png" />Erweiterungen <small>(aktiviert: %%countactive%%, deaktiviert: %%countinactive%%, gesamt: %%count%%)</small></h2>',
                                    'theme':'<div id="themes" class="tab-element">\n<h2><img alt="" style="float: right; margin: 0.5ex 1ex 0 0;" width="16" height="16" src="/assets/images/fx_themes.png" />Themes <small>(%%count%%)</small></h2>',
                                    'plugin':'<div id="plugins" class="tab-element">\n<h2><img alt="" style="float: right; margin: 0.5ex 1ex 0 0;" width="16" height="16" src="/assets/images/fx_plugins.gif" />Plugins <small>(%%count%%)</small></h2>',
                                    'dictionary':'<div id="dictionaries" class="tab-element">\n<h2><img alt="" style="float: right; margin: 0.5ex 1ex 0 0;" width="16" height="16" src="/assets/images/fx_dictionaries.png" />Wörterbücher <small>(%%count%%)</small></h2>',
                                    'service':'<div id="services" class="tab-element">\n<h2><img alt="" style="float: right; margin: 0.5ex 1ex 0 0;" width="16" height="16" src="/assets/images/fx_services.png" />Dienste <small>(%%count%%)</small></h2>',
                                    'userstyle':'<div id="userstyles" class="tab-element">\n<h2><img alt="" style="float: right; margin: 0.5ex 1ex 0 0;" width="16" height="16" src="/assets/images/fx_styles.png" />Userstyles <small>(%%count%%)</small></h2>',
                                    'greasemonkey-user-script':'<div id="gmscripts" class="tab-element">\n<h2><img alt="" style="float: right; margin: 0.5ex 1ex 0 0;" width="16" height="16" src="/assets/images/fx_monkey.png" />Greasemonkey <small>(aktiviert: %%countactive%%, deaktiviert: %%countinactive%%, gesamt: %%count%%)</small></h2>',
                                    'userchromejs':'<div id="userchromejs" class="tab-element">\n<h2><img alt="" style="float: right; margin: 0.5ex 1ex 0 0;" width="16" height="16" src="/assets/images/fx_javascript.gif" />userChromeJS <small>(%%count%%)</small></h2>'
                                    },
                'tpladdongrp_intro':{
                                    'default':'',
                                    'greasemonkey-user-script':'<p>Einige Skripte stammen direkt von mir (s. auch <a href="http://www.ardiman.de/sonstiges/fxconfig/gmskripte.html">Greasemonkey-Skripte</a> bzw. <a class="extlink" href="https://openuserjs.org/users/ardiman/scripts" rel="nofollow">https://openuserjs.org/users/ardiman/scripts</a>), andere wurden nur geringf&uuml;gig angepasst.</p>',
                                    'userchromejs':'<p id="fxcuclisteintro">Durch die Erweiterung userChromeJS eingebundene Skripte erg&auml;nzen den Firefox um diverse Funktionen.</p>'
                                    },
                'tpladdongrp_list_intro':{
                                    'default':'<ul>',
                                    'userchromejs':'<ul id="fxcucliste">'
                                    },
                'tpladdon':'<li class="%%class%%"><a href="%%homepageURL%%" rel="nofollow" class="extlink">%%name%%</a> %%version%%: %%description%%%%disabled%%</li>\n',
                'tpladdon_without_url':'<li class="%%class%%">%%name%% %%version%%: %%description%%%%disabled%%</li>\n',
                'activeclass':'addonactive',
                'inactiveclass':'addoninactive',
                'disabledtext':' <small>[deaktiviert]</small>',
                'tpladdongrp_list_outro':'</ul>\n',
                'tpladdongrp_outro':'</div>\n\n',
                'outro':''
                }
        },
    // ----- Ende Expertenkonfiguration
    
        MYSTOR: {},
        FILEUTILS: ChromeUtils.importESModule('resource://gre/modules/FileUtils.sys.mjs').FileUtils,
        init: function() {
            // legt verschiebbaren Button und Menü unter Extras an
            // Button
            if (location != "chrome://browser/content/browser.xhtml") return;
            try {
                CustomizableUI.createWidget({
                    id: 'adonli-button',
                    type: 'custom',
                    // defaultArea: CustomizableUI.AREA_NAVBAR,
                    onBuild: function(aDocument) {
                        var toolbaritem = aDocument.createElementNS('http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul', 'toolbarbutton');
                        var attributes = {
                            id: 'adonli-button',
                            class: 'toolbarbutton-1 chromeclass-toolbar-additional',
                            removable: 'true',
                            label: 'AddonLister',
                            tooltiptext: 'AddOnLister starten (Erstellung im Format »'+ADONLI.FORMAT+'«):\nLinksklick öffnet Ergebnis im Editor\nMittelklick öffnet Ergebnis als Tab im Browser\nRechtsklick exportiert die Liste ohne Anzeige im Editor oder Browser',
                            style: 'list-style-image: url(' + ADONLI.ICON_URL + ')',
                            //onclick: 'event.preventDefault(); return ADONLI.launch(event.button, \"' + ADONLI.FORMAT +'\");'
                        };
                    for (var a in attributes)
                        toolbaritem.setAttribute(a, attributes[a]);
    				    toolbaritem.addEventListener('click', function() {
    					event.preventDefault();
    					return ADONLI.launch(event.button, ADONLI.FORMAT);
    				});
                        return toolbaritem;
                    }
                });
            } catch(e) { };
            // Menü
            function addNode(parentId, type, attributes) {
                let node = document.createXULElement(type);
                for (let a in attributes) {
                    node.setAttribute(a, attributes[a]);
                };
                document.getElementById(parentId).appendChild(node);
            };
            addNode("menu_ToolsPopup", "menu", {
                id: "menu_ucjsAddonLister",
                accesskey: "L",
                label: "AddonLister",
                class: "menu-iconic",
                style: "list-style-image: url(" + ADONLI.ICON_URL + ")"
            });
            document.getElementById("menu_ToolsPopup")
                .insertBefore(document.getElementById("menu_ucjsAddonLister"),
                              document.getElementById("menu_openAddons").nextSibling);
            addNode("menu_ucjsAddonLister", "menupopup", {
                id: "menu_ucjsAddonLister-popup"
            });
            addNode("menu_ucjsAddonLister-popup", "menu", {
                id: "menu_ucjsAddonLister-bbcode",
                accesskey: "B",
                label: "BBCODE",
                class: "menu-iconic"
            });
            addNode("menu_ucjsAddonLister-bbcode", "menupopup", {
                id: "menu_ucjsAddonLister-popup-bbcode"
            });
            addNode("menu_ucjsAddonLister-popup-bbcode", "menuitem", {
                id: "menu_ucjsAddonLister_editor-bbcode",
                class: "menAddonLister_item",
              // oncommand: "ADONLI.launch(0,\'bbcode\')",		   	
                accesskey: "E",
                label: "Liste erstellen und im Editor anzeigen"			
            });
    			document.getElementById("menu_ucjsAddonLister_editor-bbcode").addEventListener('command', () => {
    				 ADONLI.launch (0, 'bbcode');				
    			});
            addNode("menu_ucjsAddonLister-popup-bbcode", "menuitem", {
                id: "menu_ucjsAddonLister_browser-bbcode",
                class: "menAddonLister_item",
               // oncommand: "ADONLI.launch(1,\'bbcode\')",
                accesskey: "A",
                label: "Liste erstellen und im Browser anzeigen"
            });
    		document.getElementById("menu_ucjsAddonLister_browser-bbcode").addEventListener('command', () => {
    				 ADONLI.launch (1, 'bbcode');				
    			});
            addNode("menu_ucjsAddonLister-popup-bbcode", "menuitem", {
                id: "menu_ucjsAddonLister_write-bbcode",
                class: "menAddonLister_item",
              //  oncommand: "ADONLI.launch(2,\'bbcode\')",
                accesskey: "o",
                label: "Liste erstellen ohne Anzeige"
            });
    		document.getElementById("menu_ucjsAddonLister_write-bbcode").addEventListener('command', () => {
    				 ADONLI.launch (2, 'bbcode');				
    			});
            addNode("menu_ucjsAddonLister-popup", "menu", {
                id: "menu_ucjsAddonLister-html",
                accesskey: "H",
                label: "HTML",
                class: "menu-iconic"
            });
            addNode("menu_ucjsAddonLister-html", "menupopup", {
                id: "menu_ucjsAddonLister-popup-html"
            });
            addNode("menu_ucjsAddonLister-popup-html", "menuitem", {
                id: "menu_ucjsAddonLister_editor-html",
                class: "menAddonLister_item",
             //   oncommand: "ADONLI.launch(0,\'html\')",
                accesskey: "E",
                label: "Liste erstellen und im Editor anzeigen"
            });
    		document.getElementById("menu_ucjsAddonLister_editor-html").addEventListener('command', () => {
    				 ADONLI.launch (0, 'html');				
    			});
            addNode("menu_ucjsAddonLister-popup-html", "menuitem", {
                id: "menu_ucjsAddonLister_browser-html",
                class: "menAddonLister_item",
               // oncommand: "ADONLI.launch(1,\'html\')",
                accesskey: "A",
                label: "Liste erstellen und im Browser anzeigen"
            });
    		document.getElementById("menu_ucjsAddonLister_browser-html").addEventListener('command', () => {
    				 ADONLI.launch (1, 'html');				
    			});
            addNode("menu_ucjsAddonLister-popup-html", "menuitem", {
                id: "menu_ucjsAddonLister_write-html",
                class: "menAddonLister_item",
              //  oncommand: "ADONLI.launch(2,\'html\')",
                accesskey: "o",
                label: "Liste erstellen ohne Anzeige"
            });
    		document.getElementById("menu_ucjsAddonLister_write-html").addEventListener('command', () => {
    				 ADONLI.launch (2, 'html');				
    			});
            addNode("menu_ucjsAddonLister-popup", "menu", {
                id: "menu_ucjsAddonLister-custom",
                accesskey: "C",
                label: "Custom",
                class: "menu-iconic"
            });
            addNode("menu_ucjsAddonLister-custom", "menupopup", {
                id: "menu_ucjsAddonLister-popup-custom"
            });
            addNode("menu_ucjsAddonLister-popup-custom", "menuitem", {
                id: "menu_ucjsAddonLister_editor-custom",
                class: "menAddonLister_item",
            //    oncommand: "ADONLI.launch(0,\'custom\')",
                accesskey: "E",
                label: "Liste erstellen und im Editor anzeigen"
            });
    		document.getElementById("menu_ucjsAddonLister_editor-custom").addEventListener('command', () => {
    				 ADONLI.launch (0, 'custom');				
    			});
            addNode("menu_ucjsAddonLister-popup-custom", "menuitem", {
                id: "menu_ucjsAddonLister_browser-custom",
                class: "menAddonLister_item",
              //  oncommand: "ADONLI.launch(1,\'custom\')",
                accesskey: "A",
                label: "Liste erstellen und im Browser anzeigen"
            });
    		document.getElementById("menu_ucjsAddonLister_browser-custom").addEventListener('command', () => {
    				 ADONLI.launch (1, 'custom');				
    			});
            addNode("menu_ucjsAddonLister-popup-custom", "menuitem", {
                id: "menu_ucjsAddonLister_write-custom",
                class: "menAddonLister_item",
            //    oncommand: "ADONLI.launch(2,\'custom\')",
                accesskey: "o",
                label: "Liste erstellen ohne Anzeige"
            });
    		document.getElementById("menu_ucjsAddonLister_write-custom").addEventListener('command', () => {
    				 ADONLI.launch (2, 'custom');				
    			});
            addNode("menu_ucjsAddonLister-popup", "menuitem", {
                tooltiptext: "Erstellung im Format »" + ADONLI.FORMAT + "«",
                id: "menu_ucjsAddonLister_editor",
                class: "menAddonLister_item",
               // oncommand: "ADONLI.launch(0,\'" + ADONLI.FORMAT + "\')",
                accesskey: "E",
                label: "Liste erstellen und im Editor anzeigen"
            });
    		document.getElementById("menu_ucjsAddonLister_editor").addEventListener('command', () => {
    				 ADONLI.launch (0, ADONLI.FORMAT);				
    			});
            addNode("menu_ucjsAddonLister-popup", "menuitem", {
                tooltiptext: "Erstellung im Format »" + ADONLI.FORMAT + "«",
                id: "menu_ucjsAddonLister_browser",
                class: "menAddonLister_item",
              //  oncommand: "ADONLI.launch(1,\'" + ADONLI.FORMAT + "\')",
                accesskey: "A",
                label: "Liste erstellen und im Browser anzeigen"
            });
    		document.getElementById("menu_ucjsAddonLister_browser").addEventListener('command', () => {
    				 ADONLI.launch (1, ADONLI.FORMAT);				
    			});
            addNode("menu_ucjsAddonLister-popup", "menuitem", {
                tooltiptext: "Erstellung im Format »" + ADONLI.FORMAT + "«",
                id: "menu_ucjsAddonLister_write",
                class: "menAddonLister_item",
              //  oncommand: "ADONLI.launch(2,\'" + ADONLI.FORMAT + "\')",
                accesskey: "o",
                label: "Liste erstellen ohne Anzeige"
            });
    		document.getElementById("menu_ucjsAddonLister_write").addEventListener('command', () => {
    				 ADONLI.launch (2, ADONLI.FORMAT);				
    			});
        },
    
        launch: function(e,format) {
            // ruft alle noetigen Funktionen nach Klick auf Toolbarbutton auf
            var ctrlConf = "";
            if (this.CHECKCONFIG) ctrlConf = this.configCheck();
            if (ctrlConf === "") {
                var expfile =  this.EXPORTPATH + this.EXPORTFILE + "." + this.MYTPLS[format].fileext;
                this.getOtherValues();
                this.resetStor();
                this.getAddons();
                if (this.WHICHTYPES.indexOf('userchromejs') !== -1) this.getScripts();
                var result = this.writeAddons(expfile,format);
                this.showAddons(e,this.TEXTOPENEXE,expfile,format,result);
            } else {
                alert ("Lt. Konfigurationstest des AddonListers muss folgendes kontrolliert werden:\n" + ctrlConf);
            }
        },
    
        configCheck: function() {
            var fehler = "";
            // Kontrolle des Pfades
            if (this.EXPORTPATH.substr(-1) !== "\\" && this.EXPORTPATH.substr(-1) !== "/") fehler += "\n - Der Pfad in EXPORTPATH endet nicht mit einem Verzeichnistrenner.";
            if (!this.fileExists(this.EXPORTPATH)) fehler += "\n - Der Pfad »" + this.EXPORTPATH + "« in EXPORTPATH existiert nicht.";
            // Kontrolle des Dateinamens
            if (this.EXPORTFILE.indexOf(".") !== -1) fehler += "\n - Der Dateiname in EXPORTFILE sollte keinen Punkt enthalten (ohne Erweiterung sein).";
            if (this.EXPORTFILE.length === 0) fehler += "\n - Es wurde kein Dateiname in EXPORTFILE hinterlegt.";
            // Kontrolle des Formates
            var formate = ["bbcode", "custom", "html"];
            if (formate.indexOf(this.FORMAT) === -1) fehler += "\n - Ungültiges FORMAT »" + this.FORMAT + "«.";
            // Kontrolle des Editors
            if (!this.fileExists(this.TEXTOPENEXE)) {
                var pref = Cc["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
                if (!this.fileExists(pref.getCharPref("view_source.editor.path"))) {
                    fehler += "\n - Der in TEXTOPENEXE und about:config [view_source.editor.path] hinterlegte Editor kann nicht gefunden werden.";
                }
            }
            // Kontrolle der gewünschten Addon-Typen, folgende sind momentan gültig:
            var addontypes = ["extension","theme","plugin","dictionary","service","userstyle","greasemonkey-user-script","userchromejs"];
            var w;
            for (w = 0; w < this.WHICHTYPES.length; w++) {
                if (addontypes.indexOf(this.WHICHTYPES[w]) === -1) {
                    fehler += "\n - In WHICHTYPES wurden ein oder mehrere unbekannte Add-on-Typen (z.B. »" + this.WHICHTYPES[w] + "«) gewählt.";
                    break;
                }
            }
            return fehler;
        },
    
        fileExists: function(mypath) {
            // kontrolliert, ob Pfad oder Datei gültig/vorhanden ist
            var file = new this.FILEUTILS.File(mypath);
            return file.exists();
        },
    
        resetStor: function() {
            // setzt das JSON-Object (bzw. die "Listen" darin) zurueck
            var h;
            for (h = 0; h < this.WHICHTYPES.length; h++) {
                this.MYSTOR[this.WHICHTYPES[h]] = [];
            }
        },
    
        getOtherValues: function() {
            // speichert momentan Auswertungsdatum und useragent im JSON-Object
            var options;
            options = {weekday: "long", year: "numeric", month: "long", day: "numeric", hour: "numeric", minute: "numeric", second: "numeric", hour12: false};
            if (this.SHOWDATE) this.MYSTOR["lastupd"] = new Date().toLocaleDateString("de-DE", options);
            if (this.SHOWUSERAGENT) this.MYSTOR["useragent"] = window.navigator.userAgent;
        },
    
        getAddons: function() {
            // speichert die gewaehlten Addons (s. WHICHTYPES) im JSON-Object
            var i, x, j, iAo, Addons, added, storedItems;
            AddonManager.getAddonsByTypes(this.WHICHTYPES).then(function(addonlist) {
                Addons = addonlist;
            });
            var thread = Cc['@mozilla.org/thread-manager;1'].getService().mainThread;
            while (Addons === void(0)) {
                thread.processNextEvent(true);
            }
            // Schleife ueber Addons
            for (i = 0; i < Addons.length; i++) {
                iAo = Addons[i];
                added = false;
                storedItems = this.MYSTOR[iAo.type].length;
                // nächste Aktionen nur, wenn Addon *nicht* in BLACKLIST steht
                if (this.BLACKLIST.indexOf(iAo.name) === -1) {
                    // Ablage gleich sortiert vornehmen
                    for (j = 0; j < storedItems; j++) {
                        if (iAo.name.toLowerCase() < this.MYSTOR[iAo.type][j].name.toLowerCase()) {
                            this.MYSTOR[iAo.type].splice(j,0,{ 'name': iAo.name, 'version': iAo.version, 'active': iAo.isActive, 'homepage': iAo.homepageURL});
                            added = true;
                            break;
                        }
                    }
                    if (!added) this.MYSTOR[iAo.type].push({ 'name': iAo.name, 'version': iAo.version, 'active': iAo.isActive, 'homepage': iAo.homepageURL});
                }
            }
        },
    
        getScripts: function() {
            // speichert ggf. im Chrome-Ordner vorhandene uc.js und uc.xul-Dateien im JSON-Object
            var hp, j, storedItems, added;
            // Suchmuster, also die Dateierweiterungen uc.js und uc.xul
            let extjs = /\.uc\.js$/i;
            let extxul = /\.uc\.xul$/i;
            let aFolder = Cc["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("UChrm", Components.interfaces.nsIFile);
            // files mit Eintraegen im Chrome-Ordner befuellen
            let files = aFolder.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);
            // Ordner bzw. Dateien durchlaufen und kontrollieren, ob gesuchte Dateien dabei sind
            while (files.hasMoreElements()) {
                let file = files.getNext().QueryInterface(Ci.nsIFile);
                // keine gewuenschte Datei, deshalb continue
                if ((!extjs.test(file.leafName) && !extxul.test(file.leafName)) || this.BLACKLIST.indexOf(file.leafName) !== -1) continue;
                // uc.js bzw. uc.xul gefunden, die nicht in der Blacklist stehen -> Ablage sortiert (unter Linux erforderlich) im JSON vornehmen
                hp = this.githubLink(file.leafName);
                added = false;
                storedItems = this.MYSTOR.userchromejs.length;
                for (j = 0; j < storedItems; j++) {
                    if (file.leafName.toLowerCase() < this.MYSTOR.userchromejs[j].name.toLowerCase()) {
                        this.MYSTOR.userchromejs.splice(j,0,{'name': file.leafName, 'version': undefined, 'active': true, 'description': undefined, 'homepage': hp});
                        added = true;
                        break;
                    }
                }
                if (!added) this.MYSTOR.userchromejs.push({'name': file.leafName, 'version': undefined, 'active': true, 'description': undefined, 'homepage': hp});
            }
        },
    
        githubLink: function(sName) {
            // übergibt für gegebenen Skriptnamen den Link zu github
            // früher Ausstieg, da Skript nicht verlinkt werden soll
            if (this.GITHUBBLACKLIST.indexOf(sName) !== -1 || this.GITHUBBLACKLIST.indexOf("*") !== -1) return null;
            sName = sName.toLowerCase();
            /* Das folgende Array enthaelt regulaere Ausdruecke, um ungueltige Zeichenfolgen entfernen:
            /Datei-Erweiterungen am Ende/, /"ucjs_" am Anfang/, /"_"gefolgtVonZahlUndDanachBeliebigenZeichen/
            / "_fx"gefolgtVonZahl(en)/, /"-" oder "+" oder "."/, /"_v"gefolgtVonZahlen
            */
            var regs = [/\.uc\.js$/,/\.uc\.xul$/,/^ucjs_/,/_\d.+/,/_fx\d+/,/[-+\.]/g,/_v\d+/];
            for (var i = 0; i < regs.length; i++) {
                sName = sName.replace(regs[i],"");
            }
            return "https://github.com/ardiman/userChrome.js/tree/master/" + sName;
        },
    
        writeAddons: function(file,format){
            var a, t, c, n, d, atype, aout, thisaddon;
            var output = "";
            var addontpl = "";
            var addontplwithouturl = "";
            
            addontpl = this.MYTPLS[format].tpladdon;
            addontplwithouturl = this.MYTPLS[format].tpladdon_without_url;
            output += this.MYTPLS[format].intro;
    
            if (this.SHOWDATE) output +=  this.MYTPLS[format].tpllastupd.replace(/%%lastupd%%/g,this.MYSTOR.lastupd)+"\n";
            if (this.SHOWUSERAGENT) output +=  this.MYTPLS[format].tpluseragent.replace(/%%useragent%%/g,this.MYSTOR.useragent)+"\n";
    
            for (t = 0; t < this.WHICHTYPES.length; t++) {
                atype = this.WHICHTYPES[t];
                c = this.MYSTOR[atype].length;
                n = 0;
                d = 0;
                output += this.MYTPLS[format].tpladdongrp_title[atype].replace(/%%count%%/g,c)+"\n";
                if (this.MYTPLS[format].tpladdongrp_intro[atype] == undefined) {
                    output += this.MYTPLS[format].tpladdongrp_intro.default + (this.MYTPLS[format].tpladdongrp_intro.default.length > 0 ? "\n" : "");
                } else {
                    output += this.MYTPLS[format].tpladdongrp_intro[atype] + (this.MYTPLS[format].tpladdongrp_intro[atype].length > 0 ? "\n" : "");
                }
                if (this.MYTPLS[format].tpladdongrp_list_intro[atype] == undefined) {
                    output += this.MYTPLS[format].tpladdongrp_list_intro.default+"\n";
                } else {
                    output += this.MYTPLS[format].tpladdongrp_list_intro[atype]+"\n";
                }
                for (a = 0; a < c; a++) {
                    thisaddon =  this.MYSTOR[atype][a];
                    // console.log(atype + " " + thisaddon.name + " " + thisaddon.active);
                    if (thisaddon.homepage == undefined) {
                        aout = addontplwithouturl;
                    } else {
                        aout = addontpl;
                        aout = aout.replace(/%%homepageURL%%/g,thisaddon.homepage.replace(/&(?!amp;)/g,'&amp;'));
                    }
                    aout = aout.replace(/%%name%%/g,thisaddon.name);
                    if (thisaddon.version == undefined) {
                        if (thisaddon.description != undefined) {
                            aout = aout.replace(/ %%version%%: /g,": ");
                        } else {
                            aout = aout.replace(/ %%version%%: /g,"");
                        }
                    }
                    aout = aout.replace(/%%version%%/g,thisaddon.version);
                    if (thisaddon.description != undefined) {
                        aout = aout.replace(/%%description%%/g,thisaddon.description);
                    } else {
                        aout = aout.replace(/%%description%%/g,"");
                    }
                    if (thisaddon.active !== true) {
                        aout = aout.replace(/%%class%%/g,this.MYTPLS[format].inactiveclass);
                        aout = aout.replace(/%%disabled%%/g,this.MYTPLS[format].disabledtext);
                        d++;
                    } else {
                        aout = aout.replace(/%%class%%/g,this.MYTPLS[format].activeclass);
                        aout = aout.replace(/%%disabled%%/g,"");
                        n++;
                    }
                    output += aout;
                }
                output = output.replace(/%%countactive%%/g,n).replace(/%%countinactive%%/g,d);
                output += this.MYTPLS[format].tpladdongrp_list_outro;
                output += this.MYTPLS[format].tpladdongrp_outro;
            }
            output += this.MYTPLS[format].outro+"\n";
            let encoder = new TextEncoder();
            let myarray = encoder.encode(output);
            let promise = IOUtils.write(file, myarray);
            return output;
        },
    
        showAddons: function(e,RanPath,OpenPath,format,myoutput) {
            // zeigt das EXPORTFILE im Editor oder im Browser (Mittelklick) an
            switch (e) {
                case 0:
                    var file = new this.FILEUTILS.File(RanPath);
                    var proc = Cc["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess);
                    var args = [OpenPath];
                    // falls der im Konfigurationsabschnitt definierte Editor nicht gefunden wird, auf Einstellung in about:config ausweichen:
                    if (!this.fileExists(RanPath)) {
                        console.log("AddonLister meldet: Editor nicht gefunden, ausweichen auf about:config.");
                        var pref = Cc["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
                        RanPath = pref.getCharPref("view_source.editor.path");
                        file = new this.FILEUTILS.File(RanPath);
                    }
                    proc.init(file);
                    proc.run(false, args, args.length);
                    break;
                case 1:
                    if (this.MYTPLS[format].opendatauri) {
                        var datastring = myoutput.replace(/\n/g,"%0A").replace(/#/g,"%23");
                        // getBrowser().selectedTab = getBrowser().addTrustedTab('data:text/plain;charset=utf-8,' + datastring);
                        openTrustedLinkIn('data:text/plain;charset=utf-8,' + datastring, "tab");
                        XULBrowserWindow.statusTextField.label = "Export nach  »"+ OpenPath + "« ist erfolgt.";
                    } else {
                        // alert sorgt ein wenig dafür, dem OS Zeit fürs Speichern der Datei zu geben ...
                        alert("Export nach »"+ OpenPath + "« ("+ format + "-format) ist erfolgt.");
                        openTrustedLinkIn(OpenPath, "tab");
                        //getBrowser().selectedTab = getBrowser().addTrustedTab(OpenPath);
                    }
                    break;
                default:
                    XULBrowserWindow.statusTextField.label = "Export nach  »"+ OpenPath + "« ist erfolgt.";
                    break;
            }
        }
    
    };
    
    ADONLI.init();
    Alles anzeigen

    Endor Wenn milupo sein OK gibt, dann nimm doch bitte diese Version.

  • Was schaut ihr gerade?

    • Mira_Belle
    • 4. Mai 2025 um 09:47

    Jessie Wow, jetzt verstehe ich auch, warum solche Schuhe mehrere hundert Euro kosten.
    Danke für den Klipp.

  • userChrome.js Scripte für den Fuchs (Diskussion)

    • Mira_Belle
    • 4. Mai 2025 um 09:30

    Test die Version von hier.

  • Mehrzeilige Tableiste für aktuelle Firefox-Versionen

    • Mira_Belle
    • 3. Mai 2025 um 23:24

    Tabbreite auf 165px eingestellt, Tabhöhe ist und war auf 35px eingestellt.
    Hier die "MultiRowTabLiteforFx.uc.js"

    JavaScript
    // ==UserScript==
    // @name           MultiRowTabLiteforFx.uc.js
    // @namespace      Based on Alice0775's zzzz-MultiRowTab_LiteforFx48.uc.js
    // @description    Mehrzeilige Tableiste - Experimentelle CSS Version
    // @include        main
    // @compatibility  Firefox 138+
    // @version        2025/04/07 12:00
    // ==/UserScript==
    "use strict";
    
    MultiRowTabLiteforFx();
    function MultiRowTabLiteforFx() {
    if (!window.gBrowser) { return; }
    
        // -- Config --
        // Vergleichbarer CSS Code in userChrome.css Datei wird vorrangig behandelt!
    
        const                                                 // Mehrzeilige Tableiste Ein/Aus Anzahl der Tabzeilen
        MultiRowTab_OnOff_and_TabBar_Rows =       -1         ,// [-1] = Mehrzeilige Tableiste aktiv unbegrenzte Anzahl von Zeilen.
                                                              //  0   = Mehrzeilige Tableiste aus.
                                                              //  1   = Mehrzeilige Tableiste aktiv. Standard = 1 Zeile. Bei Berührung
                                                              //        der Tableiste mit der der Maus, werden die zweite und die folgenden 
                                                              //        Zeilen bis zur angegebenen Anzahl von Zeilen angezeigt.
                                                              //  2   = Mehrzeilige Tableiste aktiv. Anzahl der Tabzeilen angeben.
    	    
        TabBar_Rows_on_MouseOver =                3          ,// Standard = 1 Zeile. Anzahl der Zeilen angeben, die angezeigt werden sollen, 
                                                              // wenn der Mauszeiger über die Tableiste bewegt wird. Voraussetzung: 
                                                              // „MultiRowTab_OnOff_and_TabBar_Rows“ auf „1“ setzen.
    	    
        TabBar_DisplayTime_on_MouseOver =         1          ,// Sie können die Anzeigezeit (Sekunden) festlegen, wann die zweite und die 
                                                              // folgenden Zeilen beim Mouseover angezeigt werden. Das Display zeigt den  
                                                              // eingestellten Wert(Sekunden) an und kehrt dann zur ersten Zeile zurück.
    
                                                              // Position der Tab-Leiste.
        TabBar_Position =                         1          ,// [0] = Standard
                                                              // 1   = unter der Symbolleiste
                                                              // 2   = unter dem Fenster
    
                                                              // Positionen der Tab-Leiste und der Lesezeichen-Symbolleiste tauschen.
                                                              // sofern die Position der Tab-Leiste unterhalb der Symbolleiste festgelegt ist.
                                                              // Voraussetzung: "TabBar_Position" auf "1".
        Bookmark_Toolbar_Position =             true         ,// [true] = Menüleiste, Navigationsleiste, Lesezeichenleiste, Tableiste
                                                              // false = Menüleiste, Navigationsleiste, Tableiste, Lesezeichensymbolleiste
    
                                                              // Tab-Höhe „UI-Dichte“
        UI_Density_Compact =                    35           ,// Standard = 29 Pixelbei Kompakt
        UI_Density_Normal =                     35           ,// Standard = 36 Pixel bei Normal
        UI_Density_Touch =                      41           ,// Standard = 41 Pixel bei Touch
    
                                                              // Tab-Breite
        Tab_Min_Width =                        165           ,// Standard - Mindestwert = 76px
        Tab_Max_Width =                        165           ,// Standard - Maxwert = 225px
                                                              // Bei gleichen Werten bei Min und Max, wird die Tabbreite fixiert!
    
                                                              // „Tab schließen“ Schaltfläche
        Tab_Close_Button =                       0           ,// [0] = Standard
                                                              //  1  = Ausgeblendet
                                                              //  2  = Auf allen Tabs anzeigen
                                                              //  3  = Nur bei Mausberührung anzeigen
                                                              //  4  = Aktive Tabs werden immer angezeigt, inaktive Tabs
                                                              // werden beim Mouseover angezeigt. *Standard für vertikalen Tab-Modus.
    
                                                              // ProtonUI Erscheinungsbild der Tabs ändern
        Proton_Margins =                      true           ,// [true] = Darstellung ProtonUI
                                                              // Die Höhe der Tab-Leiste entspricht der Höhe der UI-Dichte plus dem Leerraum darüber
                                                              // und darunter.                                                 
                                                              // false  = Darstellung wie bei browser.proton.enabled auf false, was man vor Firefox 90
                                                              // noch einstellen konnte.
                                                              // Wenn der Leerraum um die Tabs auf 0 und die Höhe auf die UI-Dichte eingestellt
                                                              // ist, ist sie 4 Pixel breiter und 8 Pixel niedriger als die Standardeinstellung.
    								 
                                                              // Ränder auf der linken und rechten Seite der Tabs
        Tab_Separators  =                     false          ,// [false] = Nicht anzeigen
                                                              // true    = Anzeigen
                                                              // Rahmen CSS wurde extrahiert und angepasst, an Aussehen wie bei browser.proton.enabled
                                                              // auf false, was man vor Firefox 90 noch einstellen konnte.
    									
                                                              // Voraussetzung: „TabBar_Position“ auf „0“ setzen.
        TitleBar_Button_Autohide =            false          ,// [false] = Aktiviert
                                                              // true    = Deaktiviert
    	    
                                                              // Äußeren Rahmen der Titelleistenschaltfläche [-□×] reduzieren und transparent machen.
        TitleBar_Button_DisplayTime =          0.6           ,// Dauer der Anzeige in Sekunden, nach der Rückkehr zur Originalgröße und dem Aufheben
                                                              // der Transparenz per Mouseover angeben.
    
                                                              // Tab-Leiste von Anfang an auf die angegebene Höhe einstellen.
                                                              // Voraussetzung: „MultiRowTab_OnOff_and_TabBar_Rows“ auf „2“ oder höher setzen.
        Set_the_TabBar_to_the_Specified_Height =  false      ,// [false] = Die Tab-Leiste wird höher, wenn der nächsten Zeile weitere Tabs hinzugefügt werden.
                                                              //  true   = Verwendung: Die Tab-Leiste wird von Anfang an auf die angegebene Höhe eingestellt 
    
                                                              // „.tabDropIndicator“, der beim Ziehen und Ablegen eines Tabs angezeigt wird, ersetzen.
                                                              // Voraussetzung: „MultiRowTab_OnOff_and_TabBar_Rows“ auf einen anderen Wert als „0“ setzen.
        Tab_Drop_Indicator =                  false          ,// [false] = Stecknadel Symbol 📍
                                                              // true    = Rote Linie (2px × 29px) als Symbol
    
                                                              // Position der angepinnten Tabs
                                                              // Voraussetzung: „MultiRowTab_OnOff_and_TabBar_Rows“ auf einen Wert ungleich „0“ setzen.
        Separate_Tabs_and_PinnedTabs =        false          ,// [false] = Standard
                                                              // true    = Angeheftete Tabs von der Tab-Leiste lösen und in die darüber liegende 
                                                              // Zeile verschieben. Breite der angehefteten Tabs für die Position der 
                                                              // angehefteten Tabs „true“ anpassen.
    
        PinnedTab_Width =                     false          ,// [false] = Kein Standard
                                                              //  true   = Breite angehefteter Tabs anpassen, z. B. „Tab-Breite“.
    
        PinnedTab_Min_Width =                    76          ,// Standard Mindestbreite =  76 Pixel
        PinnedTab_Max_Width =                   225          ,// Standard Maximalbreite = 225 Pixel
                                                              // Bei gleichen Werten ist die Breite fixiert.
    
                                                              // Angeheftete Tab, Schließen Schaltfläche
                                                              // Voraussetzung: „Separate_Tabs_and_PinnedTabs“ auf „true“ setzen.
        PinnedTab_Close_Button =                  0          ,// [0] = Standard
                                                              //  1  = auf allen Tabs sichtbar
                                                              //  2  = auf Tab bei Mouseover anzeigen
                                                              //  3  = Aktiver Tab immer sichtbar, inaktiver Tab bei Mouseover sichtbar 
                                                              // *Standard für vertikalen Tab-Modus.
    
                                                              // Tab-Leisten-Ziehbereich
        Left_Drag_Area =                          0          ,// Linker Ziehbereich Breite: Standard 40 Pixel
        Right_Drag_Area =                         0          ,// Rechter Ziehbereich Breite: Standard 40 Pixel
        Maximize_Left_Drag_Area =             false          ,// true = Linken Ziehbereich bei maximiertem Fenster anzeigen. Standard ausgeblendet.
        Fullscreen_Drag_Area =                false          ,// true = Linken und rechten Ziehbereich bei Vollbild anzeigen. Standard ausgeblendet.
                                                              // Wenn die Titelleiste angezeigt wird, funktioniert sie nicht als Drag-Bereich, selbst
                                                              // wenn „.titlebar-spacer“ angezeigt wird. Daher habe ich dafür gesorgt, dass sie nichts bewirkt.
        // -- Config Ende --
    
        css = `
    
        #TabsToolbar:not([collapsed="true"]) {
    
          :root[uidensity="compact"] & {
            --tab-min-height: ${UI_Density_Compact}px;
          }
          :root:not([uidensity]) & {
            --tab-min-height: ${UI_Density_Normal}px;
          }
          :root[uidensity="touch"] & {
            --tab-min-height: ${UI_Density_Touch}px;
          }
    
          #tabbrowser-tabs {
            min-height: calc(var(--tab-min-height) + ${Proton_Margins ? 8 : 0}px);
    
            ${MultiRowTab_OnOff_and_TabBar_Rows != 0 ? `
              &[overflow] {
                padding-inline: 0 !important;
                & > #tabbrowser-arrowscrollbox {
                  & > .tabbrowser-tab[pinned] {
                    display: flex;
                    margin-inline-start: 0 !important;
                    position: static !important;
                  }
                  &::part(scrollbox) {
                    padding-inline: 0;
                  }
                }
                & + #new-tab-button {
                  display: none;
                }
              }
    
              ${Tab_Drop_Indicator ? `
                & > .tab-drop-indicator {
                  background: url(
                    data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAdCAIAAAAPVCo9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAASSURBVBhXY3growJEQ5+SUQEAOb1EM8kwskcAAAAASUVORK5CYII=
                  ) no-repeat center;
                }
              ` : ``}
    
              #tabbrowser-arrowscrollbox {
                &::part(scrollbox) {
                  & > slot {
                    flex-wrap: wrap;
                  }
    
                  ${MultiRowTab_OnOff_and_TabBar_Rows != -1 ? `
                    ${MultiRowTab_OnOff_and_TabBar_Rows == 1 ? `
                      ${TabBar_Rows_on_MouseOver == 0 || TabBar_Rows_on_MouseOver == 1 ? `
                        max-height: calc((var(--tab-min-height) + ${Proton_Margins ? 8 : 0}px) * 2);
                      ` : `
                        max-height: calc((var(--tab-min-height) + ${Proton_Margins ? 8 : 0}px) * ${TabBar_Rows_on_MouseOver});
                      `}
                      &:not(:hover) {
                        max-height: calc(var(--tab-min-height) + ${Proton_Margins ? 8 : 0}px) !important;
                        ${Proton_Margins ? `scrollbar-width: none;` : ``}
                        transition: all 0s ease-in-out ${TabBar_DisplayTime_on_MouseOver}s;
                      }
                    ` : `
                      ${Set_the_TabBar_to_the_Specified_Height ? `
                        min-height: calc((var(--tab-min-height) + ${Proton_Margins ? 8 : 0}px) * ${MultiRowTab_OnOff_and_TabBar_Rows});
                        & > slot {
                          max-height: calc(var(--tab-min-height) + ${Proton_Margins ? 8 : 0}px);
                        }
                      ` : `
                        max-height: calc((var(--tab-min-height) + ${Proton_Margins ? 8 : 0}px) * ${MultiRowTab_OnOff_and_TabBar_Rows});
                      `}
                    `}
    
                    overflow: hidden auto;
                    & scrollbar {
                      -moz-window-dragging: no-drag;
                    }
                  ` : ``}
    
                }
                &::part(overflow-start-indicator),
                &::part(overflow-end-indicator),
                &::part(scrollbutton-up),
                &::part(scrollbutton-down) {
                  display: none;
                }
    
                ${Separate_Tabs_and_PinnedTabs ? `
                  &:has(> .tabbrowser-tab[fadein][pinned]) {
                    &::part(scrollbox) {
                      & > slot::after {
                        display: flow-root list-item;
                        content: "";
                        flex-basis: -moz-available;
                        height: 0;
                        overflow: hidden;
                      }
                    }
                  }
                  .tabbrowser-tab[fadein] {
                    &:not([pinned]) {
                      #tabbrowser-tabs[haspinnedtabs] & {
                        &, & + :not(#tabs-newtab-button) {
                          order: 1;
                        }
                      }
                    }
                    &[pinned] {
                      .tab-background:after {
                        content: "📌";
                        font-size: 11px;
                        right: -2px;
                        position: absolute;
                        top: -2px;
                      }
    
                      ${PinnedTab_Width ? `
                        flex: 100 100;
                        max-width: ${PinnedTab_Max_Width}px;
                        min-width: ${PinnedTab_Min_Width}px;
                        .tab-throbber, .tab-icon-pending, .tab-icon-image, .tab-sharing-icon-overlay, .tab-icon-overlay {
                          margin-inline-end: 5.5px !important;
                        }
    
                        ${PinnedTab_Close_Button == 1 ? `
                          .tab-close-button {
                            display: flex;
                          }
                        ` : PinnedTab_Close_Button == 2 ? `
                          .tab-close-button {
                            display: none;
                          }
                          &:hover .tab-close-button {
                            display: flex;
                          }
                        ` : PinnedTab_Close_Button == 3 ? `
                          &:not([selected]):hover,
                          &[selected] {
                            .tab-close-button {
                              display: flex;
                            }
                          }
                        ` : ``}
    
                      ` : ``}
    
                    }
                  }
                ` : ``}
    
                #tabbrowser-tabs[haspinnedtabs]:not([positionpinnedtabs]):not([orient="vertical"]) > & {
                  &  > .tabbrowser-tab:nth-child(1 of :not([pinned], [hidden])) {
                    margin-inline-start: 0 !important;
                  }
                }
    
              }
            ` : ``}
          }
    
          .tabbrowser-tab[fadein]:not([pinned]) {
            max-width: ${Tab_Max_Width}px;
            min-width: ${Tab_Min_Width}px;
    
            ${Tab_Close_Button == 1 ? `
              .tab-close-button {
                display: none;
              }
            ` : Tab_Close_Button == 2 ? `
              .tab-close-button {
                display: flex;
              }
            ` : Tab_Close_Button == 3 ? `
              .tab-close-button {
                display: none;
              }
              &:hover .tab-close-button {
                display: flex;
              }
            ` : Tab_Close_Button == 4 ? `
              &:not([selected]):hover {
                .tab-close-button {
                  display: flex;
                }
              }
            ` : ``}
    
          }
    
          ${Tab_Separators ? `
            .titlebar-spacer[type="pre-tabs"] {
              border-inline-end: 1px solid color-mix(in srgb, currentColor 20%, transparent);
            }
            .tabbrowser-tab {
              &::after,
              &::before {
                border-left: 1px solid color-mix(in srgb, currentColor 50%, transparent);
                height: calc(var(--tab-min-height) - 15%);
                margin-block: auto;
              }
              &:hover::after,
              &[multiselected]::after,
              #tabbrowser-tabs:not([movingtab]) &:has(+ .tabbrowser-tab:hover)::after,
              #tabbrowser-tabs:not([movingtab]) &:has(+ [multiselected])::after {
                height: 100%;
              }
              &::after,
              #tabbrowser-tabs[movingtab] &[visuallyselected]::before {
                display: flex;
                content: "";
              }
            }
          ` : ``}
    
          ${Proton_Margins ? `` : `
            .tabbrowser-tab,
            .toolbarbutton-1 {
              padding: 0;
            }
            .tabbrowser-tab,
            #tabs-newtab-button {
              height: var(--tab-min-height);
            }
            .tabbrowser-tab {
              .tab-background {
                box-shadow: none;
                margin-block: 0;
              }
              .tab-label-container {
                height: var(--tab-min-height);
                max-height: 24px;
              }
              .tab-close-button {
                height: 20px !important;
                padding-block: 3px !important;
              }
              &[usercontextid] > .tab-stack > .tab-background > .tab-context-line {
                margin-block-start: 1px !important;
              }
            }
          `}
    
        ${TabBar_Position == 0 ? `
          .titlebar-buttonbox-container {
            height: calc(var(--tab-min-height) + ${Proton_Margins ? 8 : 0}px);
          }
    
          ${TitleBar_Button_Autohide ? `
            & > .titlebar-buttonbox-container {
              background-color: color-mix(in srgb, currentColor 20%, transparent);
              position: fixed;
              right: 0;
              &:not(:hover) {
                height: 6px;
                .titlebar-button {
                  padding: 0;
                }
                &,& .titlebar-button {
                  opacity: 0;
                  transition: all 0s ease-in-out ${TitleBar_Button_DisplayTime}s;
                }
              }
            }
          ` : ``}
    
        }` : `
    
          ${TabBar_Position == 1 || TabBar_Position == 2 ? `
            & > .titlebar-buttonbox-container {
                display: none;
            }}
            #nav-bar {
              &:not(.browser-titlebar) {
                :root[customtitlebar] #toolbar-menubar[autohide="true"] ~ &,
                :root[inFullscreen] #toolbar-menubar ~ & {
                  & > .titlebar-buttonbox-container {
                    display: flex;
                  }
                }
              }
              .titlebar-button {
                padding-block: 0;
              }
            }
          ` : ``}
    
          body:has(> #navigator-toolbox:not([tabs-hidden])) {
            ${TabBar_Position == 1 ? `
              script, toolbar:not(#TabsToolbar ${Bookmark_Toolbar_Position ? `` : `, #PersonalToolbar`}) {
                order: -1;
              }
            ` : TabBar_Position == 2 ? `
              & > #fullscr-toggler[hidden] + tabbox,
              :root[inFullscreen] & > tabbox:hover {
                border-top: 0.01px solid var(--chrome-content-separator-color);
              }
              & > tabbox > #navigator-toolbox {
                border-block: none !important;
              }
              :root[inFullscreen] & {
                & > #navigator-toolbox {
                  transition: none;
                  &:has(~ tabbox:hover) {
                    margin-top: 0 !important;
                  }
                  &:hover ~ tabbox > #navigator-toolbox {
                    display: flex;
                  }
                }
                & > tabbox:not(:hover) {
                  border-top: 0.01px solid transparent;
                  & > #navigator-toolbox {
                    display: none;
                  }
                }
              }
            ` : ``}
          }
    
        `}
    
        toolbar[id$="bar"].browser-titlebar {
          .titlebar-spacer {
            &[type="pre-tabs"] {
              width: ${Left_Drag_Area}px;
            }
            &[type="post-tabs"] {
              width: ${Right_Drag_Area}px;
            }
            ${Maximize_Left_Drag_Area ? `
              :root[customtitlebar]:not([sizemode="normal"], [inFullscreen]) &[type="pre-tabs"] {
                display: flex;
              }
            ` : ``}
            ${Fullscreen_Drag_Area ? `
              :root[customtitlebar][inFullscreen] & {
                display: flex;
              }
            ` : ``}
          }
          #navigator-toolbox[tabs-hidden] & {
            #new-tab-button {
              display: none;
            }
          }
        }
    
        `,
        sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService),
        uri = Services.io.newURI("data:text/css;charset=UTF=8," + encodeURIComponent(css));
        ["0", "2", "dragend", "SSTabRestored", "TabAttrModified"].find(eventType => {
          if(!sss.sheetRegistered(uri, eventType)) sss.loadAndRegisterSheet(uri, eventType);
          if (MultiRowTab_OnOff_and_TabBar_Rows > 0) {
            gBrowser.tabContainer.addEventListener(eventType, (e) => {
              e.target.scrollIntoView({ behavior: "instant", block: "nearest" })
            })
          }
        })
    
        if (TabBar_Position == 2) {
          document.body.appendChild(
            document.createXULElement("tabbox")
          ).appendChild(
            document.importNode(document.getElementById("navigator-toolbox"))
          ).appendChild(
            document.adoptNode(document.getElementById("TabsToolbar"))
          )
        }
    
        gBrowser.tabContainer._getDropIndex = function(event) {
            let tabToDropAt = getTabFromEventTarget(event, false);
            const tabPos = gBrowser.tabContainer.getIndexOfItem(tabToDropAt);
    
            if (window.getComputedStyle(this).direction == "ltr") {
                let rect = tabToDropAt.getBoundingClientRect();
                if (event.clientX < rect.x + rect.width / 2)
                    return tabPos;
                else 
                    return tabPos + 1;
                
            } else {
                let rect = tabToDropAt.getBoundingClientRect();
                if (event.clientX > rect.x + rect.width / 2)
                    return tabPos;
                else
                    return tabPos + 1;
            }
        };
    
        // We set this to check if the listeners were added before
        let listenersActive = false;
    
        // This sets when to apply the fix (by default a new row starts after the 23th open tab, unless you changed the min-size of tabs)
        gBrowser.tabContainer.addEventListener("dragstart", () => {
            // Multiple tab select fix
            gBrowser.visibleTabs.forEach(t => t.style.transform = "");
    
            // Event handling
            if (!listenersActive) {
                gBrowser.tabContainer.getDropEffectForTabDrag = function(){};
                gBrowser.tabContainer._getDropEffectForTabDrag = function(){};
                gBrowser.tabContainer.on_dragover = (dragoverEvent) => performTabDragOver(dragoverEvent);
                gBrowser.tabContainer._onDragOver = (dragoverEvent) => performTabDragOver(dragoverEvent);
                gBrowser.tabContainer.ondrop = (dropEvent) => performTabDropEvent(dropEvent);
                listenersActive = true;
            }
        });
    }
    
    var lastKnownIndex = null;
    var lastGroupStart = null;
    var lastGroupEnd = null;
    
    /**
     * Gets the tab from the event target.
     * @param {*} event The event.
     * @returns The tab if it was part of the target or its parents, otherwise null
     */
    function getTabFromEventTarget(event, { ignoreTabSides = false } = {}) {
        let { target } = event;
        if (target.nodeType != Node.ELEMENT_NODE) {
            target = target.parentElement;
        }
        let tab = target?.closest("tab") || target?.closest("tab-group");
        const selectedTab = gBrowser.selectedTab;
        if (tab && ignoreTabSides) {
            let { width, height } = tab.getBoundingClientRect();
            if (
                event.screenX < tab.screenX + width * 0.25 ||
                event.screenX > tab.screenX + width * 0.75 ||
                ((event.screenY < tab.screenY + height * 0.25 ||
                    event.screenY > tab.screenY + height * 0.75) &&
                    gBrowser.tabContainer.verticalMode)
            ) {
                return selectedTab;
            }
        }
        if (!tab) {
            return selectedTab;
        }
        return tab;
    }
    
    /**
     * Performs the tab drag over event.
     * @param {*} event The drag over event.
     */
    function performTabDragOver(event) {
        event.preventDefault();
        event.stopPropagation();
    
        let ind = gBrowser.tabContainer._tabDropIndicator;
    
        let effects = orig_getDropEffectForTabDrag(event);
        let tab;
        if (effects == "link") {
            tab = getTabFromEventTarget(event, true);
            if (tab) {
                if (!gBrowser.tabContainer._dragTime)
                    gBrowser.tabContainer._dragTime = Date.now();
                if (!tab.hasAttribute("pendingicon") && // annoying fix
                    Date.now() >= gBrowser.tabContainer._dragTime + gBrowser.tabContainer._dragOverDelay)
                    gBrowser.tabContainer.selectedItem = tab;
                ind.hidden = true;
                return;
            }
        }
    
        if (!tab) {
            tab = getTabFromEventTarget(event, false);
        }
        
        let newIndex = gBrowser.tabContainer._getDropIndex(event);
        if (newIndex == null)
            return;
    
        // Update the last known index and group position
        lastKnownIndex = newIndex;
        
        if (tab.nodeName == "tab-group" && !lastGroupStart) {
            lastGroupStart = tab.querySelector("tab:first-of-type")._tPos;
            lastGroupEnd = tab.querySelector("tab:last-of-type")._tPos;
        }
    
        let tabs = document.querySelectorAll("tab");
        let ltr = (window.getComputedStyle(gBrowser.tabContainer).direction == "ltr");
        let rect = gBrowser.tabContainer.arrowScrollbox.getBoundingClientRect();
        let newMarginX, newMarginY;
        if (newIndex == tabs.length) {
            let tabRect = tabs[newIndex - 1].getBoundingClientRect();
            if (ltr)
                newMarginX = tabRect.right - rect.left;
            else
                newMarginX = rect.right - tabRect.left;
            newMarginY = tabRect.top + tabRect.height - rect.top - rect.height; // multirow fix
    
            if (CSS.supports("offset-anchor", "left bottom")) // Compatibility fix for FF72+
                newMarginY += rect.height / 2 - tabRect.height / 2;
            
        } else if (newIndex != null || newIndex != 0) {
            let tabRect = tabs[newIndex].getBoundingClientRect();
            if (ltr)
                newMarginX = tabRect.left - rect.left;
            else
                newMarginX = rect.right - tabRect.right;
            newMarginY = tabRect.top + tabRect.height - rect.top - rect.height; // multirow fix
    
            if (CSS.supports("offset-anchor", "left bottom")) // Compatibility fix for FF72+
                newMarginY += rect.height / 2 - tabRect.height / 2;
        }
    
        newMarginX += ind.clientWidth / 2;
        if (!ltr)
            newMarginX *= -1;
    
        ind.hidden = false;
    
        ind.style.transform = "translate(" + Math.round(newMarginX) + "px," + Math.round(newMarginY) + "px)"; // multirow fix
        ind.style.marginInlineStart = (-ind.clientWidth) + "px";
    }
    
    /**
     * Performs the tab drop event.
     * @param {*} event The drop event.
     */
    function performTabDropEvent(event) {
        let newIndex;
        let dt = event.dataTransfer;
        let dropEffect = dt.dropEffect;
        let draggedTab;
        if (dt.mozTypesAt(0)[0] == TAB_DROP_TYPE) {
            draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
            if (!draggedTab) {
                return;
            }
        }
    
        if (draggedTab && dropEffect != "copy" && draggedTab.container == gBrowser.tabContainer) {
            newIndex = gBrowser.tabContainer._getDropIndex(event);
    
            /* fix for moving multiple selected tabs and tab groups */
            let selectedTabs = gBrowser.selectedTabs;
            if (lastGroupStart) {
                selectedTabs = [draggedTab?.closest("tab-group")];
                if (lastKnownIndex >= lastGroupStart && lastKnownIndex <= lastGroupEnd) {
                    newIndex = lastGroupStart;
                } else if (lastKnownIndex == lastGroupEnd + 1) {
                    newIndex = lastGroupStart + 1;
                }
            }
    
            if (selectedTabs[selectedTabs.length - 1] == null){
                newIndex = lastKnownIndex;
            } else if (newIndex > selectedTabs[selectedTabs.length - 1]._tPos + 1)
                newIndex--;
            else if (newIndex >= selectedTabs[0]._tPos)
                newIndex = -1;
    
            if (newIndex == -1) {
                newIndex = lastKnownIndex;
            }
            
            const tabToMoveAt = gBrowser.tabContainer.getItemAtIndex(newIndex);
            console.log("tabToMoveAt", tabToMoveAt);
            console.log("newIndex", newIndex);
            selectedTabs.forEach(t => gBrowser.moveTabBefore(t, tabToMoveAt));
    
            // Restart global vars
            lastKnownIndex = null;
            lastGroupStart = null;
            lastGroupEnd = null;
        }
    }
    
    // copy of the original and overrided _getDropEffectForTabDrag method
    function orig_getDropEffectForTabDrag(event) {
        let dt = event.dataTransfer;
    
        let isMovingTabs = dt.mozItemCount > 0;
        for (let i = 0; i < dt.mozItemCount; i++) {
            // tabs are always added as the first type
            let types = dt.mozTypesAt(0);
            if (types[0] != TAB_DROP_TYPE) {
                isMovingTabs = false;
                break;
            }
        }
    
        if (isMovingTabs) {
            let sourceNode = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
            if (XULElement.isInstance(sourceNode) &&
                sourceNode.localName == "tab" &&
                sourceNode.ownerGlobal.isChromeWindow &&
                sourceNode.ownerDocument.documentElement.getAttribute("windowtype") ==
                "navigator:browser" &&
                sourceNode.ownerGlobal.gBrowser.tabContainer == sourceNode.container) {
                // Do not allow transfering a private tab to a non-private window
                // and vice versa.
                if (PrivateBrowsingUtils.isWindowPrivate(window) !=
                    PrivateBrowsingUtils.isWindowPrivate(sourceNode.ownerGlobal))
                    return "none";
            
    
                if (window.gMultiProcessBrowser !=
                    sourceNode.ownerGlobal.gMultiProcessBrowser)
                    return "none";
            
    
                if (window.gFissionBrowser != sourceNode.ownerGlobal.gFissionBrowser)
                    return "none";
            
    
                return dt.dropEffect == "copy" ? "copy" : "move";
            }
        }
    
        if (Services.droppedLinkHandler.canDropLink(event, true)) 
            return "link";
    
        return "none";
    }
    Alles anzeigen

    Und hier die "userChrome.css", ohne "blau" und "rot".

    CSS
    /*----------------------------------------*/
    /* Megabar (Url-Bar) die Ecken abgerundet */
    /*----------------------------------------*/
    
    
    /* Adressleiste / Erhöhung wird verhindert */
    #urlbar-background {
      background: #f8f8ff ! important; /* Hintergrund */
      border: 1px solid #5badff !important;
      border-radius: 50px !important; }
      #urlbar[breakout][breakout-extend] {
      top: calc((var(--urlbar-toolbar-height) - var(--urlbar-height)) / 2) !important;
      left: 0 !important;
      width: 100% !important; }
      #urlbar[breakout][breakout-extend] > #urlbar-input-container {
      height: var(--urlbar-height) !important;
      padding-block: 0 !important;
      padding-inline: 0 !important; }
      #urlbar[breakout][breakout-extend][breakout-extend-animate] > #urlbar-background {
      animation-name: none !important; }
      #urlbar[breakout][breakout-extend] > #urlbar-background {
      box-shadow: none !important;
      }
      
      
      /* Suchleiste Ecken abrunden */
      #searchbar {
      background: #f8f8ff ! important; /* Hintergrund */
      border-radius: 50px !important;
      border: 1px solid #5badff !important;
      }
      
      
      /* -------------------------------------*/
      /* Kontext-Menü / Einträge ausgeblendet */
      /* -------------------------------------*/
      #context-viewinfo,
      #textnotes_gaborjuhaszprojects_com-menuitem-_textnotes,
      #_lympha-menuitem-_lympha-ctx-btn {
      display: none !important;
      }
      #context_pinTab,
      #context_moveTabOptions,
      #context_reopenInContainer,
      #context_sendTabToDevice,
      #context-sendlinktodevice,
      #context-inspect-a11y,
      #context-openlink,
      #context-openlinkprivate,
      #context-bookmarklink,
      #context-inspect,
      #context-openlinkinusercontext-menu,
      #context-viewpartialsource-selection,
      #context-sep-sendlinktodevice,
      #inspect-separator,
      #context-sendpagetodevice,
      #context-viewbgimage,
      #context-selectall,
      #context-viewsource,
      #context-sep-sendpagetodevice,
      #context-sep-viewbgimage,
      #contentAreaContextMenu > menuseparator:nth-child(93),
      #context-sendimage,
      #context-setDesktopBackground {
      display: none !important;
      }
      #context_duplicateTab {
      order: -1 !important;
      }
      #context-openlinkintab {
      order: -1 !important;
      }
      #context-copylink {
      order: -1 !important;
      }
      #copyplaintext_eros_man-menuitem-_copyPlainText {
      order: -1 !important;
      }
      
      
      #context-copy {
      order: -1 !important;
      }
      #_5dd73bb9-e728-4d1e-990b-c77d8e03670f_-menuitem-_search_engine_menu {
      order: 20 !important;
      }
      #context-print-selection,
      #textnotes_gaborjuhaszprojects_com-menuitem-_textnotes-selection {
      display: none !important;
      }
      menuitem[label="Ein Schlüsselwort für diese Suche hinzufügen…"] {
      display: none !important;
      }
      
      
      /*-------------------------------------------------------*/
      /* Trennstrich + Hintergrund für TAB geschlossen Button */
      /*-----------------------------------------------------*/
      #_4853d046-c5a3-436b-bc36-220fd935ee1d_-browser-action .toolbarbutton-badge-stack {
      background: #FF8F00 !important;
      border-radius: 35px !important;
      }
      
      
      #_4853d046-c5a3-436b-bc36-220fd935ee1d_-browser-action:hover .toolbarbutton-badge-stack {
      background-color: #FF0039 !important;
      border-radius: 35px !important;
      }
      
      
      #_4853d046-c5a3-436b-bc36-220fd935ee1d_-browser-action {
      margin-left: 12px !important;
      margin-right: 12px !important;
      }
      
      
      /*--------------------------------------------*/
      /* Ordnersymbole für Symbolleiste und Sidebar */
      /*--------------------------------------------*/
      
      
      @-moz-document url-prefix(chrome://browser/content/browser.xhtml),
      url("chrome://browser/content/places/places.xhtml") {
      .bookmark-item[container="true"]{
      list-style-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAd5JREFUeNqMU79rFUEQ/vbuodFEEkzAImBpkUabFP4ldpaJhZXYm/RiZWsv/hkWFglBUyTIgyAIIfgIRjHv3r39MePM7N3LcbxAFvZ2b2bn22/mm3XMjF+HL3YW7q28YSIw8mBKoBihhhgCsoORot9d3/ywg3YowMXwNde/PzGnk2vn6PitrT+/PGeNaecg4+qNY3D43vy16A5wDDd4Aqg/ngmrjl/GoN0U5V1QquHQG3q+TPDVhVwyBffcmQGJmSVfyZk7R3SngI4JKfwDJ2+05zIg8gbiereTZRHhJ5KCMOwDFLjhoBTn2g0ghagfKeIYJDPFyibJVBtTREwq60SpYvh5++PpwatHsxSm9QRLSQpEVSd7/TYJUb49TX7gztpjjEffnoVw66+Ytovs14Yp7HaKmUXeX9rKUoMoLNW3srqI5fWn8JejrVkK0QcrkFLOgS39yoKUQe292WJ1guUHG8K2o8K00oO1BTvXoW4yasclUTgZYJY9aFNfAThX5CZRmczAV52oAPoupHhWRIUUAOoyUIlYVaAa/VbLbyiZUiyFbjQFNwiZQSGl4IDy9sO5Wrty0QLKhdZPxmgGcDo8ejn+c/6eiK9poz15Kw7Dr/vN/z6W7q++091/AQYA5mZ8GYJ9K0AAAAAASUVORK5CYII=") !important;
      }
      }
      
      
      @-moz-document url("chrome://browser/content/places/bookmarksSidebar.xhtml") {
      treechildren::-moz-tree-image(container) {
      list-style-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAd5JREFUeNqMU79rFUEQ/vbuodFEEkzAImBpkUabFP4ldpaJhZXYm/RiZWsv/hkWFglBUyTIgyAIIfgIRjHv3r39MePM7N3LcbxAFvZ2b2bn22/mm3XMjF+HL3YW7q28YSIw8mBKoBihhhgCsoORot9d3/ywg3YowMXwNde/PzGnk2vn6PitrT+/PGeNaecg4+qNY3D43vy16A5wDDd4Aqg/ngmrjl/GoN0U5V1QquHQG3q+TPDVhVwyBffcmQGJmSVfyZk7R3SngI4JKfwDJ2+05zIg8gbiereTZRHhJ5KCMOwDFLjhoBTn2g0ghagfKeIYJDPFyibJVBtTREwq60SpYvh5++PpwatHsxSm9QRLSQpEVSd7/TYJUb49TX7gztpjjEffnoVw66+Ytovs14Yp7HaKmUXeX9rKUoMoLNW3srqI5fWn8JejrVkK0QcrkFLOgS39yoKUQe292WJ1guUHG8K2o8K00oO1BTvXoW4yasclUTgZYJY9aFNfAThX5CZRmczAV52oAPoupHhWRIUUAOoyUIlYVaAa/VbLbyiZUiyFbjQFNwiZQSGl4IDy9sO5Wrty0QLKhdZPxmgGcDo8ejn+c/6eiK9poz15Kw7Dr/vN/z6W7q++091/AQYA5mZ8GYJ9K0AAAAAASUVORK5CYII=") !important;
      }
      }
      
      /**********************************************/
      /* Anpassungen für MultiRowTabs.uc.js (START) */
      /**********************************************/
      
      .tabbrowser-tab[pinned] {
      flex-grow: 0 !important;
      min-width: 120px !important;
      }
         
      .tabbrowser-tab .tab-label {
      text-shadow: 1px 1px 0px #000000 !important;
      }
      
      .tab-background[selected],
      .tabbrowser-tab:hover > .tab-stack > .tab-background:not([selected]),
      .tabbrowser-tab:hover:not([selected]) :is(.tab-label,.tab-icon-stack),
      .tabbrowser-tab:hover > .tab-stack > .tab-background[multiselected]:not([selected]),
      .tab-background:not([selected]),
      .tab-background[multiselected]:not([selected])
      {
      filter: initial !important;
      }
      
      .tab-sharing-icon-overlay, .tab-icon-overlay:not([pinned]), .tab-icon-overlay[soundplaying] {
      transform: scale(1.0) !important;
      }
         
      #TabsToolbar #tabs-newtab-button > image {
      min-height: initial !important;
      max-height: initial !important;
      min-width: initial !important;
      max-width: initial !important;
      }
      
      #TabsToolbar #tabs-newtab-button > image {
      padding: 7px !important;
      }
      
      /*Abstände der Tabs*/
      .tabbrowser-tab {
        margin-bottom: -4px !important;
        margin-top: -3px !important;
        margin-right: -3px !important;
      }
      
      /*Aktiver Tab Hintergrund orange*/
      tab.tabbrowser-tab[selected] stack.tab-stack vbox.tab-background {
        background: rgb(240,152,0) !important;
        box-shadow: none !important;
        border-radius: 30px !important; 
        border: 2px solid white  !important;
      }
      
      /*Aktiver Tab hover Hintergrund rot */  /*
      tab.tabbrowser-tab[selected]:hover stack.tab-stack vbox.tab-background {
        background-color: red !important;
      } */
      
      /*Aktiver Tab hover Schrift weiß*/
      tab.tabbrowser-tab .tab-content[selected]:hover { 
        color:white !important;
      }
      
      /*Inaktiver Tab Hintergrund beige*/
      tab.tabbrowser-tab:not([selected]) stack.tab-stack vbox.tab-background {
        background: rgb(195,157,116) !important;
        box-shadow: none !important;
        border-radius: 30px !important; 
    
    }
      
      /*Inaktiver Tab hover Hintergrund blau */ /*
      tab.tabbrowser-tab:not([selected]):hover stack.tab-stack vbox.tab-background {
        background: blue !important; 
      } */
      
      /*Inaktiver Tab hover Schrift weiß*/
      tab.tabbrowser-tab .tab-content:not([selected]):hover {
        color: white !important;
      }
      
      /*Neuer Tabbutton weiss*/
      #TabsToolbar #tabs-newtab-button {
        fill: white !important;
      }
      
    
      
      /*********************************************/
      /* Anpassungen für MultiRowTabs.uc.js (ENDE) */
      /*********************************************/
    Alles anzeigen

Unterstütze uns!

Jährlich (2026)

69,4 %

69,4% (538,17 von 775 EUR)

Jetzt spenden
  1. Kontakt
  2. Datenschutz
  3. Impressum
Community-Software: WoltLab Suite™
Mastodon