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. FuchsFan

Beiträge von FuchsFan

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

    • FuchsFan
    • 3. September 2026 um 14:22

    Das Script für Addon-Suche funktionierte auch nicht mehr richtig. Das ist jetzt die Abfolge, in 155 bis 157 getestet:

    Das ist jetzt der Ablauf:

    Firefox startet (kein Restart).
    Die installierten Erweiterungen werden im Hintergrund geprüft.
    Es wird nichts automatisch installiert (automatische Updates deaktiviert).
    Gibt es keine Updates, passiert gar nichts.
    Gibt es Updates, wird genau ein about:addons-Tab geöffnet.
    Firefox landet direkt bei „Verfügbare Updates“.
    Rechts werden die tatsächlich verfügbaren Updates angezeigt.
    Über die Installation wird selbst entschieden.

    JavaScript
    // addonUpdateNotifier.uc.js
    // Firefox 154+
    // Version 03.09.2026
    // Sucht beim Firefox-Start nach Updates für installierte
    // Erweiterungen. Es wird NICHT automatisch installiert.
    // Automatisches Update muss deaktiviert sein
    // Bei Updates wird direkt "Verfügbare Updates" geöffnet.
    
    (async function() {
    
        if (location.href !== "chrome://browser/content/browser.xhtml")
            return;
    
    
        const { AddonManager } =
            ChromeUtils.importESModule(
                "resource://gre/modules/AddonManager.sys.mjs"
            );
    
    
        async function checkForUpdates() {
    
            let foundUpdate = false;
    
            let addons =
                await AddonManager.getAddonsByTypes([
                    "extension"
                ]);
    
    
            for (let addon of addons) {
    
                if (
                    !(addon.permissions &
                      AddonManager.PERM_CAN_UPGRADE)
                ) {
                    continue;
                }
    
    
                await new Promise(resolve => {
    
                    addon.findUpdates({
    
                        onUpdateAvailable(
                            aAddon,
                            install
                        ) {
    
                            foundUpdate = true;
    
                        },
    
    
                        onNoUpdateAvailable() {
                        },
    
    
                        onUpdateFinished() {
    
                            resolve();
    
                        }
    
                    },
                    AddonManager.UPDATE_WHEN_USER_REQUESTED);
    
                });
            }
    
    
            /*
             * Keine Updates:
             * nichts machen.
             */
    
            if (!foundUpdate)
                return;
    
    
            /*
             * ========================================================
             * UPDATE GEFUNDEN
             * ========================================================
             */
    
            let win =
                Services.wm.getMostRecentWindow(
                    "navigator:browser"
                );
    
            if (!win)
                return;
    
    
            /*
             * Einen neuen about:addons-Tab öffnen.
             */
    
            let tab =
                win.gBrowser.addTrustedTab(
                    "about:addons"
                );
    
            win.gBrowser.selectedTab =
                tab;
    
            win.focus();
    
    
            /*
             * ========================================================
             * ABOUT:ADDONS WARTEN
             * ========================================================
             */
    
            let browser =
                tab.linkedBrowser;
    
    
            browser.addEventListener(
                "DOMContentLoaded",
                function listener() {
    
                    browser.removeEventListener(
                        "DOMContentLoaded",
                        listener
                    );
    
                    /*
                     * Jetzt NICHT about:addons#updates laden!
                     *
                     * Stattdessen den internen ViewController
                     * von about:addons benutzen.
                     */
    
                    selectUpdatesView(
                        browser
                    );
    
                },
                {
                    once: true
                }
            );
        }
    
    
        /*
         * ============================================================
         * UPDATE-VIEW AUSWÄHLEN
         * ============================================================
         */
    
        function selectUpdatesView(browser) {
    
            let tries = 0;
    
    
            let timer =
                setInterval(() => {
    
                    tries++;
    
    
                    try {
    
                        let win =
                            browser.contentWindow;
    
                        let doc =
                            browser.contentDocument;
    
    
                        if (!win || !doc) {
    
                            if (tries > 200)
                                clearInterval(timer);
    
                            return;
                        }
    
    
                        /*
                         * ------------------------------------------------
                         * Firefox about:addons ViewController
                         * ------------------------------------------------
                         */
    
                        let controller =
                            win.gViewController;
    
    
                        if (!controller) {
    
                            if (tries > 200) {
    
                                clearInterval(timer);
    
                                console.error(
                                    "[AddonUpdateNotifier] " +
                                    "gViewController nicht gefunden."
                                );
                            }
    
                            return;
                        }
    
    
                        /*
                         * ------------------------------------------------
                         * Direkt die Firefox-View aufrufen.
                         * ------------------------------------------------
                         *
                         * Die gewünschte View lautet:
                         *
                         *     addons://updates/available
                         *
                         * Das ist die View-ID der Kategorie
                         * "Verfügbare Updates".
                         */
    
    
                        clearInterval(timer);
    
    
                        /*
                         * Je nach Firefox-Version ist die Methode
                         * loadView() bzw. loadViewInternal() verfügbar.
                         */
    
                        if (
                            typeof controller.loadView ===
                            "function"
                        ) {
    
                            controller.loadView(
                                "addons://updates/available"
                            );
    
                            return;
                        }
    
    
                        if (
                            typeof controller.loadViewInternal ===
                            "function"
                        ) {
    
                            controller.loadViewInternal(
                                "addons://updates/available"
                            );
    
                            return;
                        }
    
    
                        /*
                         * ------------------------------------------------
                         * Fallback:
                         *
                         * Kategorie-Button über seine View-ID anklicken.
                         * ------------------------------------------------
                         */
    
                        let button =
                            doc.querySelector(
                                '[viewid="addons://updates/available"]'
                            );
    
    
                        if (!button) {
    
                            button =
                                doc.querySelector(
                                    '[name="available-updates"]'
                                );
                        }
    
    
                        if (button) {
    
                            button.click();
    
                            return;
                        }
    
    
                        console.error(
                            "[AddonUpdateNotifier] " +
                            "Keine Möglichkeit gefunden, " +
                            "'Verfügbare Updates' zu öffnen."
                        );
    
    
                    } catch (e) {
    
                        console.error(
                            "[AddonUpdateNotifier]",
                            e
                        );
    
    
                        if (tries > 200)
                            clearInterval(timer);
                    }
    
                }, 100);
        }
    
    
        /*
         * ============================================================
         * START
         * ============================================================
         */
    
        setTimeout(
            checkForUpdates,
            2000
        );
    
    })();
    Alles anzeigen
  • Skripte funktionieren nicht mehr seit Update auf FF 155

    • FuchsFan
    • 2. September 2026 um 15:27
    Zitat von baramax

    Diese ist jetzt trotz der neuen Dateien immer noch weg.

    Dann stelle mal bitte das Script hier rein, dann sehen wir weiter.

  • Skript-Vorstellung: ExtensionOptionsMenu.uc.js

    • FuchsFan
    • 2. September 2026 um 15:24
    Zitat von Mira_Belle

    Habe kein Interesse mehr an der Fortsetzung!

    Bist du jetzt beleidigt, hätte doch gern deine Version getestet.:/

  • Mehrzeilige Tableiste für aktuelle Firefox-Versionen

    • FuchsFan
    • 2. September 2026 um 09:45

    Bob___

    Habe etwas Geduld, ich schaue es mir an, melde mich dann zurück.

    Übrigens, hast du dich damit befasst (ab 155): https://github.com/Endor8/userChr…0155/userChrome

  • Skript-Vorstellung: ExtensionOptionsMenu.uc.js

    • FuchsFan
    • 1. September 2026 um 22:11
    Zitat von Mira_Belle

    Ich werde daran herumbasteln.

    Aber gewiss doch!;)

  • Skript-Vorstellung: ExtensionOptionsMenu.uc.js

    • FuchsFan
    • 1. September 2026 um 15:22
    Zitat von Mira_Belle

    aber weiß immer noch nicht, wozu es gut sein soll.

    Wenn es aus dem Text nicht hervor geht, dann schau auf die Bildchen.;)

  • Skript-Vorstellung: ExtensionOptionsMenu.uc.js

    • FuchsFan
    • 1. September 2026 um 11:06

    Das Script im Original ist hier zu finden. Mit KI übersetzt und weitere Anpassungen vorgenommen. Es erstellt einen Button, bei Klick darauf öffnet sich ein Menü mit alle Erweiterungen, wie sie unter about:addons zu finden sind. Verweilt die Maus über einem Eintrag, dann öffnet sich ein Tooltip-Dialog, dem man Handlungsanweisungen entnehmen kann. Außerdem sind Beispiele für die Pfade des Icons angegeben., und auch im Code selbst gibt es Einstellungsmöglichkeiten für das Aussehen des Tooltip-Dialoges.

                 

    JavaScript
    // ==UserScript==
    // @name          Extension Options Menu.uc.js
    // @description   Fügt eine Menüschaltfläche zur Verwaltung von Erweiterungen hinzu
    // @include       main
    // @charset       UTF-8
    // @version       4.1.1
    // @sandbox       false
    // ==/UserScript==
    
    'use strict';
    
    let EOM = {
    
        /*
         * ============================================================
         * EINSTELLUNGEN
         * ============================================================
         */
    
        // Version hinter dem Add-on-Namen anzeigen
        showVersion: true,
    
        // Auch Add-ons ohne Einstellungsseite anzeigen
        showAll: true,
    
        // Deaktivierte Add-ons anzeigen
        showDisabled: true,
    
        /* Position des Buttons von rechts:
         * 0  = ganz rechts
         * z.B. 1  = eine Position vom rechten Rand entfernt
         * z.B. 5  = fünf Positionen vom rechten Rand entfernt */
    	 
        positionFromRight: 5,
    
        /*  Das ICON für den Button = iconPath:
    	 *   Leerzeichen im Pfad mit %20 ergänzen
         *   1 = C:\FoxIcons2\addons.png
         *   2 = G:\Firefox Test\Firefox22p\Profilordner\chrome\icons\addons.png (portable)
    	 *   2 = C:\Users\xxx\AppData\Roaming\Mozilla\Firefox\Profiles\ArbeitsFox\chrome\Icons\addons.png" (installiert)
         * Zum Wechseln einfach die Zahl ändern */
    
        iconPath: 1,
    
        iconPaths: {
            1: 'file:///C:/FoxIcons2/addons.png',
            2: 'file:///G:/Firefox%20Test/Firefox22p/Profilordner/chrome/icons/addons.png'
    	},
    
        // Gewählten Icon-Pfad zurückgeben
        get buttonIconURL() {
            return this.iconPaths[this.iconPath] || this.iconPaths[1];
        },
    
        // Eigenes Hinweisfenster
        hoverHint: null,
    
        /* Sortierung:
         * enabled  = Position aktiver Add-ons
         * disabled = Position deaktivierter Add-ons
         * 0, 0 = alle alphabetisch
         * 0, 1 = aktive zuerst, deaktivierte danach */
    	 
        sort: {
            enabled: 0,
            disabled: 1
        },
    
    
        /*========== * CSS für Button u. Menü * =========*/
    
        injectStyles: function() {
    
            const css = `
                #eom-button image.toolbarbutton-icon {
                    scale: 1.0 !important;
                    padding: 7px !important;
                }
    
                #eom-button-popup menuitem.menuitem-iconic img.menu-icon {
                    margin-left: -28px !important;
                }
    
                #eom-button-popup menuitem.menuitem-iconic label.menu-text {
                    margin-left: 5px !important;
                }
            `;
    
            try {
                let style = document.createElement('style');
                style.type = 'text/css';
                style.appendChild(document.createTextNode(css));
    
                let head = document.getElementsByTagName('head')[0];
    
                if (head) {
                    head.appendChild(style);
                } else {
                    document.documentElement.appendChild(style);
                }
    
            } catch (e) {
                Cu.reportError(
                    'EOM: CSS konnte nicht injiziert werden: ' + e
                );
            }
        },
    
    
        /*=========== * INITIALISIERUNG * ===========*/
    
        init: function() {
    
            this.injectStyles();
    
            const XUL_NS =
                'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul';
    
            // Button nicht doppelt erstellen
            if (document.getElementById('eom-button')) {
                return;
            }
    
            // Navigationsleiste suchen
            let toolbar =
                document.getElementById('nav-bar-customization-target') ||
                document.getElementById('nav-bar');
    
            // Falls die Toolbar noch nicht vorhanden ist, später erneut versuchen
            if (!toolbar) {
                setTimeout(() => EOM.init(), 1000);
                return;
            }
    
    
            /*=========== * Toolbarbutton erstellen * ===========*/
    
            let toolbarButton = document.createElementNS(
                XUL_NS,
                'toolbarbutton'
            );
    
            toolbarButton.setAttribute('id', 'eom-button');
            toolbarButton.setAttribute(
                'class',
                'toolbarbutton-1 chromeclass-toolbar-additional'
            );
            toolbarButton.setAttribute('type', 'menu');
            toolbarButton.setAttribute(
                'label',
                'Menü für Erweiterungsoptionen'
            );
            toolbarButton.setAttribute(
                'tooltiptext',
                'Menü für Erweiterungsoptionen'
            );
    
            // Icon setzen
            toolbarButton.setAttribute(
                'image',
                this.buttonIconURL
            );
    
            try {
                toolbarButton.style.setProperty(
                    'list-style-image',
                    `url("${this.buttonIconURL}")`,
                    'important'
                );
            } catch (e) {
                Cu.reportError(
                    'EOM: Button-Icon konnte nicht gesetzt werden: ' + e
                );
            }
    
    
            /*============ * Kontextmenü unterdrücken * =============*/
    
            toolbarButton.addEventListener(
                'contextmenu',
                event => event.preventDefault(),
                false
            );
    
    
            /*============ * Button-Klicks * =============*/
    
            toolbarButton.addEventListener(
                'click',
                event => EOM.iconClick(event),
                false
            );
    
    
            /*=========== * Menü-Popup erstellen * ===========*/
    
            let menuPopup = document.createElementNS(
                XUL_NS,
                'menupopup'
            );
    
            menuPopup.setAttribute(
                'id',
                'eom-button-popup'
            );
    
            menuPopup.addEventListener(
                'popupshowing',
                event => EOM.populateMenu(event),
                false
            );
    
            menuPopup.addEventListener(
                'popuphiding',
                () => EOM.hideHoverHint(),
                false
            );
    
            menuPopup.addEventListener(
                'popuphidden',
                () => EOM.hideHoverHint(),
                false
            );
    
            toolbarButton.appendChild(menuPopup);
    
    
            /*======= * Button an gewünschter Position einsetzen * =======*/
    
            let toolbarItems = Array.from(toolbar.children)
                .filter(item => item.id !== 'eom-button');
    
            let insertIndex = Math.max(
                0,
                toolbarItems.length - this.positionFromRight
            );
    
            let referenceItem = toolbarItems[insertIndex];
    
            if (referenceItem) {
                toolbar.insertBefore(
                    toolbarButton,
                    referenceItem
                );
            } else {
                toolbar.appendChild(toolbarButton);
            }
        },
    
    
        /* ============================================================
         * HINWEISFENSTER
         * ============================================================ */
    
        createHoverHint: function() {
    
            if (this.hoverHint) {
                return this.hoverHint;
            }
    
            const XUL_NS =
                'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul';
    
            let panel = document.createElementNS(
                XUL_NS,
                'panel'
            );
    
            panel.setAttribute(
                'id',
                'eom-custom-hover-hint'
            );
    
            panel.setAttribute('noautohide', 'true');
            panel.setAttribute('ignorekeys', 'true');
            panel.setAttribute('level', 'top');
            panel.setAttribute('orient', 'vertical');
            panel.setAttribute('hidden', 'true');
    
            panel.style.cssText = `
                -moz-appearance: none !important;
                appearance: none !important;
                box-sizing: border-box !important;
    
                width: 520px !important;
                min-width: 520px !important;
                max-width: 520px !important;
    
                padding: 10px !important;
    
                background: #202124 !important;
                color: #fff !important;
    
                border: 3px solid #4a90e2 !important;
                border-radius: 8px !important;
    
                box-shadow: 0 5px 18px rgba(0,0,0,.55) !important;
    
                pointer-events: none !important;
                z-index: 2147483647 !important;
            `;
    
            let description = document.createElementNS(
                XUL_NS,
                'description'
            );
    
            description.setAttribute(
                'id',
                'eom-custom-hover-hint-text'
            );
    
            description.style.cssText = `
                display: block !important;
                margin: 0 !important;
                padding: 5px 5px 5px 15px !important;
    
                background: grey !important;
                color: #fff !important;
    
                font-family: Arial, sans-serif !important;
                font-size: 15px !important;
                font-weight: normal !important;
                line-height: 1.5 !important;
    
                white-space: pre-wrap !important;
                overflow-wrap: anywhere !important;
                word-wrap: break-word !important;
            `;
    
            panel.appendChild(description);
    
            let popupSet =
                document.getElementById('mainPopupSet');
    
            if (popupSet) {
                popupSet.appendChild(panel);
            } else {
                document.documentElement.appendChild(panel);
            }
    
            this.hoverHint = panel;
    
            return panel;
        },
    
    
        showHoverHint: function(event, message) {
    
            let panel = this.createHoverHint();
    
            let description =
                document.getElementById(
                    'eom-custom-hover-hint-text'
                );
    
            if (!description) {
                return;
            }
    
            description.textContent = message;
    
            try {
                panel.hidePopup();
            } catch (e) {}
    
            panel.removeAttribute('hidden');
    
            try {
                panel.openPopupAtScreen(
                    event.screenX + 18,
                    event.screenY + 32,
                    false
                );
            } catch (e) {
                Cu.reportError(
                    'EOM: Hinweisfenster konnte nicht geöffnet werden: ' + e
                );
            }
        },
    
    
        hideHoverHint: function() {
    
            if (!this.hoverHint) {
                return;
            }
    
            try {
                this.hoverHint.hidePopup();
            } catch (e) {}
    
            this.hoverHint.setAttribute(
                'hidden',
                'true'
            );
        },
    
    
        /*========= * MENÜ AUFBAUEN * ==========*/
    
        populateMenu: async function(event) {
    
            let popup = event.target;
    
            if (popup !== event.currentTarget) {
                return;
            }
    
            this.hideHoverHint();
    
            // Vorhandene Einträge entfernen
            while (popup.hasChildNodes()) {
                popup.removeChild(popup.firstChild);
            }
    
            let previousState;
    
            let addons =
                await AddonManager.getAddonsByTypes(['extension']);
    
            addons
                .sort((a, b) => {
                    let keyA = this.key(a);
                    let keyB = this.key(b);
    
                    return keyA < keyB ? -1 : 1;
                })
                .forEach(addon => {
    
                    // Integrierte Add-ons und Such-Plugins ausblenden
                    if (
                        addon.isBuiltin ||
                        addon.id.endsWith('@search.mozilla.org')
                    ) {
                        return;
                    }
    
                    // Prüfen, ob das Add-on angezeigt werden soll
                    if (
                        !addon.appDisabled &&
                        (
                            (
                                addon.isActive &&
                                addon.optionsURL
                            ) ||
                            (
                                addon.userDisabled &&
                                this.showDisabled
                            ) ||
                            (
                                !addon.userDisabled &&
                                this.showAll
                            )
                        )
                    ) {
    
                        let state = addon.isActive;
    
                        // Trennlinie zwischen aktiv und deaktiviert
                        if (
                            this.sort.disabled === 1 &&
                            previousState !== undefined &&
                            state !== previousState
                        ) {
                            popup.appendChild(
                                document.createXULElement(
                                    'menuseparator'
                                )
                            );
                        }
    
                        previousState = state;
    
    
                        /* Menüeintrag erstellen */
    
                        let menuItem =
                            document.createXULElement('menuitem');
    
                        let label = addon.name;
    
                        if (this.showVersion) {
                            label += ' [' + addon.version + ']';
                        }
    
                        menuItem.setAttribute(
                            'label',
                            label
                        );
    
                        menuItem.setAttribute(
                            'class',
                            'menuitem-iconic'
                        );
    
    
                        /* Hinweistext */
    
                        menuItem._EOMHint =
                            'ID: ' + addon.id +
                            '\n\n' +
                            'Linksklick = Einstellungsseite des Add-ons öffnen\n' +
                            'Rechtsklick = Add-on aktivieren/deaktivieren\n' +
                            'Mittelklick = Startseite des Add-ons öffnen\n' +
                            'Strg + Linksklick = Ordner des Add-ons öffnen\n' +
                            'Strg + Rechtsklick = Add-on deinstallieren/Rückgängigmachen\n' +
                            '※ Bei Add-ons, die keinen Neustart benötigen, kann die Deinstallation nicht rückgängig gemacht werden\n' +
                            'Alt + Linksklick = ID des Add-ons kopieren';
    
    
                        /* Hinweis beim Überfahren */
    
                        menuItem.addEventListener(
                            'mouseenter',
                            event => {
                                this.showHoverHint(
                                    event,
                                    menuItem._EOMHint
                                );
                            },
                            false
                        );
    
                        menuItem.addEventListener(
                            'mouseleave',
                            () => this.hideHoverHint(),
                            false
                        );
    
    
                        /* Add-on-Symbol */
    
                        let icon =
                            addon.iconURL ||
                            addon.iconURL64 ||
                            '';
    
                        if (icon) {
                            menuItem.setAttribute(
                                'image',
                                icon
                            );
                        }
    
    
                        menuItem._Addon = addon;
    
                        menuItem.addEventListener(
                            'click',
                            event => this.handleClick(event),
                            false
                        );
    
    
                        /* Darstellung */
    
                        if (
                            !addon.optionsURL &&
                            addon.isActive
                        ) {
                            menuItem.setAttribute(
                                'style',
                                'color: Gray'
                            );
                        }
    
                        if (addon.optionsURL) {
                            menuItem.setAttribute(
                                'style',
                                'color: #000'
                            );
                        }
    
    
                        // Status aktualisieren
                        this.updateState(
                            menuItem,
                            addon.userDisabled
                        );
    
                        this.setUninstall(
                            menuItem,
                            this.isPending(addon)
                        );
    
                        popup.appendChild(menuItem);
                    }
                });
        },
    
    
        /* ============================================================
         * BUTTON-KLICKS
         * ============================================================ */
    
        iconClick: function(event) {
    
            if (event.target !== event.currentTarget) {
                return;
            }
    
            // Mittelklick = Firefox neu starten
            if (event.button === 1) {
                this.restart();
            }
    
            // Rechtsklick = Add-on-Manager öffnen
            else if (event.button === 2) {
    
                event.preventDefault();
                event.stopPropagation();
    
                setTimeout(() => {
    
                    let contextMenu =
                        document.getElementById(
                            'toolbar-context-menu'
                        );
    
                    if (contextMenu) {
                        contextMenu.hidePopup();
                    }
    
                }, 0);
    
                BrowserAddonUI.openAddonsMgr(
                    'addons://list/extension'
                );
            }
        },
    
    
        /* ============================================================
         * MENÜEINTRÄGE BEDIENEN
         * ============================================================ */
    
        handleClick: function(event) {
    
            let menuItem = event.target;
    
            if (menuItem !== event.currentTarget) {
                return;
            }
    
            if (!('_Addon' in menuItem)) {
                return;
            }
    
            let addon = menuItem._Addon;
            let pending = this.isPending(addon);
    
            let hasModifier =
                event.ctrlKey ||
                event.shiftKey ||
                event.altKey ||
                event.metaKey;
    
            switch (event.button) {
    
                /* Linksklick */
    
                case 0:
    
                    // Einstellungsseite öffnen
                    if (
                        addon.optionsURL &&
                        !hasModifier
                    ) {
                        this.openAddonOptions(addon);
                    }
    
                    // Strg + Linksklick = Erweiterungsordner öffnen
                    else if (event.ctrlKey) {
                        this.browseDir(addon);
                    }
    
                    // Alt + Linksklick = ID kopieren
                    else if (event.altKey) {
    
                        let clipboard =
                            Cc['@mozilla.org/widget/clipboardhelper;1']
                                .getService(Ci.nsIClipboardHelper);
    
                        clipboard.copyString(addon.id);
                    }
    
                    break;
    
    
                /* Mittelklick = Startseite öffnen */
    
                case 1:
    
                    if (addon.homepageURL) {
                        openURL(addon.homepageURL);
                    }
    
                    break;
    
    
                /* Rechtsklick */
    
                case 2:
    
                    // Rechtsklick = aktivieren/deaktivieren
                    if (!hasModifier) {
    
                        let newState =
                            !addon.userDisabled;
    
                        if (newState) {
                            addon.disable();
                        } else {
                            addon.enable();
                        }
    
                        this.updateState(
                            menuItem,
                            newState
                        );
                    }
    
                    // Strg + Rechtsklick = deinstallieren/rückgängig
                    else if (event.ctrlKey) {
    
                        if (pending) {
                            addon.cancelUninstall();
                        } else {
                            addon.uninstall();
                        }
    
                        this.setUninstall(
                            menuItem,
                            !pending
                        );
                    }
    
                    break;
            }
        },
    
    
        /* ============================================================
         * STATUSVERWALTUNG
         * ============================================================ */
    
        updateState: function(menuItem, disabled) {
    
            if (disabled) {
                menuItem.classList.add('addon-disabled');
            } else {
                menuItem.classList.remove('addon-disabled');
            }
        },
    
    
        setUninstall: function(menuItem, uninstallPending) {
    
            if (uninstallPending) {
                menuItem.classList.add('addon-uninstall');
            } else {
                menuItem.classList.remove('addon-uninstall');
            }
        },
    
    
        isPending: function(addon) {
    
            return addon.pendingOperations &
                AddonManager.PENDING_UNINSTALL;
        },
    
    
        /* ============================================================
         * ADD-ON-EINSTELLUNGEN ÖFFNEN
         * ============================================================ */
    
        openAddonOptions: function(addon) {
    
            let optionsURL = addon.optionsURL || '';
    
            if (!addon.isActive || !optionsURL) {
                return;
            }
    
            // optionsType 3 = eigene Seite in einem Tab
            if (addon.optionsType === 3) {
    
                if ('switchToTabHavingURI' in window) {
                    switchToTabHavingURI(
                        optionsURL,
                        true
                    );
                } else {
                    openTab(
                        'contentTab',
                        {
                            contentPage: optionsURL
                        }
                    );
                }
    
            } else {
    
                // Add-on-Manager direkt bei den Einstellungen öffnen
                BrowserAddonUI.openAddonsMgr(
                    'addons://detail/' +
                    encodeURIComponent(addon.id) +
                    '/preferences'
                );
            }
        },
    
    
        /* ============================================================
         * ADD-ON-ORDNER ÖFFNEN
         * ============================================================ */
    
        browseDir: function(addon) {
    
            try {
    
                let directory =
                    Services.dirsvc.get(
                        'ProfD',
                        Ci.nsIFile
                    );
    
                directory.append('extensions');
    
                directory.append(
                    addon.id +
                    (addon.unpack ? '' : '.xpi')
                );
    
                if (directory.exists()) {
                    directory.reveal();
                } else {
                    Services.prompt.alert(
                        null,
                        'Fehler',
                        'Ordner oder Datei nicht gefunden.'
                    );
                }
    
            } catch (e) {
    
                Cu.reportError(
                    'EOM: browseDir fehlgeschlagen: ' + e
                );
            }
        },
    
    
        /* ============================================================
         * SORTIERUNG
         * ============================================================ */
    
        key: function(addon) {
    
            let sortPosition =
                addon.isActive
                    ? this.sort.enabled
                    : this.sort.disabled;
    
            return (
                sortPosition +
                '\n' +
                addon.name.toLowerCase()
            );
        },
    
    
        /* ============================================================
         * FIREFOX NEU STARTEN
         * ============================================================ */
    
        restart: function() {
    
            let cancelQuit =
                Cc['@mozilla.org/supports-PRBool;1']
                    .createInstance(Ci.nsISupportsPRBool);
    
            Services.obs.notifyObservers(
                cancelQuit,
                'quit-application-requested',
                'restart'
            );
    
            if (cancelQuit.data) {
                return;
            }
    
            // Im abgesicherten Modus neu starten
            if (Services.appinfo.inSafeMode) {
    
                Services.startup.restartInSafeMode(
                    Ci.nsIAppStartup.eAttemptQuit
                );
    
                return;
            }
    
            // Normaler Neustart
            Services.appinfo.invalidateCachesOnRestart();
    
            Services.startup.quit(
                Ci.nsIAppStartup.eAttemptQuit |
                Ci.nsIAppStartup.eRestart
            );
        }
    };
    
    
    /* ================================================================
     * START
     * ================================================================ */
    
    EOM.init();
    Alles anzeigen
  • extra_config_menu.uc.js > ohne security.allow_unsafe_dangerous_privileged_evil_eval auf false

    • FuchsFan
    • 31. August 2026 um 15:31
    Zitat von Mira_Belle

    Das ist auch in ganz anderen Bereichen so
    und so etwas regt mich tierisch auf.
    Wobei, ich versuche gelassener zu werden, aber DAS beeinflusst halt auch meine Zukunft!

    Mira_Belle

    Gelassener werden, ein weiser Entschluss. Ich muss sagen, wenn ich noch an die Zeit zurück denke, als ich hier meine ersten Gehversuche gemacht habe, da konnte ich noch so viel Lesen, aber verstanden davon habe ich nur Bruchteile. Und auch mir wurde geholfen, manchmal habe ich mich nicht mehr getraut nachzufragen, weil mir bewusst war, dass es für die Helfer auch nervig sein muss. Und ist es nicht toll, wenn du und all die anderen mit Lösungen helfen, und der User dann glücklich und zufrieden ist (war bei mir auch so).

  • Benutzerskripte funktionieren seit Version 138 teilweise nicht mehr

    • FuchsFan
    • 29. August 2026 um 13:31
    Zitat von Stoiker

    funktioniert wieder, Danke fürs anpassen

    Prima! Gern geschehen.:)

  • extra_config_menu.uc.js > ohne security.allow_unsafe_dangerous_privileged_evil_eval auf false

    • FuchsFan
    • 27. August 2026 um 16:43
    Zitat von Mira_Belle

    Ist klar was gemeint ist

    Aber ja!:)

  • extra_config_menu.uc.js > ohne security.allow_unsafe_dangerous_privileged_evil_eval auf false

    • FuchsFan
    • 27. August 2026 um 10:52
    Zitat von 2002Andreas

    Es ist also nicht ganz einfach, es für alle Nutzer perfekt zu machen

    Mira_Belle

    Und damit hat Andreas vollkommen recht. Mache ein Basis-Skript fertig, wer dann noch Wünsche hat, das kannst du dann nachliefern (nicht unter Zwang ;)). Für mich ist das Script das "Schweizer Taschenmesser", möchte ich nicht mehr missen.

  • extra_config_menu.uc.js > ohne security.allow_unsafe_dangerous_privileged_evil_eval auf false

    • FuchsFan
    • 27. August 2026 um 10:33
    Zitat von Mira_Belle

    Was haltet ihr davon?

    Wieder eine neue Variante, nicht schlecht. Was aber dringend fehlt mMn ist das:

    Code
    // Falls die JavaScript-Scripte nicht im chrome-Verzeichnis,
      // sondern einem Unterverzeichnis sind, hier das Unterverzeichnis eintragen.
      // Sonst '':
    
      jsSubfolder: 'Scripte',
  • extra_config_menu.uc.js > ohne security.allow_unsafe_dangerous_privileged_evil_eval auf false

    • FuchsFan
    • 26. August 2026 um 21:39
    Zitat von Sören Hentzschel

    wäre ich dankbar, wenn du einen Bruchteil davon verwenden könntest, um bei deinem Codes hier im Forum JavaScript auszuwählen

    Sören Hentzschel

    Das war nie meine Absicht zusätzliche Arbeit zu verursachen. Das ist das erste Mal, dass ich diesen Hinweis erhalten habe, eine Auswahl zu treffen. Ich habe überhaupt nicht gewusst dass es so was gibt. Danke für diese Aufklärung, werde mich bessern.;):)

  • extra_config_menu.uc.js > ohne security.allow_unsafe_dangerous_privileged_evil_eval auf false

    • FuchsFan
    • 26. August 2026 um 20:05

    Die Einstellungen für das folgende Script habe ich von hier übernommen, und weitere Anpassungen vorgenommen (mit KI), wie z.B. den CSSShadow-Ordner mit ON/OFF ausgestattet. Wenn CSS-Ordner gelistet werden, so haben sie ein Submenü mit den enthaltenen Dateien ( dazu mit Zähler). Eine weitere Variante zum testen.

    JavaScript
    // ==UserScript==
    // @name           extras_config_menu.uc.js
    // @compatibility  Firefox 154+
    // @include        main
    // @version        2.0.20260826
    // @edit           CSS-Ordner als dynamische Untermenüs
    // @edit           CSS-Dateizähler sofort anzeigen
    // @edit           CSSShadow eigener Ein/Aus-Schalter
    // @edit           Ordner öffnen mit System-Dateimanager oder alternativem Dateimanager
    // @edit           GM/USL/Scriptish entfernt
    // @edit           Einstellungen für aktuelle Firefox-Versionen angepasst
    // ==/UserScript==
    
    var uProfMenu = {
    
      // ==================== KONFIGURATION ====================
    
      // 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: 'C:\\Program Files (x86)\\Notepad++\\notepad++.exe',
      // TextOpenExe: 'C:\\Program Files\\Notepad++\\notepad++.exe',
    
      TextOpenExe: 'C:\\notepad++\\notepad++.exe',
    
      // Falls gewuenscht, hier einen Dateimanager eintragen.
      // Leer lassen = Dateimanager des Systems.
      // Beispiele:
      // vFileManager: 'E:\\Total Commander\\Totalcmd.exe',
      // vFileManager: 'C:\\Program Files (x86)\\FreeCommander\\FreeCommander.exe',
      // vFileManager: 'C:\\Program Files\\FreeCommander XE\\FreeCommander.exe',
    
      vFileManager: '',
    
      // Eventuelle Parameter für den alternativen Dateimanager.
      // vFilemanagerParam = "";
      // vFilemanagerParam = "/O /T"; // TotalCommander, FreeCommander
      // vFMParam: "/T",
    
      vFMParam: '',
    
      // Falls die JavaScript-Scripte nicht im chrome-Verzeichnis,
      // sondern einem Unterverzeichnis sind, hier das Unterverzeichnis eintragen.
      // Sonst '':
    
      jsSubfolder: 'Scripte',
    
      // 'menu' = Menüleiste, sonst '' = Button
    
      location: '',
    
      // Bei location = 'menu':
      // 0 = Menüleiste, 1 = Extras-Menü
    
      menuLocation: 0,
    
      // Unter Linux sollte/kann versucht werden, die userChromeJS-Skripte
      // zu sortieren. Die Sortierung berücksichtigt Gross-/Kleinschreibung nicht.
    
      sortScripts: 0, // 1 zum Erzwingen der Sortierung
    
      // Einbindung CSS-Ordner:
      // 0 = nein, 1 = ja, Chrome-Unterordner, 2 = ja, anderer Pfad
    
      cssOrdner: 1,
    
      // CSSShadow-Ordner:
      // 0 = ausblenden, 1 = anzeigen
    
      cssShadowOrdner: 0,
    
      // Wenn cssOrdner = 1 oder 2:
      // Chrome-Unterordner oder vollständige Pfade eintragen.
    
      cssLocation1: 'CSS',
      cssLocation2: 'CSSWeb',
      cssLocation3: 'CSSAbout',
      cssLocation4: 'CSSShadow',
    
      // Anzeigenamen für die CSS-Ordner
    
      cssLocation1Name: 'CSS-Ordner',
      cssLocation2Name: 'CSSWeb-Ordner',
      cssLocation3Name: 'CSSAbout-Ordner',
      cssLocation4Name: 'CSSShadow-Ordner',
    
      // Gültige about:-Adressen eintragen.
      // Zum Ausblenden: abouts: []
      // Bei '0' als erstem Element werden die Seiten direkt angezeigt.
    
      abouts: [
        'about:about',
        'about:config',
        'about:preferences',
        'about:addons'
      ],
    
      // Einbindung Konfigurationsdateien:
      // 0 = nein, 1 = ja
    
      configFiles: 1,
    
      // Firefox-Ordner anzeigen:
      // 0 = nein, 1 = ja
    
      firefoxOrdner: 1,
    
      // Normale Firefox-Einstellungen:
      // 0 = nein, 1 = ja
    
      showNormalPrefs: 1,
    
      // Skriptliste in Zwischenablage:
      // 0 = nein, 1 = ja, 2 = getrennte Nummerierung,
      // 3 = gemeinsame Nummerierung
    
      enableScriptsToClip: 3,
    
      // Neustart anzeigen:
      // 0 = nein, 1 = ja
    
      enableRestart: 1,
    
    
      // ==================== INITIALISIERUNG ====================
    
      init: function() {
        var menu;
    
        // --- MENÜ ---
    
        if (this.location.toLowerCase() == 'menu') {
          var zielmenu = this.menuLocation
            ? document.getElementById('menu_ToolsPopup')
            : document.getElementById('main-menubar');
    
          if (!zielmenu) return;
    
          menu = zielmenu.appendChild(
            this.createME('menu', 'Config-Menü', '', '', 'ExtraConfigMenu')
          );
    
          menu.setAttribute('tooltiptext', 'Mittelklick öffnet about:config');
          menu.setAttribute('accesskey', 'M');
    
          menu.addEventListener('click', function(event) {
            if (event.button == 1 && !this.open)
              openTrustedLinkIn('about:config', 'tab');
          });
        }
    
        // --- BUTTON ---
    
        else {
          if (window.__SSi == 'window0') {
            CustomizableUI.createWidget({
              id: 'ExtraConfigMenu-button',
              defaultArea: CustomizableUI.AREA_NAVBAR,
              label: 'Extra Config Menü',
              tooltiptext: 'Extra Config Menü\nRechtsklick öffnet about:config'
            });
          }
    
          menu = document.getElementById('ExtraConfigMenu-button');
          if (!menu) return;
    
          menu.setAttribute('type', 'menu');
    
          menu.addEventListener('click', function(event) {
            if (event.button == 2 && !this.open) {
              openTrustedLinkIn('about:config', 'tab');
              event.preventDefault();
            }
          }, true);
        }
    
    
        // --- CSS FÜR BUTTON ---
    
        var css =
          '#ExtraConfigMenu, #ExtraConfigMenu-button {' +
          'list-style-image: url("file:///C:/FoxIcons/1206.png") !important;' +
          'margin-right: 10px !important;' +
          'margin-bottom: 2px !important;' +
          'margin-top: 2px !important;' +
          '}' +
          '#ExtraConfigMenu-button > dropmarker,' +
          '#ExtraConfigMenu-button > hbox > .toolbarbutton-menu-dropmarker {' +
          'display: none !important;' +
          '}';
    
        var sss =
          Cc['@mozilla.org/content/style-sheet-service;1']
            .getService(Ci.nsIStyleSheetService);
    
        var uri = makeURI(
          'data:text/css;charset=UTF-8,' + encodeURIComponent(css)
        );
    
        if (!sss.sheetRegistered(uri, sss.AGENT_SHEET))
          sss.loadAndRegisterSheet(uri, sss.AGENT_SHEET);
    
    
        // --- HAUPTMENÜ ---
    
        var menupopup = menu.appendChild(
          this.createME(
            'menupopup',
            '',
            '',
            '',
            'ExtraConfigMenu-popup'
          )
        );
    
    
        // --- MEINE SCRIPTE ---
    
        var submenu = menupopup.appendChild(
          this.createME(
            'menu',
            'Meine Scripte',
            '',
            '',
            'submenu-ucjs'
          )
        );
    
        submenu.appendChild(
          this.createME(
            'menupopup',
            '',
            '',
            '',
            'submenu-ucjs-items'
          )
        );
    
        submenu.addEventListener(
          'popupshowing',
          function() {
            uProfMenu.getScripts(0);
          },
          true
        );
    
        this.getScripts(0); // Zähler sofort beim Start setzen
    
    
        // --- NEUES SKRIPT ---
    
        menupopup.appendChild(
          this.createME(
            'menuitem',
            'uc.js-Datei erstellen',
            'uProfMenu.createJSfile()',
            'uProfMenu_createJSfile',
            0
          )
        );
    
    
        // --- SKRIPTLISTE ---
    
        if (this.enableScriptsToClip) {
          menupopup.appendChild(
            this.createME(
              'menuitem',
              'Skriptliste in Zwischenablage',
              'uProfMenu.getScripts(1)',
              'uProfMenu_clipboard',
              0
            )
          );
        }
    
    
        // --- KONFIGURATIONSDATEIEN ---
    
        if (this.configFiles) {
          menupopup.appendChild(
            document.createXULElement('menuseparator')
          );
    
          [
            'userChrome.js',
            'userChrome.css',
            'userContent.css',
            'prefs.js',
            'user.js',
            'Bild Url.css',
            'config Einträge.css'
          ].forEach(function(file) {
            var mode =
              (file == 'prefs.js' || file == 'user.js') ? 1 : 3;
    
            menupopup.appendChild(
              uProfMenu.createME(
                'menuitem',
                file,
                "uProfMenu.edit(" + mode + ",'" + file + "')",
                'uProfMenu_edit',
                0
              )
            );
          });
        }
    
    
        // --- CSS-ORDNER ---
    
        if (this.cssOrdner) {
          menupopup.appendChild(
            document.createXULElement('menuseparator')
          );
    
          [
            this.cssLocation1,
            this.cssLocation2,
            this.cssLocation3,
            this.cssLocation4
          ].forEach(function(loc, i) {
            if (
              loc &&
              loc.length > 0 &&
              (i != 3 || uProfMenu.cssShadowOrdner)
            ) {
              uProfMenu.addCSSSubmenu(
                menupopup,
                uProfMenu['cssLocation' + (i + 1) + 'Name'],
                loc
              );
            }
          });
        }
    
    
        // --- FIREFOX-ORDNER ---
    
        if (this.firefoxOrdner) {
          menupopup.appendChild(
            document.createXULElement('menuseparator')
          );
    
          [
            {
              label: 'Ordner Scripte',
              path: function() {
                return uProfMenu.getPrefDirectoryPath('UChrm') +
                  uProfMenu.getDirSep() +
                  uProfMenu.jsSubfolder;
              }
            },
            {
              label: 'Chromeordner',
              path: function() {
                return uProfMenu.getPrefDirectoryPath('UChrm');
              }
            },
            {
              label: 'Profilordner',
              path: function() {
                return uProfMenu.getPrefDirectoryPath('ProfD');
              }
            },
            {
              label: 'Installationsordner',
              path: function() {
                return uProfMenu.getPrefDirectoryPath('CurProcD');
              }
            },
            {
              label: 'Addonordner',
              path: function() {
                return uProfMenu.getPrefDirectoryPath('ProfD') +
                  uProfMenu.getDirSep() +
                  'extensions';
              }
            },
            {
              label: 'Startup-Cacheordner',
              path: function() {
                return uProfMenu.getPrefDirectoryPath('ProfLD') +
                  uProfMenu.getDirSep() +
                  'startupCache';
              }
            }
          ].forEach(function(folder) {
            uProfMenu.addFolderMenu(
              menupopup,
              folder.label,
              folder.path
            );
          });
        }
    
    
        // --- ABOUT / EINSTELLUNGEN ---
    
        if (this.abouts.length > 0 || this.showNormalPrefs) {
          menupopup.appendChild(
            document.createXULElement('menuseparator')
          );
        }
    
    
        // --- ABOUT ---
    
        if (this.abouts.length > 0) {
          var aboutSubmenu = menupopup.appendChild(
            this.createME(
              'menu',
              'about:',
              '',
              '',
              'submenu-about'
            )
          );
    
          aboutSubmenu.appendChild(
            this.createME(
              'menupopup',
              '',
              '',
              '',
              'submenu-about-items'
            )
          );
    
          this.fillMenu(
            'submenu-about',
            'submenu-about-items',
            'about:',
            this.abouts,
            'uProfMenu_about',
            1
          );
        }
    
    
        // --- EINSTELLUNGEN ---
    
        if (this.showNormalPrefs) {
          menupopup.appendChild(
            this.createME(
              'menuitem',
              'Einstellungen',
              'uProfMenu.openSettings()',
              'uProfMenu_prefs',
              0
            )
          );
        }
    
    
        // --- NEUSTART ---
    
        if (this.enableRestart) {
          menupopup.appendChild(
            document.createXULElement('menuseparator')
          );
    
          menupopup.appendChild(
            this.createME(
              'menuitem',
              'Neustart',
              'uProfMenu.restart()',
              '',
              0
            )
          );
        }
      },
    
    
      // ==================== HILFSFUNKTIONEN ====================
    
      addFolderMenu: function(parent, label, pathFunction) {
        var item = this.createME(
          'menuitem',
          label,
          '',
          'uProfMenu_folder',
          0
        );
    
        item.addEventListener(
          'command',
          function() {
            try {
              uProfMenu.dirOpen(pathFunction());
            } catch (e) {
              console.error(
                'extras_config_menu.uc.js: Ordner konnte nicht geöffnet werden:',
                e
              );
            }
          },
          true
        );
    
        parent.appendChild(item);
      },
    
    
      addCSSSubmenu: function(parent, label, folder) {
        var count = this.getCSSFileCount(folder);
        var submenu = this.createME(
          'menu',
          label + ' (' + count + ')',
          '',
          '',
          ''
        );
    
        var popup = this.createME(
          'menupopup',
          '',
          '',
          '',
          ''
        );
    
        submenu.appendChild(popup);
        parent.appendChild(submenu);
    
        popup.addEventListener(
          'popupshowing',
          function() {
            uProfMenu.fillCSSMenu(popup, folder);
            uProfMenu.updateCSSCount(submenu, label, folder);
          },
          true
        );
      },
    
    
      getCSSFileCount: function(folder) {
        var folderPath = (this.cssOrdner == 1)
          ? this.getPrefDirectoryPath('UChrm') +
            this.getDirSep() +
            folder
          : folder;
    
        var cssFolder =
          Cc['@mozilla.org/file/local;1']
            .createInstance(Ci.nsIFile);
    
        try {
          cssFolder.initWithPath(folderPath);
        } catch (e) {
          return 0;
        }
    
        if (!cssFolder.exists() || !cssFolder.isDirectory())
          return 0;
    
        var count = 0;
    
        try {
          var entries =
            cssFolder.directoryEntries
              .QueryInterface(Ci.nsISimpleEnumerator);
    
          while (entries.hasMoreElements()) {
            var file =
              entries.getNext().QueryInterface(Ci.nsIFile);
    
            if (file.isFile() && /\.css$/i.test(file.leafName))
              count++;
          }
        } catch (e) {
          return 0;
        }
    
        return count;
      },
    
    
      updateCSSCount: function(submenu, label, folder) {
        var count = this.getCSSFileCount(folder);
        submenu.setAttribute(
          'label',
          label + ' (' + count + ')'
        );
      },
    
    
      fillCSSMenu: function(popup, folder) {
        while (popup.hasChildNodes())
          popup.removeChild(popup.firstChild);
    
        var folderPath = (this.cssOrdner == 1)
          ? this.getPrefDirectoryPath('UChrm') +
            this.getDirSep() +
            folder
          : folder;
    
        var cssFolder =
          Cc['@mozilla.org/file/local;1']
            .createInstance(Ci.nsIFile);
    
        try {
          cssFolder.initWithPath(folderPath);
        } catch (e) {
          this.addDisabledMenuItem(
            popup,
            '(ungültiger Pfad)'
          );
          return;
        }
    
        if (!cssFolder.exists() || !cssFolder.isDirectory()) {
          this.addDisabledMenuItem(
            popup,
            '(Ordner nicht gefunden)'
          );
          return;
        }
    
        var cssFiles = [];
        var entries =
          cssFolder.directoryEntries
            .QueryInterface(Ci.nsISimpleEnumerator);
    
        while (entries.hasMoreElements()) {
          var file =
            entries.getNext().QueryInterface(Ci.nsIFile);
    
          if (file.isFile() && /\.css$/i.test(file.leafName))
            cssFiles.push(file.leafName);
        }
    
        cssFiles.sort(this.stringComparison);
    
        if (cssFiles.length == 0) {
          this.addDisabledMenuItem(
            popup,
            '(keine CSS-Dateien)'
          );
          return;
        }
    
        for (var i = 0; i < cssFiles.length; i++) {
          var filename = cssFiles[i];
          var item = this.createME(
            'menuitem',
            filename,
            '',
            'uProfMenu_css',
            0
          );
    
          var fullPath =
            folderPath +
            this.getDirSep() +
            filename;
    
          item.setAttribute(
            'data-css-path',
            fullPath
          );
    
          item.setAttribute(
            'tooltiptext',
            'Öffnen: ' + fullPath
          );
    
          item.addEventListener(
            'command',
            function() {
              var path =
                this.getAttribute('data-css-path');
    
              uProfMenu.launch(
                uProfMenu.TextOpenExe,
                path
              );
            },
            true
          );
    
          popup.appendChild(item);
        }
      },
    
    
      addDisabledMenuItem: function(popup, label) {
        var item = this.createME(
          'menuitem',
          label,
          '',
          '',
          0
        );
    
        item.setAttribute('disabled', 'true');
        popup.appendChild(item);
      },
    
    
      getDirSep: function() {
        return Services.appinfo.OS == 'WINNT'
          ? '\\'
          : '/';
      },
    
    
      edit: function(OpenMode, Filename) {
        var Path = '';
        var dSep = this.getDirSep();
    
        switch (OpenMode) {
          case 0:
            Path =
              this.getPrefDirectoryPath('UChrm') +
              dSep +
              (this.jsSubfolder.length != 0
                ? this.jsSubfolder + dSep
                : '') +
              Filename;
            break;
    
          case 1:
            Path =
              this.getPrefDirectoryPath('ProfD') +
              dSep +
              Filename;
            break;
    
          case 2:
            Path = Filename;
            break;
    
          case 3:
            Path =
              this.getPrefDirectoryPath('UChrm') +
              dSep +
              Filename;
            break;
        }
    
        this.launch(this.TextOpenExe, Path);
      },
    
    
      dirOpen: function(Path) {
        if (!Path) return;
    
        if (this.vFileManager && this.vFileManager.length > 0) {
          var manager =
            Cc['@mozilla.org/file/local;1']
              .createInstance(Ci.nsIFile);
    
          try {
            manager.initWithPath(this.vFileManager);
          } catch (e) {
            console.error(
              'extras_config_menu.uc.js: Ungültiger Dateimanager:',
              this.vFileManager
            );
            return;
          }
    
          if (!manager.exists()) {
            console.error(
              'extras_config_menu.uc.js: Dateimanager nicht gefunden:',
              this.vFileManager
            );
            return;
          }
    
          var process =
            Cc['@mozilla.org/process/util;1']
              .createInstance(Ci.nsIProcess);
    
          process.init(manager);
    
          var args =
            (this.vFMParam && this.vFMParam.trim())
              ? this.vFMParam.trim().split(/\s+/)
              : [];
    
          args.push(Path);
          process.run(false, args, args.length);
          return;
        }
    
        var dir =
          Cc['@mozilla.org/file/local;1']
            .createInstance(Ci.nsIFile);
    
        try {
          dir.initWithPath(Path);
        } catch (e) {
          console.error(
            'extras_config_menu.uc.js: Ungültiger Ordner:',
            Path
          );
          return;
        }
    
        if (!dir.exists()) {
          console.error(
            'extras_config_menu.uc.js: Ordner existiert nicht:',
            Path
          );
          return;
        }
    
        dir.launch();
      },
    
    
      getPrefDirectoryPath: function(str) {
        var file = Services.dirsvc.get(str, Ci.nsIFile);
    
        if (str == 'CurProcD')
          file = file.parent;
    
        return file.path;
      },
    
    
      launch: function(RanPath, OpenPath) {
        var file =
          Cc['@mozilla.org/file/local;1']
            .createInstance(Ci.nsIFile);
    
        var proc =
          Cc['@mozilla.org/process/util;1']
            .createInstance(Ci.nsIProcess);
    
        var args = [OpenPath];
    
        try {
          file.initWithPath(RanPath);
        } catch (e) {
          file = null;
        }
    
        if (!file || !file.exists()) {
          try {
            RanPath =
              Services.prefs.getCharPref(
                'view_source.editor.path'
              );
    
            file =
              Cc['@mozilla.org/file/local;1']
                .createInstance(Ci.nsIFile);
    
            file.initWithPath(RanPath);
          } catch (e) {
            console.error(
              'extras_config_menu.uc.js: Kein Editor gefunden.'
            );
            return;
          }
        }
    
        if (!file.exists()) return;
    
        proc.init(file);
        proc.run(false, args, args.length);
      },
    
    
      openSettings: function() {
        try {
          openTrustedLinkIn(
            'about:preferences',
            'tab'
          );
          return;
        } catch (e) {
          console.error(
            'about:preferences konnte nicht geöffnet werden:',
            e
          );
        }
    
        try {
          if (typeof openPreferences == 'function') {
            openPreferences();
            return;
          }
        } catch (e) {
          console.error(
            'openPreferences() fehlgeschlagen:',
            e
          );
        }
      },
    
    
      getScripts: function(iType) {
        var ucJsScripts = [];
        var extjs = /\.uc\.js$/i;
    
        var aFolder =
          Cc['@mozilla.org/file/local;1']
            .createInstance(Ci.nsIFile);
    
        var chromePath =
          Services.dirsvc.get(
            'UChrm',
            Ci.nsIFile
          ).path;
    
        if (this.jsSubfolder.length != 0)
          chromePath +=
            this.getDirSep() +
            this.jsSubfolder;
    
        try {
          aFolder.initWithPath(chromePath);
        } catch (e) {
          return;
        }
    
        if (!aFolder.exists() || !aFolder.isDirectory())
          return;
    
        var files =
          aFolder.directoryEntries
            .QueryInterface(Ci.nsISimpleEnumerator);
    
        while (files.hasMoreElements()) {
          var file =
            files.getNext().QueryInterface(Ci.nsIFile);
    
          if (extjs.test(file.leafName))
            ucJsScripts.push(file.leafName);
        }
    
        if (this.sortScripts)
          ucJsScripts.sort(this.stringComparison);
    
        if (iType == 0) {
          this.fillMenu(
            'submenu-ucjs',
            'submenu-ucjs-items',
            'Meine Scripte',
            ucJsScripts,
            'uProfMenu_ucjs',
            0
          );
        } else {
          var result =
            this.fillClipboardValue(ucJsScripts);
    
          Cc['@mozilla.org/widget/clipboardhelper;1']
            .getService(Ci.nsIClipboardHelper)
            .copyString(result);
        }
      },
    
    
      fillMenu: function(
        whichsubmenu,
        whichsubmenuitems,
        strlabel,
        scriptArray,
        sClass,
        sTyp
      ) {
        var e =
          document.getElementById(whichsubmenu);
    
        if (!e) return;
    
        e.setAttribute(
          'label',
          strlabel + ' (' + scriptArray.length + ')'
        );
    
        var popup =
          document.getElementById(whichsubmenuitems);
    
        if (!popup) return;
    
        while (popup.hasChildNodes())
          popup.removeChild(popup.firstChild);
    
        if (scriptArray.length == 0) {
          this.addDisabledMenuItem(
            popup,
            '(keine Skripte gefunden)'
          );
          return;
        }
    
        for (var i = scriptArray.length - 1; i >= 0; i--) {
          var filename = scriptArray[i];
    
          var mitem = this.createME(
            'menuitem',
            filename,
            '',
            sClass,
            0
          );
    
          if (sTyp == 0) {
            mitem.addEventListener(
              'command',
              function() {
                uProfMenu.edit(
                  0,
                  this.getAttribute('label')
                );
              },
              true
            );
    
            mitem.addEventListener(
              'click',
              function(event) {
                uProfMenu.openAtGithub(
                  event,
                  this.getAttribute('label')
                );
    
                if (event.button == 1 || event.button == 2)
                  event.preventDefault();
              },
              true
            );
    
            mitem.setAttribute(
              'tooltiptext',
              'Linksklick: Bearbeiten\n' +
              'Mittelklick: GitHub öffnen\n' +
              'Rechtsklick: Suche auf GitHub'
            );
          } else {
            mitem.addEventListener(
              'command',
              function() {
                openTrustedLinkIn(
                  this.getAttribute('label'),
                  'tab'
                );
              },
              true
            );
          }
    
          popup.insertBefore(
            mitem,
            popup.firstChild
          );
        }
      },
    
    
      fillClipboardValue: function(sArray) {
        var retValue;
        var s = sArray.length;
    
        if (this.enableScriptsToClip == 1) {
          retValue =
            'userChromeJS/uc.js (' +
            s +
            '):\n------------------------\n' +
            sArray.join('\n');
        } else {
          retValue =
            'userChromeJS/uc.js (' +
            s +
            '):\n------------------------';
    
          for (var i = 0; i < s; i++)
            retValue +=
              '\n' +
              (i + 1) +
              '. ' +
              sArray[i];
        }
    
        return retValue;
      },
    
    
      createME: function(
        sTyp,
        sLabel,
        sCommand,
        sClass,
        sId
      ) {
        var XUL_NS =
          'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul';
    
        var m =
          document.createElementNS(XUL_NS, sTyp);
    
        switch (sTyp) {
    
          case 'menuitem':
            m.setAttribute('label', sLabel);
    
            if (sClass)
              m.setAttribute('class', sClass);
    
            if (sCommand) {
              m.addEventListener(
                'command',
                function() {
                  var command =
                    sCommand.replace(/;\s*$/, '');
    
                  if (command == 'uProfMenu.createJSfile()') {
                    uProfMenu.createJSfile();
                    return;
                  }
    
                  if (command == 'uProfMenu.getScripts(1)') {
                    uProfMenu.getScripts(1);
                    return;
                  }
    
                  if (command == 'uProfMenu.openSettings()') {
                    uProfMenu.openSettings();
                    return;
                  }
    
                  if (command == 'uProfMenu.restart()') {
                    uProfMenu.restart();
                    return;
                  }
    
                  var editMatch =
                    command.match(
                      /^uProfMenu\.edit\((\d+),'([\s\S]*)'\)$/
                    );
    
                  if (editMatch) {
                    uProfMenu.edit(
                      Number(editMatch[1]),
                      editMatch[2]
                    );
                    return;
                  }
    
                  var aboutMatch =
                    command.match(
                      /^openTrustedLinkIn\('([\s\S]*)','tab'\)$/
                    );
    
                  if (aboutMatch) {
                    openTrustedLinkIn(
                      aboutMatch[1],
                      'tab'
                    );
                    return;
                  }
                },
                true
              );
            }
            break;
    
          case 'menu':
            m.setAttribute('label', sLabel);
            if (sId) m.setAttribute('id', sId);
            break;
    
          case 'menupopup':
            if (sId) m.setAttribute('id', sId);
            break;
        }
    
        return m;
      },
    
    
      openAtGithub: function(e, sScript) {
        if (e.button == 1) {
          var sUrl =
            'https://github.com/Endor8/userChrome.js/tree/master/' +
            this.cleanFileName(sScript);
    
          openWebLinkIn(sUrl, 'tab');
        }
    
        if (e.button == 2) {
          e.preventDefault();
    
          var sUrl =
            'https://github.com/search?langOverride=&language=&q=' +
            this.cleanFileName(sScript) +
            '&repo=&start_value=1&type=Code';
    
          openWebLinkIn(sUrl, 'tab');
        }
      },
    
    
      createJSfile: function(Filename) {
        if (!Filename)
          Filename = prompt(
            'Name des Skripts',
            'skriptName'
          );
    
        if (Filename)
          Filename = Filename
            .replace(/\s+/g, ' ')
            .replace(/[\\/:*?"<>|]/g, '');
    
        if (!Filename || !/\S/.test(Filename))
          return;
    
        if (!/\.uc\.js$/i.test(Filename))
          Filename += '.uc.js';
    
        this.edit(0, Filename);
      },
    
    
      cleanFileName: function(sName) {
        sName = sName.toLowerCase();
    
        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 sName;
      },
    
    
      restart: function() {
        Services.appinfo.invalidateCachesOnRestart();
    
        Services.startup.quit(
          Ci.nsIAppStartup.eRestart |
          Ci.nsIAppStartup.eAttemptQuit,
          0
        );
      },
    
    
      stringComparison: function(a, b) {
        return a.localeCompare(b);
      }
    };
    
    
    // ==================== START ====================
    
    uProfMenu.init();
    Alles anzeigen
  • Benutzerskripte funktionieren seit Version 138 teilweise nicht mehr

    • FuchsFan
    • 25. August 2026 um 18:25
    Zitat von Dharkness

    Auch bei Dir fehlt die verbindende schließende >,

    Dharkness

    Du hast recht, Ralf, so wird dann wirklich jedes Item direkt angesprochen. Ohne, dann wurde es gleich auf den Subordner übertragen. Danke für den Hinweis.:thumbup:

  • Benutzerskripte funktionieren seit Version 138 teilweise nicht mehr

    • FuchsFan
    • 25. August 2026 um 17:54

    Dharkness

    Dieses wäre die "bessere" Variante.

    CSS
    /* Zähler bei Hover */
    menu.bookmark-item:hover > .countClass::after,
    menuitem.bookmark-item:hover > .countClass::after {
        color: #ff0000 !important;
    }

    Die Symbole können natürlich gewechselt werden, aus dem Script die habe ich hier raus gesucht.

    Powershell Emojis | </>🪟>_👨‍💻 | Copy & Paste

  • Benutzerskripte funktionieren seit Version 138 teilweise nicht mehr

    • FuchsFan
    • 25. August 2026 um 13:47

    Und wer das noch mit Symbolen haben möchte, das sieht dann so aus (Icon sind eingearbeitet).

    JavaScript
    (function() {
    
        if (!window.gBrowser)
            return;
    
        // ==========================================
        // EINSTELLUNG
        // ==========================================
    
        // Breite der einzelnen Bookmark-Items
        // Beispiele:
        // "250px"
        // "300px"
        // "20em"
        // "auto"
        const itemWidth = "400px";
    
    
        // ==========================================
    
        setTimeout(function() {
            setFunction();
        }, 50);
    
        function setFunction() {
    
            const css = `
                /* Breite der Menü-Items */
                menupopup menu.bookmark-item,
                menupopup menuitem.bookmark-item {
                    width: ${itemWidth} !important;
                    min-width: ${itemWidth} !important;
                    max-width: ${itemWidth} !important;
                    box-sizing: border-box;
                }
    
                /* Label als Bezugspunkt */
                .countClass {
                    position: relative;
                    padding-right: 6em;
                }
    
                /* Zählerbereich */
                .countClass::after {
                    content: attr(data-value);
                    position: absolute;
                    right: 0.25em;
                    top: 50%;
                    transform: translateY(-50%);
    
                    color: #631717;
                    padding: 0.75em 0;
                    border-radius: 0.25em;
    
                    font-size: 1em;
                    font-weight: 700;
    
                    white-space: pre;
                    pointer-events: none;
    
                    /* Wichtig: Monospace sorgt für feste Zeichenbreiten */
                    font-family: monospace;
                }
            `;
    
            try {
                const sss = Cc['@mozilla.org/content/style-sheet-service;1']
                    .getService(Ci.nsIStyleSheetService);
    
                const uri = Services.io.newURI(
                    'data:text/css,' + encodeURIComponent(css)
                );
    
                if (!sss.sheetRegistered(uri, sss.AGENT_SHEET)) {
                    sss.loadAndRegisterSheet(uri, sss.AGENT_SHEET);
                }
    
            } catch (e) {
                console.error(
                    "Fehler beim Registrieren des Stylesheets:",
                    e
                );
            }
    
            let bmbMenu = document.getElementById('bookmarks-menu-button');
            let bookMenu = document.getElementById('bookmarksMenu');
            let persToolBar = document.getElementById('PersonalToolbar');
    
            if (bmbMenu)
                bmbMenu.addEventListener('popupshowing', onPopupShowing);
    
            if (bookMenu)
                bookMenu.addEventListener('popupshowing', onPopupShowing);
    
            if (persToolBar)
                persToolBar.addEventListener('popupshowing', onPopupShowing);
        }
    
        function onPopupShowing(aEvent) {
    
            let popup = aEvent.originalTarget;
    
            if (!popup || !popup.children)
                return;
    
            for (let item of popup.children) {
    
                if (item.localName != 'menu' ||
                    item.id?.startsWith('history'))
                    continue;
    
                setTimeout(() => {
    
                    try {
    
                        let itemPopup = item.menupopup;
    
                        if (!itemPopup)
                            return;
    
                        itemPopup.openPopup && itemPopup.openPopup();
                        itemPopup.hidePopup && itemPopup.hidePopup();
    
                        let menuitemCount = 0;
                        let menuCount = 0;
    
                        for (let subitem of itemPopup.children) {
    
                            if (subitem.classList &&
                                subitem.classList.contains('bookmark-item') &&
                                !subitem.disabled &&
                                !subitem.hidden) {
    
                                if (subitem.localName == 'menuitem') {
                                    menuitemCount++;
                                }
                                else if (subitem.localName == 'menu') {
                                    menuCount++;
                                }
                            }
                        }
    
                        let label =
                            item.querySelector('.menu-iconic-text') ||
                            item.querySelector('label') ||
                            item.childNodes[1];
    
                        if (!label)
                            return;
    
                        label.classList.add('countClass');
    
                        /*
                         * Feste Spalten:
                         *
                         *  🔰  12  /  ⭐  34
                         *
                         * Durch die feste Breite der einzelnen
                         * Bereiche sitzt der Slash immer gleich.
                         */
                        let strCountOut =
                            "🔰️ " +
                            String(menuCount).padStart(3, " ") +
                            " / " +
                            "⭐ " +
                            String(menuitemCount).padStart(3, " ");
    
                        label.setAttribute(
                            'data-value',
                            strCountOut
                        );
    
                    } catch (e) {
    
                        console.error(
                            "Fehler im onPopupShowing-Handler:",
                            e
                        );
    
                    }
    
                }, 80);
            }
        }
    
    })();
    Alles anzeigen
  • Benutzerskripte funktionieren seit Version 138 teilweise nicht mehr

    • FuchsFan
    • 24. August 2026 um 22:30

    Stoiker

    Teste bitte! Die Breite kann in Zeile 16 eingestellt werden.

    JavaScript
    (function() {
    
        if (!window.gBrowser)
            return;
    
        // ==========================================
        // EINSTELLUNG
        // ==========================================
        
        // Breite der einzelnen Bookmark-Items
        // Beispiele:
        // "250px"
        // "300px"
        // "20em"
        // "auto"
        const itemWidth = "400px";
    
        // ==========================================
    
        setTimeout(function() {
            setFunction();
        }, 50);
    
        function setFunction() {
    
            const css = `
                /* Breite der Menü-Items */
                menupopup menu.bookmark-item,
                menupopup menuitem.bookmark-item {
                    width: ${itemWidth} !important;
                    min-width: ${itemWidth} !important;
                    max-width: ${itemWidth} !important;
                    box-sizing: border-box;
                }
    
                /* Label selbst muss relativ sein,
                   damit das Pseudo-Element absolut positioniert
                   werden kann */
                .countClass {
                    position: relative;
                    padding-right: 2.5em;
                }
    
                /* ::after absolut rechts positioniert */
                .countClass::after {
                    content: attr(data-value);
                    position: absolute;
                    right: 0.25em;
                    top: 50%;
                    transform: translateY(-50%);
                    color: white;
                    background: rgba(0,0,0,0.3);
                    padding: 0 0.25em;
                    border-radius: 0.25em;
                    font-size: 0.9em;
                    white-space: nowrap;
                    pointer-events: none;
                }
            `;
    
            try {
                const sss = Cc['@mozilla.org/content/style-sheet-service;1']
                    .getService(Ci.nsIStyleSheetService);
    
                const uri = Services.io.newURI(
                    'data:text/css,' + encodeURIComponent(css)
                );
    
                if (!sss.sheetRegistered(uri, sss.AGENT_SHEET)) {
                    sss.loadAndRegisterSheet(uri, sss.AGENT_SHEET);
                }
    
            } catch (e) {
                console.error(
                    "Fehler beim Registrieren des Stylesheets:",
                    e
                );
            }
    
            let bmbMenu = document.getElementById('bookmarks-menu-button');
            let bookMenu = document.getElementById('bookmarksMenu');
            let persToolBar = document.getElementById('PersonalToolbar');
    
            if (bmbMenu)
                bmbMenu.addEventListener('popupshowing', onPopupShowing);
    
            if (bookMenu)
                bookMenu.addEventListener('popupshowing', onPopupShowing);
    
            if (persToolBar)
                persToolBar.addEventListener('popupshowing', onPopupShowing);
        }
    
        function onPopupShowing(aEvent) {
    
            let popup = aEvent.originalTarget;
    
            if (!popup || !popup.children)
                return;
    
            for (let item of popup.children) {
    
                if (item.localName != 'menu' ||
                    item.id?.startsWith('history'))
                    continue;
    
                // kleiner Timeout zum Auffinden der child-popup Elemente
                setTimeout(() => {
    
                    try {
    
                        let itemPopup = item.menupopup;
    
                        if (!itemPopup)
                            return;
    
                        // Öffnen/Schließen nur, wenn nötig
                        itemPopup.openPopup && itemPopup.openPopup();
                        itemPopup.hidePopup && itemPopup.hidePopup();
    
                        let menuitemCount = 0;
                        let menuCount = 0;
    
                        for (let subitem of itemPopup.children) {
    
                            if (subitem.classList &&
                                subitem.classList.contains('bookmark-item') &&
                                !subitem.disabled &&
                                !subitem.hidden) {
    
                                if (subitem.localName == 'menuitem') {
                                    menuitemCount++;
                                }
                                else if (subitem.localName == 'menu') {
                                    menuCount++;
                                }
                            }
                        }
    
                        // Robuster Label-Finder
                        let label =
                            item.querySelector('.menu-iconic-text') ||
                            item.querySelector('label') ||
                            item.childNodes[1];
    
                        if (!label)
                            return;
    
                        label.classList.add('countClass');
    
                        let strCountOut =
                            menuCount + "/" + menuitemCount;
    
                        label.setAttribute(
                            'data-value',
                            strCountOut
                        );
    
                    } catch (e) {
    
                        console.error(
                            "Fehler im onPopupShowing-Handler:",
                            e
                        );
    
                    }
    
                }, 80);
            }
        }
    
    })();
    Alles anzeigen
  • Benutzerskripte funktionieren seit Version 138 teilweise nicht mehr

    • FuchsFan
    • 24. August 2026 um 21:53
    Zitat von Stoiker

    D.h. in anderen Ordnern wird die Breite (dynamisch? bis zu einer gewissen Breite?) angepasst. In dem gezeigten Ordner nicht :/

    Morgen werde ich mal versuchen das in das Script einzubauen, versprechen kann ich nichts, aber eventuell lässt es sich so einrichten, dass du dann manuell die Breite wählen kannst.

  • Benutzerskripte funktionieren seit Version 138 teilweise nicht mehr

    • FuchsFan
    • 24. August 2026 um 21:22
    Zitat von Stoiker

    D.h. hier "rutscht" die Anzeige in den Text rein.

    Schau doch mal selbst auf deine eingestellten Grafiken, fällt dir nicht auf dass das untere Popup viel schmaler ist. Dadurch ist es logisch, dass es in den Text hinein ragt. Das heißt, du kannst mit einem css-Code das Popup verbreitern, dann passt es auch. Das Script selbst sollte ja nur den Count rechtsbündig abschließen, so hattest du den Wunsch geäußert.

Unterstütze uns!

Jährlich (2026)

72,4 %

72,4% (560,79 von 775 EUR)

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