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

Beiträge von Mira_Belle

  • Aufruf von Shadow Dateien / Skript-Vorstellung: ShadowCSSLoader.uc.js

    • Mira_Belle
    • 7. September 2026 um 17:17
    Zitat von FuchsFan

    Der Nachteil hierbei besteht darin, dass immer der vollständige lange Pfad zur CSS-Datei vorgegeben werden muss, was dann so aussieht @import url("file:///B:/Firefox Test/Nightly1/Profilordner/chrome/CSSShadow/Hamburger Menü Umrandung ohne border-radius.css");.

    Sorry, das stimmt so nicht ganz!
    Denn es kommt darauf an, wie die Ordnerstruktur im Ordner "chrome" ist.
    Liegt die
    userChromeShadow.css direkt im Ordner und existiert in diesem der Ordner CSSShadow,
    kann z.B. auch der Aufruf des Imports so aussehen:
    @import url("./CSSShadow/Hamburger Menü Umrandung ohne border-radius.css");

    Ich habe mich geirrt:!:
    FuchsFan hat absolut recht, in der userChromeShadow.css müssen,
    weil diese Datei eben nicht original vom Firefox stammt und anders "geladen" wird,
    Importaufrufe immer mit absoluten Pfaden angegeben werden!
    Also z.B. genau so => @import url("file:///B:/Firefox Test/Nightly1/Profilordner/chrome/CSSShadow/Hamburger Menü Umrandung ohne border-radius.css");.

  • 155.0.1 - angeheftete Tabs wieder ablösen?

    • Mira_Belle
    • 7. September 2026 um 09:44
    Zitat von .DeJaVu

    Warum muss man darüber diskutieren wollen?

    Ich wollte darüber gar nicht diskutieren:!:
    Mein Hinweis sollte nur dazu dienen, eventuell das nächste Mal etwas aussagekräftigere Erklärungen
    oder Screenshots mitzuliefern!

    Zu einer Diskussion wurde es doch erst, als ...

    Aber lassen wir das, es führt zu nichts. Ich ziehe meine Konsequenzen und gut is'.

  • 155.0.1 - angeheftete Tabs wieder ablösen?

    • Mira_Belle
    • 6. September 2026 um 21:12
    Zitat von Sören Hentzschel

    Die Situation steht direkt über dem Screenshot beschrieben und dass das im Firefox-Jargon „anheften” heißt, weiß man nicht unbedingt, wenn man das Feature nicht bewusst nutzt …

    Ok, ich bin blond und/oder begriffsstutzig!
    Mit dieser Beschreibung habe ich auch nicht auf angepinnte Tabs getippt.
    Und wie ich schon schrieb, eventuell einen geöffneten angepinnten Tab als Screenshot hätte alles schon anders aussehen lassen.

  • 155.0.1 - angeheftete Tabs wieder ablösen?

    • Mira_Belle
    • 6. September 2026 um 19:42
    Zitat von Son Goku

    sieht man doch das ein Tan voll angezeigt wird und die anderen beiden links daneben nur als klein ohne Text nur das Icon sichtbar

    Nur so mal am Rande!
    Nein kann ich nicht!
    Es ist mir nicht klar dass da insgesamt drei Tabs zu sehen sind.
    Ich erkenne da, irgendwie so eine kleine Schrift, könnte auch ein Button sein, der keinen Rahmen hat,
    einen weiteren Button mir Symbol und einen ganz normalen Tab.
    Da es hier bei Deiner Anfrage aber irgendwie um Tabs zu gehen schien,
    könnte man das wohl eher erraten, dass das angeheftete Tabs sind!

    Wenn ein solcher Tab aktiv gewesen wäre, wäre das Bild eventuell eindeutiger gewesen,
    oder eventuell wäre von Anfang an auch eine aussagekräftige Beschreibung nicht verkehrt gewesen.

    Von daher kann ich Webmarks Frage schon irgendwie verstehen!
    Aber natürlich freut es mich, das Andreas und Angel mit ihren Vermutungen richtig lagen
    und Dein Problem somit gelöst wurde.

  • Mehrzeilige Tableiste für aktuelle Firefox-Versionen

    • Mira_Belle
    • 6. September 2026 um 08:58

    Platos Ich nutze es selber nicht, habe es nur mal angetestet und beafand es eigentlich ganz gelungen.

    Zitat von Merci chao

    Version 4.11 wurde veröffentlicht.

    Dieses Update umfasst hauptsächlich kleinere Fehlerbehebungen, Code-Refaktorierung und Unterstützung für zukünftige Firefox-Versionen.

    Darüber hinaus wurden auf der GitHub-Seite zu jedem Konfigurationspunkt kurze Beschreibungen ergänzt, wodurch die Lesbarkeit verbessert wurde. Die Installationsschritte wurden ebenfalls aktualisiert und enthalten nun Anleitungen zur Installation verschiedener Script-Loader, die bei Bedarf herangezogen werden können.

    Um das Update sofort auszuführen, setzen Sie checkUpdate auf 1 zurück. Die Aktualisierungsprüfung wird dann sofort in einem neuen Fenster gestartet.

    Bei Problemen oder Fragen ist Rückmeldung willkommen.

    Vielen Dank.

    Download und Changelog: https://github.com/Merci-chao/userChrome.js#changelog
    Einführungsseite: https://merci-chao.github.io/userChrome.js/multitabrows/en
    GitHub-Seite: https://github.com/Merci-chao/userChrome.js

    Alles anzeigen
  • Sidebar - Symbol für Downloads

    • Mira_Belle
    • 5. September 2026 um 16:20
    Zitat von Sören Hentzschel

    Natürlich. Das hat mit dem Anliegen des Themenstarters schließlich überhaupt nichts zu tun.

    Ist ja gut, habe ich längst erledigt.
    Immer gleich Schelte verteilen, wo ich doch unschuldig bin :saint:

  • Sidebar als schwebende, hover-aktivierte Leiste

    • Mira_Belle
    • 5. September 2026 um 15:24

    Das Firefox-UserScript verwandelt die standardmäßige Sidebar in eine schwebende, hover-aktivierte Leiste mit folgenden Funktionen:

    • Dynamische Höhenanpassung an das Browser-Fenster (via ResizeObserver).
    • Persistente Sichtbarkeit, wenn ein Sidebar-Menü geöffnet ist (popupshowing-Event).
    • Manuelle Breitenanpassung per Drag & Drop (Resizer-Handle).
    • CSS-Animationen für sanftes Ein-/Ausblenden (mit transform: translateX).
    • Positionierung links oder rechts (über Attribute positionend/sidebar-positionend steuerbar).
    JavaScript
    // ==UserScript==
    // @name           sidebar_floating_hover.uc.js
    // @compatibility  Firefox 155*.*
    // @version        05.09.2026
    
    // ==/UserScript==
    
    /* ----------------------------------------------------------------------------------- */
    /*  IMPORTANT!         This script was edited and modified using AI.                   */
    /* ----------------------------------------------------------------------------------- */
    
    'use strict';
    
    const
      // ■■ START UserConfiguration ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
      handleSize    = '50px'      ,// Größe des Resizer-Handles
      transDelayOut = '0.25s'     ,// Verzögerung beim Ausblenden
      transDelayIn  = '1s'        ,// Verzögerung beim Einblenden
      resizerTop    = '200px'     ,// Position des Resizer-Handles (top)
      resizerHeight = '70%'       ;// Höhe des Resizer-Handles
      // ■■ END UserConfiguration ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
    
    
    (function() {
    
        if (location.href !== 'chrome://browser/content/browser.xhtml')
            return;
    
        // adjust height to browser window
        let brow_size = document.getElementById("browser");
        let observer = new ResizeObserver(() => {
        let rect = brow_size.getBoundingClientRect();
        document.getElementById('sidebar-box').style.setProperty('--height_sidebar', rect.height + 'px');
        });
        observer.observe(brow_size);
    
        let floater = document.getElementById('sidebar-box');
    
        // keep sidebar open when open popup is hovered
        window.addEventListener("popupshowing", (e) => {
            if (e.target.id === "sidebarMenu-popup" || e.target.getAttribute("viewid")?.startsWith("sidebar-")) {
              floater.classList.add("menu_up");
            }
            else {
              floater.classList.remove("menu_up");
            }
        });
    
        // resizer
        let resizer = document.createElement("div");
        resizer.id = "sidebar_resizer";
        floater.appendChild(resizer);
    
        let isResizing = false;
        let startX, startWidth;
        let isRight;
    
        resizer.addEventListener("mousedown", e => {
          isResizing = true;
          startX = e.clientX;
          startWidth = floater.getBoundingClientRect().width;
          isRight = floater.hasAttribute("positionend") || floater.hasAttribute("sidebar-positionend");
          e.preventDefault();
        });
    
        window.addEventListener("mousemove", e => {
          if (!isResizing) return;
    
          let delta;
          if (isRight) {
            delta = startX - e.clientX;
          } else {
            delta = e.clientX - startX;
          }
    
          let newWidth = startWidth + delta;
          floater.style.width = newWidth + "px";
        });
    
        window.addEventListener("mouseup", () => {
          isResizing = false;
        });
    
        let css =`
    
        #sidebar-box {
            --ug-handle_size: ${handleSize};
            --ug-trans_delay_out: ${transDelayOut};
            --ug-trans_delay_in: ${transDelayIn};
            position: fixed !important;
            /*max-width: unset !important;*/
            right: 0px;
            left: unset;
            bottom: 0px;
            height: var(--height_sidebar);
            z-index: 99999 !important;
            transform: translateX(0%);
            transition: transform 1.5s ease !important;
            transition-delay: var(--ug-trans_delay_out) !important;
        }
    
        #sidebar-box:not([positionend],[sidebar-positionend]) {
            right: unset;
            left: 0px;
        }
    
        /*  Resizer  */
    
        #sidebar_resizer {
            position: absolute;
            top: ${resizerTop};
            right: unset;
            left: calc(-1*var(--ug-handle_size));
            width: var(--ug-handle_size);
            height: ${resizerHeight};
            cursor: ew-resize;
          /*  background: hsla(35, 0%, 50%, 0.25); */
            outline: 2px solid hsla(35, 0%, 50%, 0.25);
          /*  outline: 2px solid lightblue; */
            outline-offset: -2px;
        }
    
        #sidebar-box:not([positionend],[sidebar-positionend])  #sidebar_resizer {
            right: calc(-1*var(--ug-handle_size));
            left: unset;
        }
    
        /*   hide   */
    
        #sidebar-box:not(:hover, .menu_up) {
            transform: translateX(100%);
            transition-delay: var(--ug-trans_delay_in) !important;
        }
    
        #sidebar-box:not([positionend],[sidebar-positionend]):not(:hover, .menu_up) {
            transform: translateX(-100%);
        }
    
        /*   stuff   */
        /*
        #sidebar,
        #sidebar-header {
          background-color: whitesmoke !important;
          border-inline: 1px solid grey;
          border-inline-width: 1px 0px;
        }
    
        #sidebar-box:not([positionend],[sidebar-positionend]) :is(#sidebar, #sidebar-header) {
          border-inline-width: 0px 1px;
        }
        */
        #sidebar-splitter {
            display: none !important;
        }
    
        `;
    
      const sss = Cc['@mozilla.org/content/style-sheet-service;1'].getService(Ci.nsIStyleSheetService);
      const uri = Services.io.newURI('data:text/css,' + encodeURIComponent(css));
      sss.loadAndRegisterSheet(uri, sss.AGENT_SHEET);
    
    })();
    Alles anzeigen

    Sorry, das Script ist schon alt und entspricht nicht mehr meinen heutigen Vorstellungen,
    aber es funktioniert immer noch, von daher stelle ich es mal hier zur Verfügung.

    Habe es überarbeitet und so gefällt es mir besser.

  • Sidebar - Symbol für Downloads

    • Mira_Belle
    • 5. September 2026 um 15:19
    Zitat von 2002Andreas

    Besser wäre es, dafür dann einen eigenen neuen Thread zu erstellen.

    Meinst Du?
    Hat ja nie jemand nach so etwas gefragt.
    Von daher wäre es doch völlig egal, wenn es hier untergeht.

  • Sidebar - Symbol für Downloads

    • Mira_Belle
    • 5. September 2026 um 15:12

    Ein kleines Bonbon!
    Hatte ich mir mal "entwickelt", weil mir Platz wichtig ist.

    Das Firefox-UserScript verwandelt die standardmäßige Sidebar in eine schwebende, hover-aktivierte Leiste mit folgenden Funktionen:

    • Dynamische Höhenanpassung an das Browser-Fenster (via ResizeObserver).
    • Persistente Sichtbarkeit, wenn ein Sidebar-Menü geöffnet ist (popupshowing-Event).
    • Manuelle Breitenanpassung per Drag & Drop (Resizer-Handle).
    • CSS-Animationen für sanftes Ein-/Ausblenden (mit transform: translateX).
    • Positionierung links oder rechts (über Attribute positionend/sidebar-positionend steuerbar).
  • Sidebar - Symbol für Downloads

    • Mira_Belle
    • 5. September 2026 um 14:31
    Zitat von Sören Hentzschel

    ..., was immer die bessere Lösung ist, ...

    Sicher?
    Man ist auf jeden Fall auf einen externen Entwickler angewiesen!
    Ich habe es schon erlebt, dass eine Erweiterung einfach nicht mehr weiter entwickelt wurde, und bäm,
    es kam der Tag, wo sie ihre Funktion einstellte.
    Oder auch schon passiert, eine Erweiterung. jahrelang kostenlos, plötzlich wollte der Entwickler Kohle!
    Verarscht kam ich mir vor, weil ich kurz vorher noch eine Spende überwiesen hatte.
    Bei einem Script, weiß ich mir zu helfen!
    Entweder bekomme ich Unterstützung auf diesem Board oder ich bekomme es mit mistal in den Griff.

    Zitat von 2002Andreas

    Den Dank reiche ich mal an die KI weiter

    Quatsch, Du bist doch der, der den richtigen Promt erstellt hat!!

  • Sidebar - Symbol für Downloads

    • Mira_Belle
    • 5. September 2026 um 13:56

    Es funktioniert hier auch bei mir!

    Und 2002Andreas Danke.

  • Sidebar - Symbol für Downloads

    • Mira_Belle
    • 5. September 2026 um 12:05

    2002Andreas Top! :thumbup:

    Verrate mir doch bitte Deine genaue Fragestellung,
    denn mit mistral habe ich mir einen abgebrochen und es kam nur Mist dabei raus!

  • Neue Quicklink-Button

    • Mira_Belle
    • 4. September 2026 um 15:53

    Update:!:

    Addons-UpDate-Check.uc.js

    und eine neues Script gibt es auch.

    BackupProfile.uc.js

  • Gemini – Website bleibt dunkel?

    • Mira_Belle
    • 3. September 2026 um 19:20

    Funktioniert hier trotz "I don't care about cookies":!:
    Und ich habe nichts irgendwie eingestellt.

  • BackupProfile.uc.js - div. Fragen dazu

    • Mira_Belle
    • 3. September 2026 um 17:35

    Bisher hatte ich ja das originale Script von #1 mit leichten Abwandlungen und Korrekturen genutzt!
    Mir persönlich gefällt, gefiel mir der Aufbau dieses Scripts nicht.
    Daher habe ich mir ein "Neues" gebaut!
    Grundsätzlich funktioniert es genau so, wie das Original,
    nur ist jetzt klarer ersichtlich, wo der Nutzer Hand anlegen kann!
    Aber was "labere ich, schaut selbst.

    JavaScript
    // ==UserScript==
    // @name           BackupProfile.uc.js
    // @description    Schaltfläche zum Sichern des Firefoxprofils
    // @charset        UTF-8
    // @author         Mira Bellenbaum
    // @version        v2026.09.03
    // @note           Sicherungsdatei enthaelt auch Profilname
    // ==UserScript==
    
    /* ----------------------------------------------------------------------------------- */
    /*     Zu beachten ist, dass die Grafiken sich im richtigen Ordner befinden müssen     */
    /*            %appdata%\Mozilla\Firefox\Profiles\"Profilname"\chrome\icons             */
    /* ----------------------------------------------------------------------------------- */
    
    /* ----------------------------------------------------------------------------------- */
    /*  IMPORTANT!         This script was edited and modified using AI.                   */
    /* ----------------------------------------------------------------------------------- */
    
    'use strict';
    
    (function() {
      if (location.href !== 'chrome://browser/content/browser.xhtml')
        return;
    
      const
      // ■■ START UserConfiguration ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
               id = 'backupProfile-button',          // ID des Buttons
            label = 'Profilsicherung',               // Bezeichnung des Buttons
      tooltiptext = 'Sichern der aktuellen Konfiguration',
             icon = 'backup.svg',                    // Name des SVG-Icons
           colour = '#faea00',                     // Farbe für das SVG-Icon
         iconPath = '/chrome/icons/',                // Pfad zum Icon-Ordner
         basePath = 'E:\\Firefox-Sicherung\\',       // Standard-Speicherpfad (leer lassen für Dialog)
       // Ausschlussliste (Dateien/Ordner, die nicht gesichert werden sollen)
       excludes = 'bookmarkbackups *cache* crashes fftmp *healthreport* minidumps safebrowsing *webapps* saved-telemetry-pings *thumbnails* *session* *Telemetry* *hotfix* *.sqlite-shm *.sqlite-wal *.bak parent.lock blocklist.xml content-prefs.sqlite directoryLinks.json mimeTypes.rdf compatibility.ini parent.lock formhistory.sqlite',
      // ■■ END UserConfiguration ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
    
      curProfDir = PathUtils.toFileURI(PathUtils.join(PathUtils.profileDir));
    
      // SVG-Unterstützung aktivieren (falls nicht bereits aktiv)
      if (Services.prefs.getBoolPref('svg.context-properties.content.enabled') == false) {
        Services.prefs.setBoolPref('svg.context-properties.content.enabled', true);
      }
    
      // ---- BUTTON ERSTELLEN ----
      try {
        CustomizableUI.createWidget({
          id: id,
          defaultArea: CustomizableUI.AREA_NAVBAR,
          label: label,
          tooltiptext: tooltiptext,
          onCreated: (button) => {
            button.style.MozContextProperties = 'fill, stroke, fill-opacity';
            button.style.listStyleImage = 'url("' + curProfDir + iconPath + icon + '")';
            button.style.minWidth = 'fit-content';
            button.style.color = colour;
          }
        });
      } catch(e) {}
    
      // ---- FUNKTIONEN ----
      // Benachrichtigung anzeigen
      function showAlert(aTitle, aString) {
        const AlertNotification = Components.Constructor(
          '@mozilla.org/alert-notification;1',
          'nsIAlertNotification',
          'initWithObject'
        );
        Cc['@mozilla.org/alerts-service;1'].getService(Ci.nsIAlertsService).showAlert(
          new AlertNotification({ title: aTitle, text: aString })
        );
      }
    
      // Backup durchführen
      function performBackup() {
        let path = basePath;
    
        // Falls kein Pfad angegeben, Dialog öffnen
        if (!path) {
          const nsIFilePicker = Ci.nsIFilePicker;
          const FP = Cc['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
          FP.init(window, 'Sicherungspfad wählen', nsIFilePicker.modeGetFolder);
    
          if (FP.show() !== nsIFilePicker.returnOK) {
            return;
          }
          path = FP.file.path;
        }
    
        // Ausschlussliste in Regex umwandeln
        const excludesRegex = new RegExp(
          excludes.replace(/\./g, '\\.').replace(/\*/g, '.*').replace(/\s+/g, '|'),
          'i'
        );
    
        // ZipWriter vorbereiten
        const zw = Cc['@mozilla.org/zipwriter;1'].createInstance(Ci.nsIZipWriter);
        const pr = {PR_RDONLY: 0x01, PR_WRONLY: 0x02, PR_RDWR: 0x04, PR_CREATE_FILE: 0x08, PR_APPEND: 0x10, PR_TRUNCATE: 0x20, PR_SYNC: 0x40, PR_EXCL: 0x80};
        const fu = ChromeUtils.importESModule('resource://gre/modules/FileUtils.sys.mjs').FileUtils;
        const dir = new FileUtils.File(PathUtils.join(PathUtils.profileDir, []));
    
        // Datum/Zeit für Archivnamen
        const d = new Date();
        const dateStr = d.getDate().toString().padStart(2, '0') + '.' +
                       (d.getMonth() + 1).toString().padStart(2, '0') + '.' +
                       d.getFullYear() + ' - ' +
                       d.getHours().toString().padStart(2, '0') + '\u2236' +
                       d.getMinutes().toString().padStart(2, '0');
    
        const archiveName = 'Profil Andreas ' + AppConstants.MOZ_APP_VERSION_DISPLAY + ' - ' + dateStr + '.zip';
        const xpi = fu.File(path + '\\' + archiveName);
    
        // Zip-Datei erstellen
        zw.open(xpi, pr.PR_RDWR | pr.PR_CREATE_FILE | pr.PR_TRUNCATE);
        const dirArr = [dir];
    
        for (let i = 0; i < dirArr.length; i++) {
          const dirEntries = dirArr[i].directoryEntries;
          while (dirEntries.hasMoreElements()) {
            const entry = dirEntries.getNext().QueryInterface(Ci.nsIFile);
    
            if (entry.path === xpi.path) continue;
    
            if (entry.isDirectory()) {
              dirArr.push(entry);
            }
    
            const relPath = entry.path.replace(dirArr[0].path, '');
            if (relPath.match(excludesRegex)) continue;
    
            const saveInZipAs = relPath.substr(1).replace(/\\/g, '/');
            try {
              zw.addEntryFile(saveInZipAs, Ci.nsIZipWriter.COMPRESSION_FASTEST, entry, false);
            } catch (e) {}
          }
        }
        zw.close();
    
        // Erfolgmeldung
        showAlert('Profilsicherung', 'Die aktuelle Konfiguration wurde als:\n' + archiveName + '\ngesichert in:\n' + path);
      }
    
      // ---- KLICK-HANDLER ----
      (function setupClickHandler() {
        const button = document.getElementById(id);
        if (button) {
          button.addEventListener('click', event => {
            if (event.button !== 0) return;
            performBackup();
          });
        } else {
          setTimeout(setupClickHandler, 100);
        }
      })();
    
    })();
    Alles anzeigen
  • Skript-Vorstellung: ExtensionOptionsMenu.uc.js

    • Mira_Belle
    • 2. September 2026 um 18:17

    Ok, bitte beachten, es könnte sein, dass ich noch die eine oder andere Änderung vornehme,
    aber im Grunde ist es fertig!

    JavaScript
    // ==UserScript==
    // @name           Extension Options Menu.uc.js
    // @description    Fügt eine Menüschaltfläche zur Verwaltung von Erweiterungen hinzu
    // @compatibility  Firefox 154*.*
    // @include        main
    // @charset        UTF-8
    // @version        5.2
    // @note           Inspiriert von FuchsFan
    // @Source         https://www.camp-firefox.de/forum/thema/140889/?postID=1293608#post1293608
    
    // ==/UserScript==
    
    /* ----------------------------------------------------------------------------------- */
    /*     Zu beachten ist, dass die Grafiken sich im richtigen Ordner befinden müssen     */
    /*            %appdata%\Mozilla\Firefox\Profiles\"Profilname"\chrome\icons             */
    /* ----------------------------------------------------------------------------------- */
    
    /* ----------------------------------------------------------------------------------- */
    /*  IMPORTANT!         This script was edited and modified using AI.                   */
    /* ----------------------------------------------------------------------------------- */
    
    'use strict';
    
    (function() {
    
      if (!window.gBrowser) return;
    
      const
      // ■■ START UserConfiguration ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
                 id = 'eom-button'              , // Id des Buttons
              label = 'Erweiterungen'           , // Bezeichnung des Buttons
        tooltiptext = 'Menü für Erweiterungsoptionen',
               icon = 'Legacy Extension.svg'    ,   // [Name.Dateiendung] des Symbols
             colour = '#FF00FF'               , // Farbe für das SVG-Icon setzen
           iconPath = '/chrome/icons/'          , // Pfad zum Icon-Ordner
        showVersion = true                      , // Version hinter dem Add-on-Namen
            showAll = false                     , // Auch Add-ons ohne Einstellungsseite
       showDisabled = true                      , // Deaktivierte Add-ons anzeigen
        sortEnabled = 0                         , // Sortierung aktiver Add-ons
       sortDisabled = 0                         ; // Sortierung deaktivierter Add-ons   
      // ■■ END UserConfiguration ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
    
      const curProfDir = PathUtils.toFileURI(PathUtils.join(PathUtils.profileDir));
    
      if (!Services.prefs.getBoolPref('svg.context-properties.content.enabled')) {
        Services.prefs.setBoolPref('svg.context-properties.content.enabled', true);
      }
    
      /* ============ BUTTON ============ */
      try {
        CustomizableUI.createWidget({
          id: id,
          defaultArea: CustomizableUI.AREA_NAVBAR,
          label: label,
          tooltiptext: tooltiptext,
    
          onCreated: (button) => {
            button.style.MozContextProperties = 'fill, stroke, fill-opacity';
            button.style.listStyleImage = 'url("' + curProfDir + iconPath + icon + '")';
            button.style.color = colour;
            button.setAttribute('type', 'menu');
    
            let popup = document.createXULElement('menupopup');
            popup.id = id + '-popup';
            popup.addEventListener('popupshowing', e => {
              if (e.target === popup) populateMenu(popup);
            });
            popup.addEventListener('popuphiding', hideHoverHint);
            popup.addEventListener('popuphidden', hideHoverHint);
            button.appendChild(popup);
    
            // Kontextmenü unterdrücken
            button.addEventListener('contextmenu', e => e.preventDefault());
    
            // Mittel-/Rechtsklick auf den Button selbst
            button.addEventListener('click', e => {
              if (e.target !== e.currentTarget) return;
              if (e.button === 1) {
                e.preventDefault();
                restart();
              } else if (e.button === 2) {
                e.preventDefault();
                setTimeout(() => {
                  let cm = document.getElementById('toolbar-context-menu');
                  if (cm) cm.hidePopup();
                }, 0);
                BrowserAddonUI.openAddonsMgr('addons://list/extension');
              }
            });
          }
        });
    
      } catch(e) {
        Cu.reportError('EOM: Widget konnte nicht erstellt werden: ' + e);
      }
    
      /* ============ CSS ============ */
      const css = `
        #${id} .toolbarbutton-icon {
          -moz-context-properties: fill, stroke, fill-opacity;
          fill: ${colour};
        }
        #${id}-popup menuitem.menuitem-iconic .menu-iconic-icon {
          width: 16px;
          height: 16px;
          margin-inline-start: 2px;
          margin-inline-end: 6px;
          -moz-context-properties: fill;
        }
    
        #${id}-popup menuitem.menuitem-iconic {
          font-size: 14px !important;
          padding-block: 6px !important;
          padding-inline: 8px !important;
        }
    
        #${id}-popup menuitem.addon-uninstall {
          text-decoration: line-through !important;
          font-style: italic !important;
        }
      `;
    
      const style = document.createElement('style');
      style.textContent = css;
      (document.head || document.documentElement).appendChild(style);
    
    
      /* ============ HINWEISFENSTER ============ */
      let hoverHint = null;
    
      function createHoverHint() {
        if (hoverHint) return hoverHint;
    
        let panel = document.createXULElement('panel');
        panel.id = id + '-hover-hint';
        panel.setAttribute('noautohide', 'true');
        panel.setAttribute('ignorekeys', 'true');
        panel.setAttribute('level', 'top');
        panel.style.cssText = `
          appearance: none; -moz-appearance: none;
          width: 400px; max-width: 400px; padding: 10px;
        `;
    
        let desc = document.createXULElement('description');
        desc.id = id + '-hover-hint-text';
        desc.style.cssText = `
          margin: 0px; padding: 5px 50px 5px 15px;
          background: #808080; color: #ffffff;
          font-family: Arial, sans-serif; font-size: 15px;
          line-height: 1.5; white-space: pre-wrap;
          overflow-wrap: anywhere; word-wrap: break-word;
        `;
        panel.appendChild(desc);
    
        (document.getElementById('mainPopupSet') || document.documentElement)
          .appendChild(panel);
    
        hoverHint = panel;
        return panel;
      }
    
      function showHoverHint(event, message) {
        let panel = createHoverHint();
        let desc = document.getElementById(id + '-hover-hint-text');
        if (!desc) return;
        desc.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);
        }
      }
    
      function hideHoverHint() {
        if (!hoverHint) return;
        try { hoverHint.hidePopup(); } catch(e) {}
        hoverHint.setAttribute('hidden', 'true');
      }
    
      /* ============ ADD-ON-AKTIONEN ============ */
      function openAddonOptions(addon) {
        let optionsURL = addon.optionsURL || '';
        if (!addon.isActive || !optionsURL) return;
    
        if (addon.optionsType === 3) {
          if ('switchToTabHavingURI' in window) {
            switchToTabHavingURI(optionsURL, true);
          } else {
            openTab('contentTab', { contentPage: optionsURL });
          }
        } else {
          BrowserAddonUI.openAddonsMgr(
            'addons://detail/' + encodeURIComponent(addon.id) + '/preferences'
          );
        }
      }
    
      function browseDir(addon) {
        try {
          let dir = Services.dirsvc.get('ProfD', Ci.nsIFile);
          dir.append('extensions');
          dir.append(addon.id + (addon.unpack ? '' : '.xpi'));
          if (dir.exists()) {
            dir.reveal();
          } else {
            Services.prompt.alert(null, 'Fehler', 'Ordner oder Datei nicht gefunden.');
          }
        } catch(e) {
          Cu.reportError('EOM: browseDir fehlgeschlagen: ' + e);
        }
      }
    
      function restart() {
        let cancelQuit = Cc['@mozilla.org/supports-PRBool;1']
          .createInstance(Ci.nsISupportsPRBool);
        Services.obs.notifyObservers(cancelQuit, 'quit-application-requested', 'restart');
        if (cancelQuit.data) return;
        if (Services.appinfo.inSafeMode) {
          Services.startup.restartInSafeMode(Ci.nsIAppStartup.eAttemptQuit);
          return;
        }
        Services.appinfo.invalidateCachesOnRestart();
        Services.startup.quit(
          Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart
        );
      }
    
      function copyToClipboard(text) {
        Cc['@mozilla.org/widget/clipboardhelper;1']
          .getService(Ci.nsIClipboardHelper).copyString(text);
      }
    
      /* ============ MENÜEINTRAG-KLICK ============ */
      function handleItemClick(event, item) {
        let addon = item._addon;
        if (!addon) return;
    
        let pending = !!(addon.pendingOperations & AddonManager.PENDING_UNINSTALL);
        let hasModifier = event.ctrlKey || event.shiftKey || event.altKey || event.metaKey;
    
        switch (event.button) {
    
          case 0: // Linksklick
            if (addon.optionsURL && !hasModifier) {
              openAddonOptions(addon);
            } else if (event.ctrlKey) {
              browseDir(addon);
            } else if (event.altKey) {
              copyToClipboard(addon.id);
            }
            break;
    
          case 1: // Mittelklick = Startseite
            if (addon.homepageURL) openURL(addon.homepageURL);
            break;
    
          case 2: // Rechtsklick = aktivieren/deaktivieren
            if (!hasModifier) {
              let newState = !addon.userDisabled;
              if (newState) addon.disable(); else addon.enable();
              updateItemState(item, newState);
            } else if (event.ctrlKey) {
              if (pending) addon.cancelUninstall(); else addon.uninstall();
              item.classList.toggle('addon-uninstall', !pending);
            }
            break;
        }
      }
    
      function updateItemState(item, disabled) {
        item.classList.toggle('eom-active', !disabled);
        item.classList.toggle('eom-inactive', disabled);
      }
    
      /* ============ MENÜ FÜLLEN ============ */
      function sortKey(addon) {
        let pos = addon.isActive ? sortEnabled : sortDisabled;
        return pos + '\n' + addon.name.toLowerCase();
      }
    
      async function populateMenu(popup) {
        while (popup.hasChildNodes()) popup.removeChild(popup.firstChild);
    
        let addons = await AddonManager.getAddonsByTypes(['extension']);
        let previousState;
    
        addons.sort((a, b) => {
          let ka = sortKey(a), kb = sortKey(b);
          return ka < kb ? -1 : 1;
        });
    
        for (let addon of addons) {
    
          if (addon.isBuiltin || addon.id.endsWith('@search.mozilla.org')) continue;
    
          let showIt = !addon.appDisabled && (
            (addon.isActive && addon.optionsURL) ||
            (addon.userDisabled && showDisabled) ||
            (!addon.userDisabled && showAll)
          );
          if (!showIt) continue;
    
          let state = addon.isActive;
    
          if (sortDisabled === 1 && previousState !== undefined && state !== previousState) {
            popup.appendChild(document.createXULElement('menuseparator'));
          }
          previousState = state;
    
          let item = document.createXULElement('menuitem');
          item.classList.add('menuitem-iconic');
    
          let name = addon.name;
          if (showVersion) name += ' [' + addon.version + ']';
          item.setAttribute('label', name);
    
          // Add-on-Symbol (mit Fallback)
          let addonIcon =
            addon.iconURL ||
            addon.iconURL64 ||
            'chrome://mozapps/skin/extensions/extensionGeneric.svg';
          item.setAttribute('image', addonIcon);
          item.style.listStyleImage = 'url("' + addonIcon + '")';
    
          // Farbe als Inline-Style setzen (schlägt externes CSS)
          let baseColor =
            addon.isActive
              ? (addon.optionsURL ? '#00ff00' : '#008000')
              : (addon.optionsURL ? '#CC0000' : '#ff0000');
          item.style.setProperty('color', baseColor, 'important');
          item.dataset.eomColor = baseColor;
    
          item._addon = addon;
          item._hint =
            'ID: ' + addon.id + '\n\n' +
            'Linksklick = Einstellungsseite öffnen\n' +
            'Rechtsklick = aktivieren/deaktivieren\n' +
            'Mittelklick = Startseite öffnen\n' +
            'Strg + Linksklick = Erweiterungsordner öffnen\n' +
            'Strg + Rechtsklick = deinstallieren/rückgängig\n' +
            'Alt + Linksklick = ID kopieren';
    
          item.addEventListener('mouseenter', e => {
            item.style.setProperty('color', '#FFCC66', 'important');
            let text = item.querySelector('.menu-iconic-text, .menu-text, .menu-label');
            if (text) text.style.setProperty('color', '#FFCC66', 'important');
            showHoverHint(e, item._hint);
          });
          item.addEventListener('mouseleave', () => {
            item.style.setProperty('color', item.dataset.eomColor, 'important');
            let text = item.querySelector('.menu-iconic-text, .menu-text, .menu-label');
            if (text) text.style.setProperty('color', item.dataset.eomColor, 'important');
            hideHoverHint();
          });
    
          item.addEventListener('click', e => handleItemClick(e, item));
          popup.appendChild(item);
        }
      }
    
      /* ============ AUFRÄUMEN ============ */
      window.addEventListener('unload', () => {
        hideHoverHint();
        try { CustomizableUI.destroyWidget(id); } catch(e) {}
      }, { once: true });
    
    })();
    Alles anzeigen
  • Skripte funktionieren nicht mehr seit Update auf FF 155

    • Mira_Belle
    • 2. September 2026 um 17:22

    Du hast die " " vergessen!
    ""

    JavaScript
    try {
        CustomizableUI.createWidget({
            id: "add-BB-app",
            label: "Betterbird",
            tooltiptext: "Betterbird Start",
            onCreated: btn => btn.image = "file:///C:/Users/User/AppData/Roaming/Mozilla/Firefox/Profiles/w35ez2ds.default-release-1788350594817/chrome/images/messengerWindow-bb-green.ico",
            onCommand: function(event) {			
                var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
                file.initWithPath("C:\\Program Files\\Betterbird\\betterbird.exe");
                if (file.exists()) file.launch();
            }
        });
    } catch(e) {}
    Alles anzeigen
  • Skript-Vorstellung: ExtensionOptionsMenu.uc.js

    • Mira_Belle
    • 2. September 2026 um 17:17
    Zitat von lionsson

    ... und wenn es dann als endgültiges Script vorliegt, hat sich eine schöne Spannung aufgebaut, und viele freuen sich.

    Danke, jetzt habe ich Pipi in den Augen.
    Eventuell kommt doch noch etwas.
    Es wird noch getestet.

  • Skript-Vorstellung: ExtensionOptionsMenu.uc.js

    • Mira_Belle
    • 2. September 2026 um 16:02

    FuchsFan Mit meinen Dämonen triggern mich halt so komische Beiträge.
    Weiß nicht so recht, wie ich diese einsortieren soll,
    und bin dann recht schnell "verschnupft".

  • Skript-Vorstellung: ExtensionOptionsMenu.uc.js

    • Mira_Belle
    • 2. September 2026 um 15:18

    Habe kein Interesse mehr an der Fortsetzung!
    Habe es meinen Vorstellungen angepasst, mit Kommentaren versehen,
    damit ich es auch in Monaten noch verstehe.

    Wer grundsätzlich die Funktionen gut findet, mag FuchsFans Version nutzen,
    eventuell wird die ja weiter gepflegt.

Unterstütze uns!

Jährlich (2026)

76,1 %

76,1% (589,79 von 775 EUR)

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