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

Beiträge von bege

  • Über 1,3GB Daten im Profil von Firefox for Android und für Windows

    • bege
    • 13. Oktober 2026 um 20:19

    So

    Zitat von AngelOfDarkness

    über die Funktion "Firefox beenden"

    bleibt Firefox for Android auf meinem Handy im Speicher, und so

    Zitat von AngelOfDarkness

    "wegwischen"

    verschwindet er aus dem Speicher.

    Bei ersterem löscht die Erweiterung die Cookies bei dem erneuten Firefox-Start nicht, bei letzterem schon.

  • Über 1,3GB Daten im Profil von Firefox for Android und für Windows

    • bege
    • 13. Oktober 2026 um 20:00
    Zitat von .DeJaVu

    bitteschön ... Kontrollwahn ... Reinigungszwang

    Da ich nicht um Hilfe bei einer psychischen Störung gebeten habe, wofür das hier auch das falsche Forum wäre, trägt dein Beitrag nichts zum Thema bei.

    Zitat von .DeJaVu

    ... Ich kann mich nur wiederholen:

    Zitat von .DeJaVu

    Von meiner Seite aus möchte ich das nicht vertiefen ...

    Du kannst dich, wenn dich ein Thema nicht interessiert, sondern nur nervt, auch einfach raushalten. Wenn ich explizit eine Antwort von einem Teilnehmer möchte, dann zitiere ich ihn oder spreche ihn mit dem "@" an.

    Manchmal lese ich hilfreiche Beiträge von dir. Manchmal schießt du daneben, wie in Beitrag #2. Und öfter erlebe ich dich respektlos. Wenn du nicht respektvoll antworten kannst, dann antworte bitte nicht.

  • Über 1,3GB Daten im Profil von Firefox for Android und für Windows

    • bege
    • 13. Oktober 2026 um 18:50

    Eine gute Nachricht: Die Partition-Cookies werden von Auto-Clear Site Data erst gelöscht, wenn Firefox for Android komplett neu gestartet wird. Nach Firefox beenden bleibt der Firefox im Speichercache. Wenn man ihn dann wieder öffnet, sind die Cookies noch da. Wird er aber komplett beendet und neu gestartet, sind sie weg.

    Der Firefox-Cache wird aber nicht komplett bereinigt und läuft deshalb voll.

  • Über 1,3GB Daten im Profil von Firefox for Android und für Windows

    • bege
    • 11. Oktober 2026 um 18:44
    Zitat von Sören Hentzschel

    Du könntest ja mal diese Erweiterung testen:

    Damit habe ich mich schon auf Android beschäftigt, und dort löscht sie zumindest die Partition Cookies nicht - so wie auch Cookie AutoDelete und Forget Me Not. Leider hat der Entwickler keine Homepage für Issues und Diskussionen. Wenn die Erweiterung richtig funktioniert, wäre sie eine Lösung für mein Problem. Ich hoffe also noch ...

  • Über 1,3GB Daten im Profil von Firefox for Android und für Windows

    • bege
    • 10. Oktober 2026 um 22:58
    Zitat von Sören Hentzschel

    Wieso sollte das getrennt werden?

    Weil ich die Cookies z.B. für die Duckduckgo- und Startpage-Einstellungen, aber auch für ein paar andere Websites, speichern , aber nicht hunderte von MB von Websitedaten, von denen ich viele nur ein mal besucht habe, aufhäufen will.

  • Über 1,3GB Daten im Profil von Firefox for Android und für Windows

    • bege
    • 10. Oktober 2026 um 20:59

    Ich habe mir die Dateien im Firefox für Android mal genauer angeschaut.

    Zitat von bege

    .../[profil]/storage/permanent/chrome/idb/387011272rsegmnoittet-es.files sind 1800 Dateien

    Die sind alle ~2KB groß und beim stichprobenartigen hineinschauen sind es alles Zertifikatsdateien.

    Zitat von bege

    .../[profil]/storage/default in 9500 Ordnern 13900 Dateien

    Das sind 1620 Ordner ("https+++[Domain]") mit einer Datei ".metadata-v2", teilweise mit Unterordnern, darunter auch "cache" vom Juni.

    Außerdem 31 Ordner "moz-extension+++[Buchstaben und Ziffern]", ebenfalls mit Unterordnern. Die meisten sind ~60KB klein, nur zwei >100MB. Das sind Daten von Erweiterungen.

    Ich habe dieses Thema gefunden: https://support.mozilla.org/tn/questions/1403621

    In den Einstellungen "Browser-Daten beim Beenden löschen" habe ich "Cookies und Website-Daten" nicht angehakt, weil ich die Cookies mit Cookie AutoDelete verwalte. Einige sollen erhalten bleiben.

    Nachdem ich jetzt einmalig Cookies und Website-Daten gelöscht habe, sind die Website-Daten aus dem "default"-Ordner weg. Das heißt, wenn man Cookies nicht komplett löschen will, läuft der Speicher mit nicht gelöschten Website-Daten voll. Das ist unbefriedigend und sollte getrennt werden. Ich schaue mal auf bugzilla, ob es dafür schon einen Bericht gibt.

  • Zeilenabstand der Lesezeichen ändern?

    • bege
    • 10. Oktober 2026 um 20:07

    Damit werden bei mir die Zeilenabständer aller Popupmenüs verringert.

    CSS
    menupopup > menuitem,
    menupopup > menu {
      padding-block: 1.5px !important;
  • Über 1,3GB Daten im Profil von Firefox for Android und für Windows

    • bege
    • 3. Oktober 2026 um 16:41

    Beim Übertragen der Firefox-Daten von einem gerooteten Android-Handy auf ein anderes habe ich festgestellt, dass im Ordner .../[profil]/storage/default in 9500 Ordnern 13900 Dateien mit zusammen über 700MB sind. Die Dateien stammen aus der Zeit vom 14. Juni bis heute.

    Im Ordner .../[profil]/storage/permanent/chrome/idb/387011272rsegmnoittet-es.files sind 1800 Dateien mit ca. 600MB. Diese Dateien sind alle aus dem Juni.

    Hat das etwas mit der Chronik zu tun, oder sind das ganz andere Daten?

    In den Einstellungen habe ich das Löschen der Chronik beim Schließen deaktivert, weil ich die Chronik einige Wochen behalten möchte. Löscht Firefox for Android die Chronik automatisch erst nach über 3 Monaten? Die Erweiterung Historia, die ich für Windows nutze, funktioniert unter Android nicht.

    Unter Windows sieht die Datenmenge ähnlich aus. Dort nutze ich die Erweiterung Historia, um die Chronik nach 30 Tagen zu löschen.

    Was muss ich tun, um diese Datenmenge zumindest auf dem Handy zu reduzieren?

  • Flagfox funktioniert mit VPN nicht

    • bege
    • 2. Oktober 2026 um 23:57

    Wenn das in Firefox integrierte VPN aktiv ist, wird kein Serverstandort, stattdessen aber diese Fehlermeldung von Flagfox angezeigt:

    Ihre aktuellen Proxy-Einstellungen erlauben keine lokalen DNS-Anfragen.
    (network.proxy.socks_remote_dns) Flagfox verwendet eine interne IP-Adressen-Standort-Datenbank
    um Serverstandorte nachzuschlagen. Ohne Zugriff auf diese Datenbank ist es Flagfox jedoch
    unmöglich IP-Adressen über DNS-Abfragen nachzuschlagen.

    Die genannte erweiterte Einstellung auf "true" zu setzen, ändert nichts.

    Lässt sich das beheben?

  • Farbe Violett in Version 157 tauschen

    • bege
    • 30. September 2026 um 01:19
    Zitat von 2002Andreas

    Teste bitte:

    CSS
    :root {
        --color-accent-primary: blue !important;
        --button-background-color-primary-hover: green !important;	
    }

    Farben wenn dann anpassen.

    Auch von mir ein Dankeschön.

    Mir fehlt noch die Angabe für den Hintergrund beim Hovern über diesen inaktiven Buttons. Den habe ich mit dem Inspektor nicht herausgefunden. Der soll auch nicht mehr violett sein, sondern so wie bei dem aktiven Button. Auch wenn man über die verschiedenen Bereiche in der linken Leiste der Einstellungen hovert, sind die Hintergründe noch violett.

  • Zugang Firefox Konto nicht möglich

    • bege
    • 4. September 2026 um 23:34

    Ich bin überrascht, dass dieser Beitrag schon vom Januar ist. Bei mir passiert das heute zum ersten Mal.

    Auch hier brauchen die Mails z.T. sehr lange, bis sie ankommen, aber bei mancher Anmeldung komme ich ins Konto und werde nicht nach dem Autorisierungscode gefragt, kann ihn also nicht eingeben.

    Bei addons.mozilla.org hatte ich Glück, da konnte ich mich nach dem Abmelden wieder anmelden - wieder ohne nach dem Code gefragt zu werden. Erst bei der dritten Anmeldung kam die Abfrage.

    Bei addons.thunderbird.net habe ich mich auch ohne Code anmelden können, konnte also dem Code, der per Mail kam, gar nicht eingeben. Als ich mich nach dem Abmelden wieder anmelden wollte, war der Zugang zu thunderbird.net gesperrt mit dem "freundlichen" Hinweis, ich könnte mich per E-Mail beim Website-Betreiber melden.

    Das ist echt gruselig. Weiß jemand, wo ich mich da melden kann, um den Zugang wieder freischalten zu lassen?

  • Dateierweiterung am Icon erkennen

    • bege
    • 4. September 2026 um 21:52

    Uralt, aber funkioniert:

    Link Alert – Holen Sie sich diese Erweiterung für 🦊 Firefox (de)
    Laden Sie Link Alert für Firefox herunter. Displays an icon in the tooltip or next to the cursor indicating the target of a link.
    addons.mozilla.org
  • Skript "OpenbookModoki" klappt die Lesezeichenliste nicht mehr auf

    • bege
    • 4. September 2026 um 21:47

    Das ist die Version, die ich nutze, da geht es. Habe ich nicht mit deiner verglichen, Falls sie gleich sind, funkt was anderes dazwischen.

    JavaScript: openbookModoki.uc.js
    // ==UserScript==
    // @name           openbookModoki.uc.js
    // @namespace      https://github.com/Endor8/userChrome.js/blob/master/openbookmodoki/OpenBookModoki.uc.js
    // @description    Lesezeichen Bearbeiten Panel: Veränderbare Panelgröße hinzugefügt. Schlüsselwort und Ordner-Struktur
    // @description    Felder sind geschlossen. Weitere Einstellungen: Beschreibung, Ordner, Dieses Lesezeichen in der Sidebar laden,
    // @description    und Schlüsselwort können ein-/ausgeblendet werden.
    // @include        main
    // @source         https://www.camp-firefox.de/forum/thema/135858-skript-openbookmodoki-funktioniert-nicht-mehr/?postID=1218464#post1218464
    // @author         Alice0775
    // @version        2023/11/15 17:00 Fenster schließen, Zeitanpassung nach @Aborix aus 2019; https://www.camp-firefox.de/forum/thema/127571-lesezeichen-speichern-anzeigedauer-gr%C3%B6%C3%9Fe-des-dialogfensters-zur-bearbeitung/?postID=1108858#post1108858
    // @version        2023/01/27 14:30 Fx109 by Sören Hentzschel
    // @version        2020/05/11 10:30 Fx76 by aborix
    // @version        2018/03/15 10:30 Fx59 by aborix
    // @version        2017/11/17 02:30 Fx57
    // @version        2016/03/20 02:30 remove tst hack
    // @version        2015/08/31 02:30 Fx40
    // @version        2013/07/07 02:30 fix onFolderMenuListCommand
    // @version        2012/12/08 22:30 Bug 788290 Bug 788293 Remove E4X
    // @version        2012/07/24 14:30 Bug 761723 implement toString of function objects by saving source
    // @version        2010/12/06 10:30 Bug Bug 597557 - Bookmarks & Identity panels should use an Arrowpanel
    // @version        2010/04/01 00:00 Bug 556342  - Invalid Treeview in bookmark menu via star pane
    // @version        2009/12/22 00:00 namePicker in front
    // @version        2009/12/21 14:00 BETTER WORKAROUND FIX  Bug 536024 -  When i expand folder-tree on Edit This Bookmark, the bookmarked folder is changed.
    // @version        2009/12/20 16:00 WORKAROUND FIX  Bug 536024 -  When i expand folder-tree on Edit This Bookmark, the bookmarked folder is changed.
    // @version        2009/08/11 18:00 Tree Style Tab0.8.2009081101 Unterstützung für das Umbenennen von Objekten
    // @version        2009/08/07 00:00 Tree Style Tab0.8.2009073102 Treestyletab-Tabzeile ausblenden, wenn vorhanden
    // @version        2009/08/06 19:00 Tree Style Tab0.8.2009073102 Problem, dass der übergeordnete Tab für einen Moment angezeigt wird, behoben 
    // @version        2009/08/06 18:00 Tree Style Tab0.8.2009073102 entsprechend
    // @version        2009/06/24 00:00 Firefox3.5 Es wurde ein Fehler behoben, durch den der Offen / Geschlossen Status des Expanders in der 
    // @version        2009/06/24 00:00 Ordnerstruktur und der Tag-Auswahl nicht gespeichert wurde
    // @version        2009/01/02 02:00 Beschreibung, Position, loadInSidebar, Schlüsselwort und Einstellung anzeigen / ausblenden
    // @version        2009/01/01 22:28
    // ==/UserScript==
    
    var openbookResizer = {
    
      drag  : false,
      height: null,
      width : null,
      eventOffset: null,
      timer: null,
      PREHIDEROW    : "userChrome.openbook.hideRow",  // description, location, loadInSidebar, keyword
      PREFTREEHEIGHT: "userChrome.openbook.treeHeight",
      PREFTREEWIDTH : "userChrome.openbook.treeWidth",
      PREFOPENTREE  : "userChrome.openbook.openTree",
      PREFOPENTAG   : "userChrome.openbook.openTag",
    
      get tree(){
        return gEditItemOverlay._folderTree;
      },
    
      get getHideRow(){
        try {
          return Services.prefs.getCharPref(this.PREHIDEROW).replace(/\s/g,'').slice(',');
        } catch(e) {
          return [];
        }
      },
    
      get getPrefTreeHeight(){
        try {
          return Services.prefs.getIntPref(this.PREFTREEHEIGHT);
        } catch(e) {
          return 150;
        }
      },
      get getPrefTreeWidth(){
        try {
          return Services.prefs.getIntPref(this.PREFTREEWIDTH);
        } catch(e) {
          return 250;
        }
      },
    
      get editBookmarkPanel(){
        return StarUI.panel;
      },
    
      get treeExpander(){
        return gEditItemOverlay._element('foldersExpander');
      },
    
      get tagExpander(){
        return gEditItemOverlay._element('tagsSelectorExpander');
      },
    
      get getPrefOpenTree(){
        try {
          return Services.prefs.getBoolPref(this.PREFOPENTREE);
        } catch(e) {
          return false;
        }
      },
    
      get getPrefOpenTag(){
        try {
          return Services.prefs.getBoolPref(this.PREFOPENTAG);
        } catch(e) {
          return false;
        }
      },
    
      init: function(){
        //window.removeEventListener('load', this, false);
        window.addEventListener('unload', this, false);
    
        var style = " \
          .openbookResizerGripper { \
            list-style-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAApklEQVQokY3QK4uCURCA4QeDLCoIXoIYNFiUFVZBq2JQEEx+UcTmpi1b121eosX/a5lg8jvTzsy8M+8cGGKNusQY44QMlRTgAzOcsUqBitH0FVCWpzeNpmZsytUb4oY9qil6BfRxDaiZp1eO5OBl01u9JX7QxiRFr4XfmNbFZ+gdojbCBbt4a6CDP/wH1McDR9SwwB1b+I4bejG1ER8xxwaluHOJ8RM+9xjk9q2RpwAAAABJRU5ErkJggg=='); \
            cursor: sw-resize; \
          }";
        var sspi = document.createProcessingInstruction(
          'xml-stylesheet',
          'type="text/css" href="data:text/css,' + encodeURIComponent(style) + '"'
        );
        document.insertBefore(sspi, document.documentElement);
        sspi.getAttribute = function(name) {
        return document.documentElement.getAttribute(name);
        };
    
        this.folderTreeRow   = "folderTreeRow";
        this.tagsSelectorRow = "tagsSelectorRow";
    
        gEditItemOverlay.initPanel_org = gEditItemOverlay.initPanel;
        gEditItemOverlay.initPanel = function(aInfo) {
          aInfo.hiddenRows = openbookResizer.getHideRow;
          gEditItemOverlay.initPanel_org(aInfo);
        }
    
        // selected tree visible
        func = gEditItemOverlay.toggleFolderTreeVisibility.toString();
        func = func.replace(
          'var currentFolder = this._getFolderIdFromMenuList();',
          ''
        );
        func = func.replace(
          /expander.className = "expander-up";*/,
          'var currentFolder = this._getFolderIdFromMenuList(); \
          var onselect = this._folderTree.getAttribute("onselect"); \
          this._folderTree.removeAttribute("onselect"); \
          $&;'
        );
        func = func.replace(
          'this._folderTree.focus();',
          '$&; \
          setTimeout(function(tree){ \
            var start = new Object(); \
            var end = new Object(); \
            var numRanges = tree.view.selection.getRangeCount(); \
            if (numRanges > 0) { \
              tree.view.selection.getRangeAt(0,start,end); \
              var v = start.value; \
              tree.treeBoxObject.ensureRowIsVisible(v); \
            } \
            tree.setAttribute("onselect", onselect); \
          }, 0, this._folderTree);'
        );
        try{
          gEditItemOverlay.toggleFolderTreeVisibility = new Function(
             func.match(/\((.*)\)\s*\{/)[1],
             func.replace(/^function\s*.*\s*\(.*\)\s*\{/, '').replace(/}$/, '')
          );
        } catch(ex){}
    
        // selected tree visible
        func = gEditItemOverlay.onFolderMenuListCommand.toString();
        func = func.replace(
          'this._folderTree.selectItems([container]);',
          '{var onselect = this._folderTree.getAttribute("onselect"); \
          this._folderTree.removeAttribute("onselect"); \
          $&; \
          setTimeout(function(tree){ \
            var start = new Object(); \
            var end = new Object(); \
            var numRanges = tree.view.selection.getRangeCount(); \
            if (numRanges > 0) { \
              tree.view.selection.getRangeAt(0,start,end); \
              var v = start.value; \
              tree.treeBoxObject.ensureRowIsVisible(v); \
            } \
            tree.setAttribute("onselect", onselect); \
          }, 0, this._folderTree);}'
        );
        try{
          gEditItemOverlay.onFolderMenuListCommand = new Function(
             func.match(/\((.*)\)\s*\{/)[1],
             func.replace(/^function\s*.*\s*\(.*\)\s*\{/, '').replace(/}$/, '')
          );
        } catch(ex){}
    
        this.editBookmarkPanel.addEventListener('popupshowing', this, false);
        this.editBookmarkPanel.addEventListener('popupshown', this, false);
        this.editBookmarkPanel.addEventListener('popuphiding', this, false);
      },
    
      uninit: function(){
        window.removeEventListener('unload', this, false);
        this.editBookmarkPanel.removeEventListener('popupshowing', this, false);
        this.editBookmarkPanel.removeEventListener('popupshown', this, false);
        this.editBookmarkPanel.removeEventListener('popuphiding', this, false);
      },
    
      handleEvent: function(event){
        switch(event.type){
          case 'unload':
            this.uninit();
            break;
          case 'popupshowing':
            this.popupshowing(event);
            break;
          case 'popupshown':
            this.popupshown(event);
            break;
          case 'popuphiding':
            this.popuphiding(event);
        }
      },
    
      popuphiding: function(event){
        if (this.editBookmarkPanel != event.originalTarget)
          return;
        var state = !gEditItemOverlay._element(this.folderTreeRow).hidden;
        Services.prefs.setBoolPref(this.PREFOPENTREE, state);
        var state = !gEditItemOverlay._element(this.tagsSelectorRow).hidden;
        Services.prefs.setBoolPref(this.PREFOPENTAG, state);
    
        gEditItemOverlay._element(this.folderTreeRow).hidden = true;
        gEditItemOverlay._element(this.tagsSelectorRow).hidden = true;
      },
    
      popupshowing: function(event){
        if (this.editBookmarkPanel != event.originalTarget)
          return;
    
        this.tree.height = this.getPrefTreeHeight;
        //this.tree.width = this.getPrefTreeWidth;
        //this.editBookmarkPanel.width = this.getPrefTreeWidth;
    
        if (!document.getElementById("openbookResizerbottomBox")) {
          var panel = StarUI.panel;
    
          var innerarrow = panel.openOrClosedShadowRoot.querySelector('.panel-arrowcontent');
          if (innerarrow)
            innerarrow.setAttribute('flex', 1);
    
          var box = document.createXULElement("hbox");
          box.setAttribute('id', 'openbookResizerbottomBox');
          box.setAttribute('align',"start");
    
          var resizer = document.createXULElement("image");
          resizer.setAttribute("class", "openbookResizerGripper");
          resizer.setAttribute('onmousedown', 'openbookResizer.mousedown(event)');
    
          box.appendChild(resizer);
          panel.appendChild(box);
    
          panel.setAttribute('onmousemove', 'openbookResizer.mousemove(event)');
          panel.setAttribute('onmouseup', 'openbookResizer.mouseup(event)');
        }
      },
    
      popupshown: function(event){
        if (this.editBookmarkPanel != event.originalTarget)
          return;
        setTimeout(function(self) {
          if (self.getPrefOpenTree &&
              gEditItemOverlay._element(self.folderTreeRow).hidden ) {
            gEditItemOverlay.toggleFolderTreeVisibility();
          }
          if (self.getPrefOpenTag &&
              gEditItemOverlay._element(self.tagsSelectorRow).hidden ) {
            gEditItemOverlay.toggleTagsSelector();
          }
          try {
            gEditItemOverlay._element(Services.prefs
              .getCharPref("browser.bookmarks.editDialog.firstEditField")).focus();
          } catch(e) {}
        }, 100, this);
      },
    
      mousedown: function(event){
        this.drag = true;
        this.height = parseInt(this.tree.boxObject.height);
        this.width = parseInt(this.editBookmarkPanel.boxObject.width);
        this.eventOffset = event;
      },
    
      mousemove: function(event) {
        if (this.timer)
          clearTimeout(this.timer);
        this.timer = setTimeout(function(event, self){
          if (self.drag) {
            // make sure height [150,screen-300] and width is [300,screen-50]
            var newValue;
            newValue = self.height + event.pageY - self.eventOffset.pageY;
            if (newValue <= screen.height - 300 && newValue >= 150) {
              self.tree.height = newValue;
            }
            newValue = self.width - event.pageX + self.eventOffset.pageX;
            if (newValue <= screen.width - 50 && newValue >= 300) {
              //self.tree.width = newValue;
              self.editBookmarkPanel.width = newValue;
            }
          }
        }, 10, event, this);
      },
      mouseup: function(event) {
        if (this.drag) {
          Services.prefs.setIntPref(this.PREFTREEHEIGHT, this.tree.height);
          Services.prefs.setIntPref(this.PREFTREEWIDTH, this.editBookmarkPanel.boxObject.width);
        }
        this.drag = false;
      }
    }
    //window.addEventListener("load", openbookResizer, false);
    openbookResizer.init();
    
    /* Fenster schließen nach 6 Sekunden */
    
    (function() {
      if (window.StarUI) {
        const delay = 6;
        StarUI._autoCloseTimeout = delay * 1000;
      }
    })();
    Alles anzeigen
  • extra_config_menu.uc.js > ohne security.allow_unsafe_dangerous_privileged_evil_eval auf false

    • bege
    • 30. August 2026 um 19:54

    Mira_Belle Danke für die viele Arbeit. Ich fände es toll, wenn wir hier wieder eine Version für alle hätten.

    Mit Verweis auf meinen Beitrag #90 möchte ich nochmal anregen, für alle Menüpunkte im Skript eine Steuerung im Konfigurationsabschnitt anzulegen, wie ich es in meiner Version ergänzt habe. Das macht einmalig mehr Arbeit, macht das Skript aber für jeden nutzbar und übersichtlich.

    Mir fehlt noch der Parameter für den Dateimanager (in meiner Version vFMParam)

    und die Einstellungen für die CSS-Ordner, in meiner Version so

    JavaScript
      // Einbindung CSS-Ordner (0: nein, 1: ja, Chrome-Unterordner, 2: ja, anderer Pfad):
    cssOrdner: 0,
      // Wenn cssOrdner = 1 oder 2, hier entweder Chrome-Unterordner (z.B. 'CSS') oder andere vollständige Pfade (z.B. 'C:\\Dropbox\\Chrome\\Thunderbird\\CSS-Ordner\\css-dateien') entragen, sonst '':
      cssLocation1: 'CSS',
      cssLocation2: '',
      cssLocation3: '',
      //Anzeigenamen für die CSS-Ordner
      cssLocation1Name: 'CSS-Ordner',
      cssLocation2Name: 'CSS-Ordner2',
      cssLocation3Name: 'CSS-Ordner3',

    Edit: Wer den UserCSSLoader nutzt, braucht davon vieles nicht.

    Der Ordner für die Symbole sollte auch konfigurierbar sein, statt

    JavaScript
    /*     Zu beachten ist, dass die Grafiken sich im richtigen Ordner befinden müssen     */
    /*            %appdata%\Mozilla\Firefox\Profiles\"Profilname"\chrome\icons             */

    Ich nutze z.B. einen Ordner außerhalb der Profile, um von allen Profilen - einschließlich Thunderbird - auf einen einzigen Symbolordner zugreifen zu können.

  • UserCSSLoader (2025)

    • bege
    • 30. August 2026 um 19:19
    Zitat von 2002Andreas
    Zitat von seipe

    etwa 3-4 Sekunden später erst angezeigt.

    Nach Änderung von diesem Wert wird es hier gleich angezeigt:

    Gut, dass du das herausgefunden hast. Es kann sein, dass ich das erhöht habe, weil bei mir beim Start einiges an Skripten lädt und verschoben wird, sodass es u.a. darauf ankommt, dass einzelne Skripte nicht zu früh geladen werden.

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

    • bege
    • 26. August 2026 um 19:08
    Zitat von Mira_Belle

    einen ellenlangen Text, der nun verloren geagangen ist,
    weil der Browser einfach neu startete

    OT: Ich nutze dieses Addon, das mich schon x Mal gerettet hat.

  • UserCSSLoader (2025)

    • bege
    • 26. August 2026 um 19:01

    Ich hatte das gleiche Problem und habe herausgefunden, dass FF 153 bei aktivierten Einträgen nur noch checked setzt, nicht mehr checked="true", wie in dem Skript. Bei deaktivierten Einträgen entfernt FF 153 das Attribut checked und setzt nicht checked="false". Das hat mir noch andere CSS-Änderungen zerschossen.

    Da die Einträge des Skripts also immer das Attribut checked enthalten, behält FF 153 die Haken bei, vorausgesetzt man hat keine anderen Änderungen vorgenommen. Es ist also ein reines Anzeigeproblem, die (De-)Aktivierung durch das Skript funktioniert weiter.

    Ich habe meine Version des Skripts mit Hilfe von KI so geändert, dass jetzt das Attribut entsprechend FF 153 gesetzt wird und damit die Haken wieder richtig angezeigt werden.

    JavaScript: userCSSLoader_2026-08-21.us.js
    /* UserCSSLoader 2026-08-21
     *
     * original author: Griever -
     * https://github.com/Griever/userChromeJS/tree/master/UserCSSLoader
     *
     * Enhancements and several other changes including German translation
     * and configuration section by users aborix, Endor, bege, Speravir of
     * Camp Firefox forum - https://www.camp-firefox.de/forum/ - latest version:
     * https://www.camp-firefox.de/forum/thema/138814/?postID=1279211#post1279211
     * 2026-08-21 angepasst an Firefox 153esr mit Hilfe von KI:
     *   Firefox setzt nicht mehr "checked=true" und "checked=false" wie dieses Skript,
     *    sondern nur noch "checked" oder keine Attribut. Dadurch bekamen auch Menüeinträge
     *    mit "checked=false" ein Checkmark, weil auch hier "checked" enthalten war.
     *    Jetzt setzt das Skript "checked=true" bzw. entfernt das Attribut.
     */
    
    /****** Bedienungsanleitung ******
    
    CSS-Ordner im Chrome-Ordner erstellen, CSS-Dateien dort ablegen - speichern.
    Diejenigen, deren Dateiname mit "xul-" beginnen, diejenigen, die mit ".as.css"
    enden, sind AGENT_SHEET, alle anderen außer USER_SHEET werden gelesen. Da der
    Inhalt der Datei nicht überprüft wird, darauf achten, die Angabe von @namespace
    nicht zu vergessen!
    
    Schaltfläche oder Menü wird in Navigationsleiste eingefügt (einstellbar, siehe
    Variable "position" in unten anschließender Konfiguration).
    
    Dateiordner, Dateimanager und Texteditor können in der unten anschließenden
    Konfiguration geändert werden. Die Verwendung des in "view_source.editor.path"
    angegebenen Editors ist möglich.
    
    Linksklick auf Stil, zum Aktivieren/Deaktivieren
    Mittelklick auf Stil zum Aktivieren/Deaktivieren, ohne Menü zu schließen
    Rechtsklick auf Stil zum Öffnen im Editor
    Strg+Linksklick zum Anzeigen im Dateimanager
    
    Die Tastenkombinationen können im Menü eingeblendet werden, dazu nach 
    "acceltext" suchen und den Zeilenkommentar "//" entfernen.
    
    Ein Symbol für die Schaltfläche muss in der "userChrome.css" festgelegt werden,
    Pfad zum Bild (PNG nur als Beispiel):
    * relativ zur userChrome.css
        background-image: url("Relativer/Pfad/zum/CSS_Symbol.png");
    * eine absolute Pfadangabe zum Symbol muss mit File-Protokoll-Präfix erfolgen:
        background-image: url("file:///Absoluter/Pfad/zum/CSS_Symbol.png");
    
    Absolute Zahlenwerte müssen eventuell etwas an die eigenen Gegebenheiten
    angepasst werden (größeres Symbol, anderer Rand); der Zahlenwert für Höhe
    und Breite des Menütextes ("CSS") sollte nicht größer sein als für das
    Symbol (hier 16px).
    
    #usercssloader-menu-item {
    	background-image: url("Relativer/Pfad/zum/CSS_Symbol.png");
    	background-position: center;
    	background-repeat: no-repeat;
    	background-size: 16px;
    	border-radius: var(--toolbarbutton-border-radius);
    	margin-block: 3px;
    
    	&:hover {
    		background-color: var(--toolbarbutton-hover-background);
    	}
    
    	& #usercssloader-menu > .menu-text[value="CSS"] {
    		opacity: 0;
    		width: calc(2 * var(--toolbarbutton-inner-padding) + 16px);
    		height: calc(2 * var(--toolbarbutton-inner-padding) + 16px);
    	}
    }
    
    **** Ende der Anleitung ****/
    
    (function(){
    	setTimeout(async function () {
    
    /***** Konfiguration *****/
    /* Position: als frei verschiebbare-Schaltfläche = 0, als Menü anzeigen = 1 */
    let position = 0;//1
    /* Dateimanager festlegen, Beispiele:
     *    let fileManager = "C:\\Programme\\FreeCommanderXE\\FreeCommander.exe";
     *    let fileManager = "C:\\Programme\\totalcmd\\TOTALCMD.EXE";
     * auch möglich (Achtung, nur mit fileManagerParam = "/select,"!):
     *    let fileManager = "C:\\Windows\\explorer.exe";
     * Bleibt Parameter leer, wird Standardmanager des Systems ohne Parameter
     * verwendet mit leicht eingeschränkter Funktionalität. */
    let fileManager = "C:\\Program Files\\FreeCommander XE\\FreeCommander.exe";
    /* eventuelle Parameter für den Dateimanager, Beispiele:
     *    let fileManagerParam = "/T";//FreeCommander oder Totalcommander
     *    let fileManagerParam = "/select,";//Windows Explorer, mit Komma korrekt!
     */
    let fileManagerParam = "/T";
    /* manche Manager benötigen den Parameter nach der Pfadangabe,
       dann "fileManagerParamPost" auf true setzen */
    let fileManagerParamPost = false;
    /* eigener Texteditor mit Pfad - Standard leer, dann wird Wert aus
     * Einstellung "view_source.editor.path" verwendet mit Warnmeldung,
     * wenn auch dieser leer ist, Beispiel:
     *    let customEditor = "C:\\Windows\\System32\\notepad.exe"; */
    let customEditor = "";
    /* Unterordner für die CSS-Dateien */
    let cssFolder = "CSS";
    /* Menüeintrag zum Bearbeiten der userChrome.css anzeigen (true)
       oder verstecken (false) */
    let showUserChromeCSS = true;
    /* Menüeintrag zum Bearbeiten der userContent.css anzeigen (true)
       oder verstecken (false) */
    let showUserContentCSS = true;
    /* zusätzlich Chrome-Ordner im Untermenü anzeigen (true)
       oder verstecken (false) */
    let showChrome = true;
    /***** Ende der Konfiguration *****/
    
    // Wenn beim Start ein weiteres Fenster (zweites Fenster) vorhanden ist, beenden
    let list = Services.wm.getEnumerator("navigator:browser");
    while(list.hasMoreElements()){ if(list.getNext() != window) return; }
    
    if (window.UCL) {
    	window.UCL.destroy();
    	delete window.UCL;
    }
    
    let menutooltip = "Linksklick: an/aus, Menü schließt\nMittelklick: an/aus, Menü bleibt offen\nRechtsklick: bearbeiten";
    if (fileManager !== "") {
    		menutooltip = menutooltip + "\nStrg+Rechtsklick: im Dateimanager anzeigen";
    }
    
    window.UCL = {
    	AGENT_SHEET : Ci.nsIStyleSheetService.AGENT_SHEET,
    	USER_SHEET  : Ci.nsIStyleSheetService.USER_SHEET,
    	AUTHOR_SHEET: Ci.nsIStyleSheetService.AUTHOR_SHEET,
    	readCSS: {},
    	get disabled_list() {
    		let obj = [];
    		try {
    			obj = decodeURIComponent(this.prefs.getCharPref("disabled_list")).split("|");
    		} catch(e) {}
    		delete this.disabled_list;
    		return this.disabled_list = obj;
    	},
    	get prefs() {
    		delete this.prefs;
    		return this.prefs = Services.prefs.getBranch("UserCSSLoader.");
    	},
    	get styleSheetServices() {
    		delete this.styleSheetServices;
    		return this.styleSheetServices = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
    	},
    	get FOLDER() {
    		let aFolder;
    		try {
    			// UserCSSLoader.FOLDER verwenden
    			let folderPath = this.prefs.getCharPref("FOLDER");
    			aFolder = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
    			aFolder.initWithPath(folderPath);
    		} catch (e) {
    			aFolder = Services.dirsvc.get("UChrm", Ci.nsIFile);
    			aFolder.appendRelativePath(cssFolder);
    		}
    		if (!aFolder.exists() || !aFolder.isDirectory()) {
    			aFolder.create(Ci.nsIFile.DIRECTORY_TYPE, 0o664);
    		}
    		delete this.FOLDER;
    		return this.FOLDER = aFolder;
    	},
    	get CHRMFOLDER() {
    			let cFolder;
    			try {
    					// UserCSSLoader.CHRMFOLDER verwenden
    					let CHRMfolderPath = this.prefs.getCharPref("CHRMFOLDER");
    					cFolder = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
    					cFolder.initWithPath(CHRMfolderPath);
    			} catch (e) {
    					cFolder = Services.dirsvc.get("UChrm", Ci.nsIFile);
    			}
    			if (!cFolder.exists() || !cFolder.isDirectory()) {
    					cFolder.create(Ci.nsIFile.DIRECTORY_TYPE, 0o664);
    			}
    			delete this.CHRMFOLDER;
    			return this.CHRMFOLDER = cFolder;
    	},
    
    	init: function() {
    		const cssmenu = $C("menu", {
    			id: "usercssloader-menu",
    			label: "CSS",
    			tooltiptext: "UserCSSLoader\n\nLinksklick: Stylesheets anzeigen\nMittelklick: Styles importieren",
    			accesskey: "Y"
    		});
    		cssmenu.addEventListener("click", (event) => { if (event.button === 1) UCL.rebuild(); });
    		const menupopup = $C("menupopup", {
    			id: "usercssloader-menupopup"
    		});
    		cssmenu.appendChild(menupopup);
    
    		let menu = $C("menu", {
    			label: "Style-Loader-Menü",
    			id: "style-loader-menu",
    			accesskey: "S",
    			//acceltext: "S"
    		});
    		menupopup.appendChild(menu);
    		menupopup.appendChild($C("menuseparator"));
    
    		let mp = $C("menupopup", { id: "usercssloader-submenupopup" });
    		menu.appendChild(mp);
    		let rebuildItem = $C("menuitem", {
    			label: "Styles importieren",
    			accesskey: "I",
    			//acceltext: "I"
    		});
    		rebuildItem.addEventListener("command", () => UCL.rebuild());
    		mp.appendChild(rebuildItem);
    		mp.appendChild($C("menuseparator"));
    		//
    		let createCSS = $C("menuitem", {
    			label: "CSS-Datei erstellen",
    			accesskey: "D",
    			//acceltext: "D"
    		});
    		createCSS.addEventListener("command", () => UCL.create());
    		mp.appendChild(createCSS);
    		let openFolder = $C("menuitem", {
    			label: "CSS-Ordner öffnen",
    			accesskey: "O",
    			//acceltext: "O"
    		});
    		openFolder.addEventListener("command", () => UCL.openCSSFolder());
    		mp.appendChild(openFolder);
    		if (showChrome) {
    				let openChromeFolder = $C("menuitem", {
    					label: "Chrome-Ordner öffnen",
    					accesskey: "X",
    					//acceltext: "X"
    				});
    				openChromeFolder.addEventListener("command", () => UCL.openCHRMFolder());
    				mp.appendChild(openChromeFolder);
    		}
    		if (showUserChromeCSS || showUserContentCSS)// wenigstens eine der beiden Variablen muss …
    				mp.appendChild($C('menuseparator'));// … true sein, damit Trennlinie angezeigt wird
    		if (showUserChromeCSS) {
    				let editChromeItem = $C("menuitem", {
    					label: "userChrome.css bearbeiten"
    				});
    				editChromeItem.addEventListener("command", () => UCL.editUserCSS("userChrome.css"));
    				mp.appendChild(editChromeItem);
    		}
    		if (showUserContentCSS) {
    				let editContentItem = $C("menuitem", {
    					label: "userContent.css bearbeiten"
    				});
    				editContentItem.addEventListener("command", () => UCL.editUserCSS("userContent.css"));
    				mp.appendChild(editContentItem);
    		}
    
    		CustomizableUI.createWidget({
    			id: 'usercssloader-menu-item',
    			type: 'custom',
    			defaultArea: CustomizableUI.AREA_NAVBAR,
    			onBuild: function(aDocument) {
    				let toolbaritem = aDocument.createXULElement('toolbaritem');
    				toolbaritem.id = 'usercssloader-menu-item';
    				toolbaritem.className = 'chromeclass-toolbar-additional';
    				return toolbaritem;
    			}
    		});
    		$('usercssloader-menu-item').appendChild(cssmenu);
    
    		if (position === 1) {
    				let refNode = $('helpMenu');
    				refNode.parentNode.insertBefore(cssmenu, refNode.nextSibling);
    		}
    
    		// Stile neu laden, ohne Menü zu öffnen
    		let key = $C("key", {
    			id: "usercssloader-rebuild-key",
    			key: "R",
    			modifiers: "alt",
    		});
    		key.addEventListener("command", () => UCL.rebuild());
    		$("mainKeyset").appendChild(key);
    
    		this.rebuild();
    		this.initialized = true;
    		window.addEventListener("unload", this, false);
    	},
    	uninit: function() {
    		const dis = [];
    		for (let x of Object.keys(this.readCSS)) {
    			if (!this.readCSS[x].enabled)
    				dis.push(x);
    		}
    		this.prefs.setCharPref("disabled_list", encodeURIComponent(dis.join("|")));
    		window.removeEventListener("unload", this, false);
    	},
    	destroy: function() {
    		var i = document.getElementById("usercssloader-menu");
    		if (i) i.parentNode.removeChild(i);
    		var i = document.getElementById("usercssloader-rebuild-key");
    		if (i) i.parentNode.removeChild(i);
    		this.uninit();
    	},
    	handleEvent: function(event) {
    		switch(event.type){
    			case "unload": this.uninit(); break;
    		}
    	},
    	rebuild: function() {
    		let ext = /\.css$/i;
    		let not = /\.uc\.css/i;
    		let files = this.FOLDER.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);
    
    		while (files.hasMoreElements()) {
    			let file = files.getNext().QueryInterface(Ci.nsIFile);
    			if (!ext.test(file.leafName) || not.test(file.leafName)) continue;
    			let CSS = this.loadCSS(file);
    			CSS.flag = true;
    		}
    		for (let leafName of Object.keys(this.readCSS)) {
    			const CSS = this.readCSS[leafName];
    			if (!CSS.flag) {
    				CSS.enabled = false;
    				delete this.readCSS[leafName];
    			}
    			delete CSS.flag;
    			this.rebuildMenu(leafName);
    		}
    		if (this.initialized) {
    			if (typeof(StatusPanel) !== "undefined")
    				StatusPanel._label = "Styles importiert";
    			else
    				XULBrowserWindow.statusTextField.label = "Styles importiert";
    		}
    	},
    	loadCSS: function(aFile) {
    		let CSS = this.readCSS[aFile.leafName];
    		if (!CSS) {
    			CSS = this.readCSS[aFile.leafName] = new CSSEntry(aFile);
    			if (this.disabled_list.indexOf(CSS.leafName) === -1) {
    				CSS.enabled = true;
    			}
    		} else if (CSS.enabled) {
    			CSS.enabled = true;
    		}
    		return CSS;
    	},
    	rebuildMenu: function(aLeafName) {
    		let CSS = this.readCSS[aLeafName];
    		let menuitem = document.getElementById("usercssloader-" + aLeafName);
    		if (!CSS) {
    			if (menuitem)
    				menuitem.parentNode.removeChild(menuitem);
    			return;
    		}
    
    		if (!menuitem) {
    			menuitem = $C("menuitem", {
    				label: aLeafName,
    				id: "usercssloader-" + aLeafName,
    				class: "usercssloader-item " + (CSS.SHEET == this.AGENT_SHEET? "AGENT_SHEET" : CSS.SHEET == this.AUTHOR_SHEET? "AUTHOR_SHEET": "USER_SHEET"),
    				type: "checkbox",
    				autocheck: "false",
    				tooltiptext: menutooltip
    			});
    			menuitem.addEventListener("command", () => UCL.toggle(aLeafName));
    			menuitem.addEventListener("click", (event) => UCL.itemClick(event));
    			menuitem.addEventListener("mouseup", (event) => { if (event.button === 1) event.preventDefault(); });
    			document.getElementById("usercssloader-menupopup").appendChild(menuitem);
    		}
    		if (CSS.enabled) {
    		menuitem.setAttribute("checked", "true");
    		} else {
    		menuitem.removeAttribute("checked");
    	}
    	},
    	toggle: function(aLeafName) {
    		let CSS = this.readCSS[aLeafName];
    		if (!CSS || event.ctrlKey) return;
    		CSS.enabled = !CSS.enabled;
    		this.rebuildMenu(aLeafName);
    	},
    	itemClick: function(event) {
    		let label = event.currentTarget.getAttribute("label");
    		event.preventDefault();
    		event.stopPropagation();
    		if (event.button === 0) {
    				return;
    		} else if (event.button === 1) {
    				this.toggle(label);
    		} else if (event.button === 2) {
    				if (event.ctrlKey && fileManager  !== "") {
    						UCL.showFile(label);
    				} else {
    				closeMenus(event.target);
    				this.edit(this.getFileFromLeafName(label));
    				}
    		}
    	},
    	getFileFromLeafName: function(aLeafName) {
    		let f = this.FOLDER.clone();
    		f.QueryInterface(Ci.nsIFile); // use appendRelativePath
    		f.appendRelativePath(aLeafName);
    		return f;
    	},
    	showFile: function(fname) {
    				const PathSep = AppConstants.platform === "win" ? "\\" : "/";
    				let target= this.FOLDER.path + PathSep + fname;
    				let file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
    				let process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess);
    				let args = (!fileManagerParamPost) ? [fileManagerParam,target] :
    				           [target,fileManagerParam];
    				file.initWithPath(fileManager);
    				process.init(file);
    				// Verzeichnis mit anderem Dateimanager öffnen
    				process.run(false, args, args.length);
    	},
    	openCSSFolder:function(){
    		if (fileManager !== "" && fileManagerParam !== "/select,") {
    				let target = this.FOLDER.path;
    				let file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
    				let process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess);
    				let args = (!fileManagerParamPost) ? [fileManagerParam,target] :
    				           [target,fileManagerParam];
    				file.initWithPath(fileManager);
    				process.init(file);
    				// Verzeichnis mit anderem Dateimanager öffnen
    				process.run(false, args, args.length);
    		} else {
    				// Verzeichnis mit Dateimanager des Systems öffnen
    				this.FOLDER.launch();
    		}
    	},
    	openCHRMFolder:function(){
    		if (fileManager !== "" && fileManagerParam !== "/select,") {
    				let target = this.CHRMFOLDER.path;
    				let file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
    				let process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess);
    				let args = (!fileManagerParamPost) ? [fileManagerParam,target] :
    				           [target,fileManagerParam];
    				file.initWithPath(fileManager);
    				process.init(file);
    				// Verzeichnis mit anderem Dateimanager öffnen
    				process.run(false, args, args.length);
    		} else {
    				// Verzeichnis mit Dateimanager des Systems öffnen
    				this.CHRMFOLDER.launch();
    		}
    	},
    	editUserCSS: function(aLeafName) {
    		let file = Services.dirsvc.get("UChrm", Ci.nsIFile);
    		file.appendRelativePath(aLeafName);
    		this.edit(file);
    	},
    	edit: function(aFile) {
    		let editor = (customEditor !== "") ? customEditor : Services.prefs.getCharPref("view_source.editor.path");
    		if (!editor) return alert('In der Konfiguration einen Texteditor festlegen ("customEditor") oder\n unter about:config im vorhandenen Schalter "view_source.editor.path"\n den vollständigen Editorpfad eintragen.');
    		try {
    			let UI = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
    			UI.charset = window.navigator.platform.toLowerCase().indexOf("win") >= 0? "Shift_JIS": "UTF-8";
    			let path = UI.ConvertFromUnicode(aFile.path);
    			let app = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
    			app.initWithPath(editor);
    			let process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
    			process.init(app);
    			process.run(false, [path], 1);
    		} catch (e) {}
    	},
    	create: function(aLeafName) {
    		if (!aLeafName) aLeafName = prompt("Name des Styles", dateFormat(new Date(), "%Y_%m%d_%H%M%S"));
    		if (aLeafName) aLeafName = aLeafName.replace(/\s+/g, " ").replace(/[\\/:*?\"<>|]/g, "");
    		if (!aLeafName || !/\S/.test(aLeafName)) return;
    		if (!/\.css$/.test(aLeafName)) aLeafName += ".css";
    		let file = this.getFileFromLeafName(aLeafName);
    		this.edit(file);
    	},
    	UCrebuild: function() {
    		let re = /^file:.*\.uc\.css(?:\?\d+)?$/i;
    		let query = "?" + new Date().getTime();
    		Array.slice(document.styleSheets).forEach(function(css){
    			if (!re.test(css.href)) return;
    			if (css.ownerNode) {
    				css.ownerNode.parentNode.removeChild(css.ownerNode);
    			}
    			let pi = document.createProcessingInstruction('xml-stylesheet','type="text/css" href="'+ css.href.replace(/\?.*/, '') + query +'"');
    			document.insertBefore(pi, document.documentElement);
    		});
    		UCL.UCcreateMenuitem();
    	},
    	UCcreateMenuitem: function() {
    		let sep = $("usercssloader-ucseparator");
    		let popup = sep.parentNode;
    		if (sep.nextSibling) {
    			let range = document.createRange();
    			range.setStartAfter(sep);
    			range.setEndAfter(popup.lastChild);
    			range.deleteContents();
    			range.detach();
    		}
    
    		let re = /^file:.*\.uc\.css(?:\?\d+)?$/i;
    		Array.slice(document.styleSheets).forEach(function(css) {
    			if (!re.test(css.href)) return;
    			let fileURL = decodeURIComponent(css.href).split("?")[0];
    			let aLeafName = fileURL.split("/").pop();
    			let m = $C("menuitem", {
    				label: aLeafName,
    				tooltiptext: fileURL,
    				id: "usercssloader-" + aLeafName,
    				type: "checkbox",
    				autocheck: "false",
    				checked: "true",
    			});
    			m.css = css;
    			m.addEventListener("command", function() {
    	if (!event.ctrlKey) {
    		this.css.disabled = !this.css.disabled;
    		if (!this.css.disabled) {
    			this.setAttribute("checked", "true");
    		} else {
    			this.removeAttribute("checked");
    		}
    	}
    });
    			m.addEventListener("mouseup", function(event) {
    				if (event.button === 1) event.preventDefault();
    			});
    			m.addEventListener("click", function(event) {
    				UCL.UCItemClick(event);
    			});
    			popup.appendChild(m);
    		});
    	},
    	UCItemClick: function(event) {
    		if (event.button === 0) return;
    		event.preventDefault();
    		event.stopPropagation();
    
    		if (event.button === 1) {
    			event.target.doCommand();
    		}
    		else if (event.button === 2) {
    			closeMenus(event.target);
    			let fileURL = event.currentTarget.getAttribute("tooltiptext");
    			let file = Services.io.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler).getFileFromURLSpec(fileURL);
    			this.edit(file);
    		}
    	},
    };
    
    function CSSEntry(aFile) {
    	this.path = aFile.path;
    	this.leafName = aFile.leafName;
    	this.lastModifiedTime = 1;
    	this.SHEET = /^xul-|\.as\.css$/i.test(this.leafName) ?
    		Ci.nsIStyleSheetService.AGENT_SHEET:
    		/\.author\.css$/i.test(this.leafName)?
    			Ci.nsIStyleSheetService.AUTHOR_SHEET:
    			Ci.nsIStyleSheetService.USER_SHEET;
    }
    CSSEntry.prototype = {
    	sss: Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService),
    	_enabled: false,
    	get enabled() {
    		return this._enabled;
    	},
    	set enabled(isEnable) {
    		let aFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile)
    		aFile.initWithPath(this.path);
    
    		let isExists = aFile.exists(); // true, wenn die Datei bereits existiert
    		let lastModifiedTime = isExists ? aFile.lastModifiedTime : 0;
    		let isForced = this.lastModifiedTime != lastModifiedTime; //true, wenn es eine Änderung in der Datei gibt
    
    		let fileURL = Services.io.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler).getURLSpecFromActualFile(aFile);
    		let uri = Services.io.newURI(fileURL, null, null);
    
    		if (this.sss.sheetRegistered(uri, this.SHEET)) {
    			// Wenn diese Datei bereits gelesen wurde
    			if (!isEnable || !isExists) {
    				this.sss.unregisterSheet(uri, this.SHEET);
    			}
    			else if (isForced) {
    				// Nach Stornierung erneut einlesen
    				this.sss.unregisterSheet(uri, this.SHEET);
    				this.sss.loadAndRegisterSheet(uri, this.SHEET);
    			}
    		} else {
    			// Datei wurde nicht gelesen
    			if (isEnable && isExists) {
    				this.sss.loadAndRegisterSheet(uri, this.SHEET);
    			}
    		}
    		if (this.lastModifiedTime !== 1 && isEnable && isForced) {
    			log(this.leafName + " wurde aktualisiert");
    		}
    		this.lastModifiedTime = lastModifiedTime;
    		return this._enabled = isEnable;
    	},
    };
    
    UCL.init();
    
    function $(id) { return document.getElementById(id); }
    function $A(arr) { return Array.slice(arr); }
    function $C(name, attr) {
    	const el = document.createXULElement(name);
    	if (attr) Object.keys(attr).forEach(function(n) { el.setAttribute(n, attr[n]) });
    	return el;
    }
    function dateFormat(date, format) {
    	format = format.replace("%Y", ("000" + date.getFullYear()).substr(-4));
    	format = format.replace("%m", ("0" + (date.getMonth()+1)).substr(-2));
    	format = format.replace("%d", ("0" + date.getDate()).substr(-2));
    	format = format.replace("%H", ("0" + date.getHours()).substr(-2));
    	format = format.replace("%M", ("0" + date.getMinutes()).substr(-2));
    	format = format.replace("%S", ("0" + date.getSeconds()).substr(-2));
    	return format;
    }
    
    function log(mes) { console.log(mes); }
    	}, 3000); 
    })();
    Alles anzeigen
  • extra_config_menu.uc.js > ohne security.allow_unsafe_dangerous_privileged_evil_eval auf false

    • bege
    • 25. August 2026 um 20:44

    Mira_Belle Unten ist meine bisherige, unveränderte Version, die auch im FF 154 funktioniert. Die Symbole für Button und Menü habe ich jetzt nicht getestet, weil ich das Menü zusammen mit anderen Skripten und Menüs ins App-Menü verschiebe und dafür die Symbol mit einem eigenen CSS anpassen muss. Ansonsten ist es mir lieber, wenn die Symbole im Skript enthalten sind und nicht mit einem separaten CSS hinzugefügt werden müssen. Das wird für mich leicht unübersichtlich. (Ich habe ein anderes Symbol, weil ich das Skript hauptsächlich für das Untermenü mit den Skripten verwende, die meisten anderen Menüs sind bei mir ausgeblendet.)

    Alle Einstellungen, was angezeigt wird und was nicht, finden im Konfigurationsabschnitt am Anfang statt. Zusätzlich etwas per CSS auszublenden ist für mich unübersichtlich.
    In den Erläuterungen für die Konfiguration habe ich vermieden, Zeilennummern anzugeben (passt bei dir z.B. in Zeile 21 nicht), weil die sich mit jeder Änderung verschieben. Stattdessen so etwas wie "im Folgenden ...".

    Was hier, glaube ich, schon diskutiert wurde, ist, ob userChromeShadow.uc.js aufgelistet werden soll. Ich nutze das bisher nicht, es würde mich aber stören, wenn ich nicht alle Skripte angezeigt bekomme, die geladen werden. Deshalb würde ich das die Nutzer auch in der Konfiguration steuern lassen, anstatt es "hart zu verdrahten".

    Wesentliche Ergänzungen in meiner Version sind

    • Parameter für den Dateimanager (Zeile 23 - 25)
    • konfigurierbarer Skripte-Unterordner (Zeilen 26 - 28)
    • Einstellung, in welchem Menü, falls als Menü angezeigt (Zeilen 31 - 33)
    • umfangreichere Einstellungen für CSS-Ordner (war mal von einem Nutzer hier im Forum angefragt) (Zeilen 38 - 47)

    Beim Überfliegen deiner Version war ich mir nicht sicher, ob alle menuseparator in die if-Abfragen eingebunden sind, sodass sie jeweils nur angezeigt werden, wenn der jeweilige Menüpunkt auch angezeigt wird.

    Mit etwas mehr Muße schaue ich mir deine Version genauer an.

    JavaScript: extras_config_menu-Fx135.uc.js
    // ==UserScript==
    // @name           extras_config_menu.uc.js
    // @compatibility  Firefox 135*.*
    // @include        main
    // @version        1.0.20250112
    // @edit           @aborix 7/21 CSS Dateien als Untermenü eingefügt 
    // @edit           @2002Andreas 8/21 Shadow CSS Dateien als Untermenü + Ordner eingefügt
    // @edit 	   @BrokenHeart	1/25 Anpass. wg. Änderung der Sicherheitsrichtlinien bei 'inlineEvents'
    // @edit           @bege, eigene Änderungen
    // ==/UserScript==
    
    var uProfMenu = {
      // Beginn der 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',
      // Falls gewuenscht, in der Zeile nach den Beispielen einen Dateimanager eintragen (komplett leer lassen fuer 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',
      // eventuelle Parameter für den alternativen Dateimanager, sonst vFilemanagerParam = "";
      //vFilemanagerParam = "/O /T";//Totalcommander, Freecommander
      vFMParam: "/T",
      // Falls die JavaScript-Scripte nicht im chrome-Verzeichnis, sondern einem Unterverzeichnis sind,
      // in der folgenden Zeile das Unterverzeichnis eintragen, sonst '':
      jsSubfolder: 'JS',
      // Im Folgenden bei "location" 'menu' eintragen, damit es in der Menueleiste erscheint, sonst '', damit es als Button erscheint:
      location: 'menu',
      // Für die Einstellung 'menu' wird hier der Ort festgelegt, wo das Menue angezeigt werden soll.
      // (0: in der Menueleiste, 1: im Extras-Menue)
      menuLocation: 0,  
      // Unter Linux sollte/kann versucht werden, die userChromeJS-Skripte zu sortieren, unter Windows ist das evtl. nicht noetig (die Sortierung wird Gross- und Kleinschreibung *nicht* beruecksichtigen - dazu wird die sort()-Funktion entsprechend mit einer Vergleichsfunktion aufgerufen)
      sortScripts: 0,   // 1 zum Erzwingen der Sortierung
      // Einbindung GM-Skripte-Ordner (0: nein, 1: Greasemonkey [Profil-Verzeichnis], 2: UserScriptLoader [Chrome-Verzeichnis], 3: Scriptish [Profil-Verzeichnis]):
      gmOrdner: 0,
      // Einbindung CSS-Ordner (0: nein, 1: ja, Chrome-Unterordner, 2: ja, anderer Pfad):
      cssOrdner: 0,
      // Wenn cssOrdner = 1 oder 2, hier entweder Chrome-Unterordner (z.B. 'CSS') oder andere vollständige Pfade (z.B. 'C:\\Dropbox\\Chrome\\Thunderbird\\CSS-Ordner\\css-dateien') entragen, sonst '':
      cssLocation1: 'CSS',
      cssLocation2: '',
      cssLocation3: '',
      //Anzeigenamen für die CSS-Ordner
      cssLocation1Name: 'CSS-Ordner',
      cssLocation2Name: 'CSS-Ordner2',
      cssLocation3Name: 'CSS-Ordner3',
      // In einer der folgenden Zeilen gueltige about:Adressen eintragen, die ebenfalls aufgerufen werden sollen.
      // - Zum Ausblenden: abouts: [],
      // - Damit die about:-Seiten nicht als Untermenue, sondern direkt als Menuepunkte aufgefuehrt werden, muss das erste Element '0' sein:
      // abouts: ['0','about:config','about:about','about:cache','about:certificate','about:checkerboard','about:crashes','about:debugging','about:devtools','about:memory','about:networking','about:performance','about:policies','about:profiles','about:serviceworkers','about:support','about:telemetry','about:url-classifier','about:webrtc'],
      // abouts: ['about:config','about:about','about:cache','about:certificate','about:checkerboard','about:crashes','about:debugging','about:devtools','about:memory','about:networking','about:performance','about:policies','about:profiles','about:serviceworkers','about:support','about:telemetry','about:url-classifier','about:webrtc'],
       abouts: [],
      // Einbindung config-Dateien wie user.js etc. (0: nein, 1: ja)
       configFiles: 0,
      // Die Firefox-Ordner anzeigen (0: nein, 1: ja):
       firefoxOrdner: 0,
      // Die normalen Firefox-Einstellungen auch zur Verfuegung stellen (0: nein, 1: ja):
      showNormalPrefs: 0,
      // Stellt "Skriptliste in Zwischenablage" zur Verfuegung (1: ja, 2: mit getrennter Nummerierung, 3: mit gemeinsamer Nummerierung) oder nicht (0):
      enableScriptsToClip: 3,
      // Den Eintrag "Neustart" anzeigen (0: nein, 1: ja):
      enableRestart: 0,
      
      // Ende der Konfiguration ---------------------------------------------------------------------------
    
      init: function() {
        if (this.location.toLowerCase() == 'menu') {
          // aufgrund des gewaehlten 'location' als Menue anlegen
          if (this.menuLocation) {
          var zielmenu = document.getElementById('menu_ToolsPopup');
          } else {
             var zielmenu = document.getElementById('main-menubar');
          }
        
          if (zielmenu==null) {
            userChrome.log("extras_config_menu.uc.js findet Zielmenue nicht, evtl. weil ein anderes Fenster als das Hauptfenster " +
                           "geoeffnet wurde. Falls dieser Fehler auch im Hauptfenster auftritt, bitte die vorgehende Definition " +
                           "von 'zielmenu' kontrollieren.");
           return
          }
          var menu = zielmenu.appendChild(this.createME("menu","Config-Menü",0,0,"ExtraConfigMenu"));
          //menu.setAttribute("class","menu-iconic");
          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');
            }
          });
         } else {
    		 
    	 // als verschiebbaren Button anlegen
          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"
            });
    		
          }
          var menu = document.getElementById("ExtraConfigMenu-button");
          menu.setAttribute("type", "menu");
    	  menu.addEventListener('click', function(event) {
    			if (event.button == 2 && !this.open) { 
    				openTrustedLinkIn("about:config", "tab");
    				event.preventDefault();
    			};
    	 },true);
         }
        var css = " \
          #ExtraConfigMenu-button { \
            list-style-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAC4gAAAuIAeWOKUkAAAEZSURBVDhP7ZMxLENRFIa/c2l5ESrFI+KpoUQTRoOYTJp0NBgsFpP5xSAxWNgkNlYJo72L3SIhMRiaaCxdRKIRkfQet+81FhUPsTnLvfnPzfefc3Ku6MW08oswrfPH8Q/4c8DohjKyFt+7AmVix5I/ULIlG4tfAfoXlb75eE+mDiGzIBgPctuG9HCkJ2tBOpTunPB4DrfrwvWS8lqTZioZQBvCQ9nirwqFU6Vn9n17kw+xEhqqu5a079o5MgwuR3NoD0j5sYO4tLbMmq61Y8NVUXipKAOlT1oINi0zZ8L4lsWbjB/3zlkKJ+KclSB0VYw5/S4if/yNKVdiECpeHp5vlOqe0HgSskXL0IrQmYH6JdzvO73eBvCtgDf14FTmcYgI3gAAAABJRU5ErkJggg==);  \
    		 margin-top: 0px !important; \);  \
    		 margin-top: 0px !important; \
    		 opacity: 1 !important;\
          } \
          #ExtraConfigMenu-button > dropmarker, #ExtraConfigMenu-button > hbox > .toolbarbutton-menu-dropmarker { \
            display: none !important; \
          } \
          #ExtraConfigMenu .menubar-text { \
            margin-inline-start: 0px !important;\
          }";
    
        //ab hier ist alles gleich, egal ob Button oder Menue
    
        var sss = Cc['@mozilla.org/content/style-sheet-service;1'].getService(Ci.nsIStyleSheetService);
        var uri = makeURI('data:text/css;charset=UTF=8,' + encodeURIComponent(css));
        sss.loadAndRegisterSheet(uri,sss.AGENT_SHEET);
    	menu.addEventListener('popupshowing', function(event) {
    			uProfMenu.getScripts(0);
    		//	uProfMenu.getCss(3);
    		//	uProfMenu.getCss(4);
    		//	uProfMenu.getCss(5);
    	 },true);
    	
        var menupopup = menu.appendChild(this.createME("menupopup",0,0,0,"ExtraConfigMenu-popup"));
        // Anlegen von Untermenues fuer userChromeJS-Skripte (befuellt werden sie spaeter)
        var submenu = menupopup.appendChild(this.createME("menu","uc.js",0,0,"submenu-ucjs"));
        var submenupopup = submenu.appendChild(this.createME("menupopup",0,0,0,"submenu-ucjs-items"));
        // var submenu = menupopup.appendChild(this.createME("menu","uc.xul",0,0,"submenu-ucxul"));
        // var submenupopup = submenu.appendChild(this.createME("menupopup",0,0,0,"submenu-ucxul-items"));
        menupopup.appendChild(this.createME("menuitem","uc.js-Datei erstellen","uProfMenu.createJSfile()","uProfMenu_createJSfile",0));
        if (this.enableScriptsToClip) menupopup.appendChild(this.createME("menuitem","Skriptliste in Zwischenablage","uProfMenu.getScripts(1)","uProfMenu_clipboard",0));
        // Ende Anlegen von Untermenues fuer die userChromeJS-Skripte
        if (this.configFiles)menupopup.appendChild(document.createXULElement('menuseparator'));
        // Einbindung von Konfigdateien
        if (this.configFiles) {
        menupopup.appendChild(this.createME("menuitem","userChrome.js","uProfMenu.edit(3,'userChrome.js');","uProfMenu_edit",0));
        menupopup.appendChild(this.createME("menuitem","userChrome.css","uProfMenu.edit(3,'userChrome.css');","uProfMenu_edit",0));
        menupopup.appendChild(this.createME("menuitem","userContent.css","uProfMenu.edit(3,'userContent.css');","uProfMenu_edit",0));
        menupopup.appendChild(this.createME("menuitem","prefs.js","uProfMenu.edit(1,'prefs.js');","uProfMenu_edit",0));
        menupopup.appendChild(this.createME("menuitem","user.js","uProfMenu.edit(1,'user.js');","uProfMenu_edit"),0);
        };
        // Ende Einbindung von Konfigdateien
        if (this.gmOrdner || this.cssOrdner) menupopup.appendChild(document.createXULElement('menuseparator'));
        // Einbindung von Ordnern
        switch (this.gmOrdner) {
          case 1:
            menupopup.appendChild(this.createME("menuitem","GM-Skripte","uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('ProfD')+uProfMenu.getDirSep()+'gm_scripts');","uProfMenu_folder"),0);
            break;
          case 2:
            menupopup.appendChild(this.createME("menuitem","USL-Skripte","uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm')+uProfMenu.getDirSep()+'UserScriptLoader');","uProfMenu_folder"),0);
            break;
          case 3:
            menupopup.appendChild(this.createME("menuitem","Scriptish-Skripte","uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('ProfD')+uProfMenu.getDirSep()+'scriptish_scripts');","uProfMenu_folder"),0);
            break;
        }
        
        if (this.cssOrdner) {
           if (this.cssOrdner == 1) {
          menupopup.appendChild(this.createME("menuitem",this.cssLocation1Name,"uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm')+uProfMenu.getDirSep()+uProfMenu.cssLocation1);","uProfMenu_folder"),0);
              if (this.cssLocation2.length>0) {
                 menupopup.appendChild(this.createME("menuitem",this.cssLocation2Name,"uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm')+uProfMenu.getDirSep()+uProfMenu.cssLocation2);","uProfMenu_folder"),0);
              };
              if (this.cssLocation3.length>0) {
                 menupopup.appendChild(this.createME("menuitem",this.cssLocation3Name,"uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm')+uProfMenu.getDirSep()+uProfMenu.cssLocation2);","uProfMenu_folder"),0);
              };
           } else {menupopup.appendChild(this.createME("menuitem",this.cssLocation1Name,"uProfMenu.dirOpen(uProfMenu.cssLocation1);","uProfMenu_folder"),0);
                if (this.cssLocation2.length>0) {
                menupopup.appendChild(this.createME("menuitem",this.cssLocation2Name,"uProfMenu.dirOpen(uProfMenu.cssLocation2);","uProfMenu_folder"),0);
                };
                if (this.cssLocation3.length>0) {
                menupopup.appendChild(this.createME("menuitem",this.cssLocation3Name,"uProfMenu.dirOpen(uProfMenu.cssLocation3);","uProfMenu_folder"),0);
                };
            }
        }
        
        if (this.firefoxOrdner) menupopup.appendChild(document.createXULElement('menuseparator'));
    
        if (this.firefoxOrdner) {
        menupopup.appendChild(this.createME("menuitem","Chromeordner","uProfMenu.prefDirOpen('UChrm');","uProfMenu_folder"),0);
        menupopup.appendChild(this.createME("menuitem","Profilordner","uProfMenu.prefDirOpen('ProfD');","uProfMenu_folder"),0);
     //   menupopup.appendChild(this.createME("menuitem","Icons-Ordner","uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm')+uProfMenu.getDirSep()+'Icons');","uProfMenu_folder"),0);
        menupopup.appendChild(this.createME("menuitem","Installationsordner","uProfMenu.prefDirOpen('CurProcD');","uProfMenu_folder"),0);
        menupopup.appendChild(this.createME("menuitem","Addonordner","uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('ProfD')+uProfMenu.getDirSep()+'extensions');","uProfMenu_folder"),0);
        menupopup.appendChild(this.createME("menuitem","Startup-Cacheordner","uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('ProfLD')+uProfMenu.getDirSep()+'startupCache');","uProfMenu_folder"),0);
      /*   menupopup.appendChild(this.createME("menuitem","Ordner about","uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm')+uProfMenu.getDirSep()+'about');","uProfMenu_folder"),0); */
        }
        // Ende Einbindung von Ordnern
        
        if (this.abouts.length>0 || this.showNormalPrefs) menupopup.appendChild(document.createXULElement('menuseparator'));
        
        // Einbindung von abouts
        if (this.abouts.length>0) {
          // falls der erste Eintrag des Arrays = '0' ist, dann kein Untermenue anlegen, sondern direkt als Menuepunkte einbinden
          if (this.abouts[0]=='0') {
            for (var i = 1; i < this.abouts.length; i++) {
            menupopup.appendChild(this.createME("menuitem",this.abouts[i],"openTrustedLinkIn('"+this.abouts[i]+"','tab')","uProfMenu_about"),0);
            }
           } else {
            // der erste Eintrag des arrays ist ungleich '0', deshalb als Untermenue einrichten
            var submenu = menupopup.appendChild(this.createME("menu","uc.js",0,0,"submenu-about"));
            var submenupopup = submenu.appendChild(this.createME("menupopup",0,0,0,"submenu-about-items"));
            this.fillMenu("submenu-about","submenu-about-items", "about:",this.abouts,"uProfMenu_about",1);
          }
        };
        // Ende Einbindung von abouts
        // Separator, falls dieser nicht schon durch abouts generiert wurde und weitere Menuepunkte folgen werden
       // if (this.abouts.length==0 && (this.showNormalPrefs || typeof(ToolRstartMod) != "undefined")) menupopup.appendChild(document.createXULElement('menuseparator'));
        // Falls gewuenscht (s. Konfigurationsabschnitt), Zugriff auf die normalen Einstellungen
        if (this.showNormalPrefs) menupopup.appendChild(this.createME("menuitem","Einstellungen","try{openOptionsDialog();}catch(e){openPreferences();}","uProfMenu_prefs"),0);
        
        if (this.enableRestart) menupopup.appendChild(document.createXULElement('menuseparator'));
    
        // Falls enableRestart = 1, Neustart-Menuepunkt zur Verfügung stellen
        if(this.enableRestart) menupopup.appendChild(this.createME("menuitem","Neustart",
        "Services.appinfo.invalidateCachesOnRestart(); Services.startup.quit(Ci.nsIAppStartup.eRestart | Ci.nsIAppStartup.eAttemptQuit,0);"));
        },
    
      getDirSep:function() {
        // Betriebssystem nach https://developer.mozilla.org/en/Code_snippets/Miscellaneous ermitteln
        var osString = Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULRuntime).OS;
        var dirsep = "/";
        switch(osString) {
          case "WINNT":
            dirsep = "\\";
            break;
          case "Linux":
            dirsep = "/";
            break;
          case "Darwin":
            dirsep = "/";
            break;
        }
        return dirsep;
      },
    
      edit:function(OpenMode,Filename){
        var Path = "";
        var dSep = this.getDirSep();  // die Trennzeichen zwischen Ordnern abhaengig vom Betriebssystem machen
        switch (OpenMode){
          //Current is Chrome Directory or Subfolder
          case 0:
            if (this.jsSubfolder.length != 0) {
            var Path = this.getPrefDirectoryPath("UChrm") + dSep + this.jsSubfolder + dSep + Filename;
            } else {
               var Path = this.getPrefDirectoryPath("UChrm") + dSep + Filename;
            }
            break;
          //Current is Profile Directory
          case 1:
            var Path = this.getPrefDirectoryPath("ProfD") + dSep + Filename;
            break;
          //Current is Root
          case 2:
            var Path = Filename;
            break;
          //Current is Chrome Directory
          case 3:
            var Path = this.getPrefDirectoryPath("UChrm") + dSep + Filename;
            break;
        }
        this.launch(this.TextOpenExe,Path);
      },
    
      dirOpen:function(Path){
        var dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
        if (this.vFileManager.length != 0) {
          var process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess);
          var args = [this.vFMParam,Path];
          dir.initWithPath(this.vFileManager);
          process.init(dir);
          // Verzeichnis mit anderem Dateimanager oeffnen
          process.run(false, args, args.length);
         } else {
          // Verzeichnis mit Dateimanager des Systems oeffnen
          dir.initWithPath(Path);
          dir.launch();
        }
      },
    
      prefDirOpen:function(prefDir){
        Path = this.getPrefDirectoryPath(prefDir);
        this.dirOpen(Path);
      },
    
      getPrefDirectoryPath:function(str){
        // get profile directory
        var file = Components.classes["@mozilla.org/file/directory_service;1"]
          .getService(Components.interfaces.nsIProperties)
          .get(str, Components.interfaces.nsIFile);
       // folgende 3 Zeilen nur für Firefox, nicht für Thunderbird
        if (str == 'CurProcD') {
          file = file.parent;
        };
        return file.path;
      },
    
      launch:function(RanPath,OpenPath){
        var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsIFile);
        var proc = Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess);
        var args = [OpenPath];
        file.initWithPath(RanPath);
        // falls der im Konfigurationsabschnitt definierte Editor nicht gefunden wird, auf Einstellung in about:config ausweichen:
        if (!file.exists()) {
          var pref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
          RanPath = pref.getCharPref("view_source.editor.path");
          file.initWithPath(RanPath);
        }
        proc.init(file);
        proc.run(false, args, args.length);
      },
    
      stringComparison:function(a, b){
        a = a.toLowerCase();
        a = a.replace(/ä/g,"a");
        a = a.replace(/ö/g,"o");
        a = a.replace(/ü/g,"u");
        a = a.replace(/ß/g,"s");
        b = b.toLowerCase();
        b = b.replace(/ä/g,"a");
        b = b.replace(/ö/g,"o");
        b = b.replace(/ü/g,"u");
        b = b.replace(/ß/g,"s");
        return(a==b)?0:(a>b)?1:-1;
      },
    
      getScripts:function(iType) {
        // Arrays (jeweils ein Array fuer uc.js und uc.xul) nehmen Namen der gefundenen Skripte auf
        let ucJsScripts = [];
        // let ucXulScripts = [];
        // 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/local;1'].createInstance(Ci.nsIFile);
        if (this.jsSubfolder.length != 0) {
           aFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path+uProfMenu.getDirSep()+this.jsSubfolder);
        } else {
            aFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path);
        };
        // files mit Eintraegen im Chrome-Ordner befuellen
        let files = aFolder.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);
        // Ordner bzw. files 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)) continue;
          // uc.js gefunden -> im Array ablegen
          if (extjs.test(file.leafName)) ucJsScripts.push(file.leafName);
          // uc.xul gefunden -> im Array ablegen
          // if (extxul.test(file.leafName)) ucXulScripts.push(file.leafName);
        }
        if (this.sortScripts) {
          ucJsScripts.sort(this.stringComparison);
          // ucXulScripts.sort(this.stringComparison);
        }
        // Aufruf der naechsten Methoden um die beiden Untermenues oder die Zwischenablage zu befuellen
        if (iType==0) {
          this.fillMenu("submenu-ucjs","submenu-ucjs-items", "uc.js",ucJsScripts,"uProfMenu_ucjs",0);
          // this.fillMenu("submenu-ucxul","submenu-ucxul-items", "uc.xul",ucXulScripts,"uProfMenu_ucxul",0);
         } else {
          var result = this.fillClipboardValue(ucJsScripts/*,ucXulScripts*/);
          Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper).copyString(result);
        }
      },
    
    /*  getCss:function(iType) {
        // Array nimmt Namen der gefundenen css-Dateien auf
        let cssFiles = [];
        // Suchmuster, also die Dateierweiterung css
        let extcss = /\.css$/i;
        let aFolder = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
        if (iType==3) {
          aFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path+this.getDirSep()+"CSS");
         } else if (iType==4) {
          aFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path+this.getDirSep()+"CSSWeb");
        }  else if (iType==5) {
          aFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path+this.getDirSep()+"CSSShadow");
        }
        // files mit Eintraegen im CSS- bzw. CSSWeb-Ordner befuellen
        let files = aFolder.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);
        // Ordner bzw. files durchlaufen und kontrollieren, ob gesuchte Dateien dabei sind
        while (files.hasMoreElements()) {
          let file = files.getNext().QueryInterface(Ci.nsIFile);
          // css gefunden -> im Array ablegen
          if (extcss.test(file.leafName)) cssFiles.push(file.leafName);
        }
        if (this.sortScripts) {
          cssFiles.sort(this.stringComparison);
        }
        // Untermenue befuellen
        if (iType==3) {
          this.fillMenu("submenu-css","submenu-css-items","Meine CSS-Dateien",cssFiles,"uProfMenu_css",3);
         } else if (iType==4) {
          this.fillMenu("submenu-cssweb","submenu-cssweb-items","Meine CSSWeb-Dateien",cssFiles,"uProfMenu_css",4);
        }  else if (iType==5) {
          this.fillMenu("submenu-CSSShadow","submenu-CSSShadow-items","Meine CSSShadow-Dateien",cssFiles,"uProfMenu_css",5);
        }
      },
    */
      fillMenu:function(whichsubmenu, whichsubmenuitems, strlabel, scriptArray,sClass,sTyp) {
        // Beschriftung des Untermenues mit Anzahl der gefundenen Dateien ergaenzen
        var e = document.getElementById(whichsubmenu);
        e.setAttribute('label',strlabel + ' (' + scriptArray.length + ')');
        var popup = document.getElementById(whichsubmenuitems);
        // zunaechst Untermenue zuruecksetzen
        while(popup.hasChildNodes()){
          popup.removeChild(popup.firstChild);
        }
        // Untermenue endlich befuellen
        for (var i = scriptArray.length-1; i > -1; i--) {
          // Typunterscheidung (userChromeJS-Skript oder about:)
          if (sTyp==0){
            var mitem = this.createME("menuitem",scriptArray[i],"uProfMenu.edit(0,'"+scriptArray[i]+"')",sClass,0);
    		mitem.addEventListener('click', function(event) {
    			uProfMenu.openAtGithub(event,'"+scriptArray[i]+"');
    			event.preventDefault();
    		},true);
    		
            mitem.setAttribute("tooltiptext"," Linksklick: Bearbeiten,\n Mittelklick: https://github.com/.../"+this.cleanFileName(scriptArray[i])+" oeffnen,\n Rechtsklick: Suche auf GitHub");
           } else if (sTyp==1){
            var mitem = this.createME("menuitem",scriptArray[i],"openTrustedLinkIn('"+scriptArray[i]+"','tab')",sClass,0);
           } /* else if (sTyp==3){
            var mitem = this.createME("menuitem",scriptArray[i],"uProfMenu.edit(3,'"+scriptArray[i]+"')",sClass,0);
           } else if (sTyp==4){
            var mitem = this.createME("menuitem",scriptArray[i],"uProfMenu.edit(4,'"+scriptArray[i]+"')",sClass,0);
          }
    	  else if (sTyp==5){
            var mitem = this.createME("menuitem",scriptArray[i],"uProfMenu.edit(5,'"+scriptArray[i]+"')",sClass,0);
          } */
          popup.insertBefore(mitem, popup.firstChild);
        }
      },
    
      fillClipboardValue:function(sArray/* ,xArray */) {
        var retValue;
        var s = 0;
        // var x = 0;
        s = sArray.length;
        // x = xArray.length;
        switch(this.enableScriptsToClip) {
          case 1:
            retValue = "userChromeJS/uc.js ("+s+"):\n------------------------\n"+sArray.join("\n"); // +
                       // "\n\nuserChromeJS/uc.xul ("+x+"):\n-------------------------\n"+xArray.join("\n");
            break;
          default:
            retValue = "userChromeJS/uc.js ("+s+"):\n------------------------";
            for (var i = 0; i < s ; i++) {
              j = i + 1;
              retValue = retValue + "\n" + j + ". " + sArray[i];
            }
     /*       retValue = retValue + "\n\nuserChromeJS/uc.xul ("+x+"):\n-------------------------";
            if (this.enableScriptsToClip==2) s = 0;
            for (var i = 0; i < x ; i++) {
              j = i + s + 1;
              retValue = retValue + "\n" + j + ". " + xArray[i];
            } */
            break;
        }
        return retValue;
      },
    
      createME:function(sTyp,sLabel,sCommand,sClass,sId) {
        // Anlegen von menuitem, menu oder menupop - fuer bestimmte Typen nicht eingesetzte Parameter werden als 0 uebergeben
        const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
        var m = document.createElementNS(XUL_NS, sTyp);
        switch (sTyp) {
          case "menuitem":
            // this.createME("menuitem","Label des Items","ZuzuweisenderCodeFueroncommand","GewuenschteKlasseDesItems",0)
            m.setAttribute('label', sLabel);
            m.setAttribute('class',sClass);
    		m.addEventListener('command', function(event) {
    			Function(sCommand)();
    		}, true);
    		
            break;
          case "menu":
            // this.createME("menu","Label des Menues",0,0,"GewuenschteIdDesMenues")
            m.setAttribute('label', sLabel);
            m.setAttribute('id', sId);
            break;
          case "menupopup":
            //this.createME("menupopup",0,0,0,"GewuenschteIdDesMenupopups");
            m.setAttribute('id', sId);
            break;
        }
        return m;
      },
    
      openAtGithub:function(e,sScript) {
        if (e.button==1){
          // Mittelklick - Seite auf GitHub oeffnen (funktioniert nur, wenn Ordner- und bereinigter Dateiname [ohne Erweiterung] uebereinstimmen):
          var sUrl = "https://github.com/Endor8/userChrome.js/tree/master/"+this.cleanFileName(sScript);
          openWebLinkIn(sUrl, 'tab');
        }
        if (e.button==2){
          // Rechtsklick - Suche auf GitHub starten (funktioniert nur, wenn der Dateiname im Code hinterlegt ist):
          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$/.test(Filename)) Filename += ".uc.js";
    		this.edit(0, Filename);
    	},
    
      cleanFileName:function(sName) {
        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 sName;
      }
    
    };
    
    uProfMenu.init();
    Alles anzeigen
  • extra_config_menu in Betterbird funktioniert nicht mehr

    • bege
    • 20. August 2026 um 22:08
    Seit Update auf Betterbird 153 funktioniert extra_config-menu nicht mehr - Thunderbird Mail DE
    Einzelne Einstellungen in extra_config_menu wie Einstellungen und das Icon für den Neustart (nicht sichtbar) im Datei-Orner nicht mehr.
    www.thunderbird-mail.de
  • extra_config_menu.uc.js > ohne security.allow_unsafe_dangerous_privileged_evil_eval auf false

    • bege
    • 17. August 2026 um 01:50
    Zitat von Endor

    Ist erledigt:

    https://github.com/Endor8/userChr…r/Firefox%20153

    In der Version fehlen viele Erläuterungen im Vergleich zur Version für FF 135, sowohl für die Konfiguration als auch innerhalb des Skripts zur Funktion einzelner Teile. (Einige sind aber zugefügt.) Ich wüsste nicht, wie ich die Konfiguration einstellen muss, noch, was die einzelnen Skriptteile tun, was künftige Änderungen erschwert. Ich habe allerdings inzwischen eine an einigen Stellen abweichende Version, die ich deshalb beibehalte.

    Es gibt einige Änderungen mit der Erklärung (ANGEPASST: sCommand als Funktion). Welchen Vorteil hat das gegenüber der vorherigen Version? In der wird das an nur einer Stelle in den Zeilen 429 - 430 gelöst.

    Der Wert helpMenu in Zeile 20 stammt wohl noch aus einer älteren Version, als es den verschiebbaren Button noch nicht gab. Das ist in der Erläuterung der Version für FF 135 falsch. Es gibt es nur noch den Wert menu als Menü im Extras Menü (menu_ToolsPopup in Zeile 35 fest eingestellt) und sonst z.B. leer für Button. Das Skript prüft nur noch auf menu. Wenn das dort nicht steht, egal ob leer oder irgend etwas anderes, wird ein Button erstellt.

Unterstütze uns!

Jährlich (2026)

75,5 %

75,5% (584,79 von 775 EUR)

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