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

Beiträge von Horstmann

  • Eigene Zusatzleisten

    • Horstmann
    • 24. Dezember 2025 um 17:03

    Ein kleiner Update zu Weihnachten. :)

    Die Icons sind etwas besser eingebunden, das Kontext-Menü Item zur Positionierung der Toolbar taucht nur noch bei Rechtsklick auf den Button oder in die Toolbar auf (anderen Menüs wird es nicht mehr aufgezwungen), und eine Ladung kleinerer Änderungen.

    Funktion und Usereinstellungen sind ansonsten unverändert, und können von früheren Versionen direkt übernommen werden.

    Version 17c:

    JavaScript
    // Additional toolbar
    // Choice of vertical left, right, or horizontal bottom, top position
    // Button to turn toolbar On/Off
    // Switch toolbar position via right-click/contextmenu, only available on this button and this toolbar
    
    // Use filename starting with 00 for custom button functions !! =>
    // 00_extra_toolbars_V17c.uc.js
    
    // Based on:
    // Aris: https://github.com/Aris-t2/CustomJSforFx/blob/master/scripts/addonbar_vertical.uc.js
    // Latest versions and icons =>
    // Forum topic: https://www.camp-firefox.de/forum/thema/139927-eigene-zusatzleisten
    // Kudos to Aris, Mitleser and Mira_Belle
    
    // ATTENTION: Some system buttons can still be moved to additional/custom toolbars, but they will have no function.
    // There is a patch by @BrokenHeart: https://www.camp-firefox.de/forum/thema/138875-fix-toolbar-buttons-reagieren-nicht-mehr-ab-ff-134/
    // Different patch re. the issue by Aris included in this script, experimental
    
    // Version V17c
    
    (function() {
    
        if (location.href !== 'chrome://browser/content/browser.xhtml')
            return;
    
    // User settings
    // After script changes, restart with Clear StartUp Cache => about:support
    
       // Icons
    
            // false = use Firefox Icon, true = Custom Icon
            let custom_tb_icon  = false;       // On/Off Button
            let custom_tb_icon_sw  = false;    // Position switch button
    
            // Custom icon files
            let Icon_tb = 'toolbar_4.svg';           // On/Off Button
            let Icon_sw = 'toolbar_switch_4.svg';    // Position switch menuitem
    
            // Firefox icons
            let Icon_tb_Fx = 'chrome://browser/skin/sidebars-right.svg';      // On/Off Button
            let Icon_sw_Fx = 'chrome://global/skin/icons/arrow-right.svg';    // Position switch menuitem
    
            // Custom Icons expected in profile-name/chrome/icons folder ("icons" folder needs to be created)
            // Path to icon folder named "icons" inside profile folder
            let IconPath = '/chrome/icons/';
    
       // Custom background color: false = Off ; true = On (overwrites themes)
            let new_tb_color = false;
            // background color if true
            let new_tb_bg_color = 'hsla(200, 45%, 87%, 1)';
    
       // Border width, 0px = off
            let new_tb_border_width = '1px';
       // Border color
            //let new_tb_border_color = 'red';                                              // Fixed color
            //let new_tb_border_color = 'var(--sidebar-border-color)';                      // Firefox default
            let new_tb_border_color = 'color-mix(in srgb, currentColor 30%, transparent)';  // Custom self-adjusting color
    
    // Size of toolbar and buttons changes, must be px values, all 3 settings are related ==>
    
            // Change button sizes via padding, 8px default, changes toolbar size as well
            let new_tb_btn_size = '6px';
    
            // Width vertical toolbar / height horizontal toolbar, increased by this value on both sides
            // Increases distance of buttons to edges, 0px => toolbar size = button size
            let new_tb_size = '1px';
    
            // Distance between buttons, 2px default, doesn't change toolbar size
            let new_tb_distance = '5px';
    
    // Expert mode ===>>>
    // Saving changes, initial states ==>
    
       // true = save states toolbar On/Off / position on quitting Firefox, false = don't save (prefs deleted)
            // 2x restart required once after change, to make the the option stick
            let new_tb_save = true;
    
       // Initial state toolbar visibility: 0 = On, 1 = Off, only if new_tb_save = false (not saved)
            let new_tb_off = 0;
       // Position initial state: 0 = right, 1 = left, 2 = bottom, 3 = top, only if new_tb_save = false (not saved)
            let new_tb_loc = 0;
    
       // Extra: false = Button switches toolbar On/Off / changes Position for all open windows ; true = only active window
            let new_tb_uno = false;       // On/Off Button
            let new_tb_uno_sw = false;    // Position button
    
    // Possible problem solutions, if required, experimental ==>
    
       // Fix #1 for themes with low/ tiling background images, true / false, best to only use one of both
            let theme_fix = false;
            // Fix #2, overwrites Fix #1
            let theme_fix_2 = false;
    
       // Adjustments for Restore 'Space & Separator' items script for Firefox 102+ by Aris, true / false
            // https://github.com/Aris-t2/CustomJSforFx/blob/master/scripts/space_and_separator_restorer.uc.js
            let separator_fix = true;
    
    // End of user settings
    
        // Icons stuff
        // Get path to profile folder
        let ProfilePath = PathUtils.toFileURI(PathUtils.join(PathUtils.profileDir));
    
        let ImagePath = ProfilePath + IconPath + Icon_tb;
        if (!custom_tb_icon) {
           ImagePath = Icon_tb_Fx;
           }
        let ImagePathSW = ProfilePath + IconPath + Icon_sw;
        if (!custom_tb_icon_sw) {
           ImagePathSW = Icon_sw_Fx;
           }
    
        // Enable .svg icons properties
        if (Services.prefs.getBoolPref('svg.context-properties.content.enabled') == false) {
        	Services.prefs.setBoolPref('svg.context-properties.content.enabled', true );
        }
    
        // Toolbar
        const pref_new_toolbar_state = "userchrome.new_toolbar.enabled";
    
        let ntb_box = document.createXULElement('toolbox');
        ntb_box.id = 'toolbox_new';
        ntb_box.setAttribute('orient','horizontal');
    
        let ntb = document.createXULElement('toolbar');
        ntb.id = 'new_toolbar';
        ntb.setAttribute('customizable', true);
        ntb.setAttribute("class","toolbar-primary chromeclass-toolbar browser-toolbar customization-target");
        ntb.setAttribute('mode', 'icons');
        ntb.setAttribute('context', 'toolbar-context-menu');
        ntb.setAttribute('label', 'New Toolbar');
        ntb.setAttribute('orient', 'vertical');
        ntb.setAttribute("accesskey","");
    
        ntb_box.appendChild(ntb);
        document.getElementById('browser').parentNode.appendChild(ntb_box);
    
        CustomizableUI.registerArea('new_toolbar', {legacy: true});
        CustomizableUI.registerToolbarNode(ntb);
    
        let observer_custom = new MutationObserver(function(mutations) {
          for (let mutation of mutations) {
            try {
              const customContainer = document.getElementById('customization-container');
              if (!customContainer) return;
              const rect = customContainer.getBoundingClientRect();
              document.getElementById('toolbox_new').style.setProperty('--height_newbar_c', rect.top + 'px');
            } catch (e) { }
          }
        });
        observer_custom.observe(document.querySelector('#main-window'), {
          attributes: true,
          attributeFilter: ['customizing'],
        });
    
        let navbar_size = document.getElementById("browser");
        let observer = new ResizeObserver(() => {
        let rect = navbar_size.getBoundingClientRect();
        document.getElementById('toolbox_new').style.setProperty('--height_newbar', rect.height + 'px');
        document.getElementById('toolbox_new').style.setProperty('--height_newbar_top', rect.top + 'px');
        });
        observer.observe(navbar_size);
    
        //On/Off button
        try {
            CustomizableUI.createWidget({
              id: 'NewToolbar_button',
              defaultArea: CustomizableUI.AREA_NAVBAR,
              tooltiptext: 'Toolbar On',
              label: 'Toggle New Toolbar',
              onCreated: (this_button) => {
                 this_button.setAttribute('closemenu', 'none');
                 this_button.style.MozContextProperties = 'fill, stroke, fill-opacity, stroke-opacity';
                 this_button.style.listStyleImage = 'url("' + ImagePath + '")';
                 this_button.style.minWidth = 'fit-content';
              }
            });
        } catch(e) { }
    
        // Button function
        NewToolbar_button.addEventListener('click', event => {
            if (event.button === 0 ) {
              if (!new_tb_uno) {
                tb_toggle();
              }
              else {
                tb_toggle_uno();
              };
              if (NewToolbar_button.classList.contains("off-mode_btn")) {
                 NewToolbar_button.setAttribute("tooltiptext", "Toolbar Off");
                }
              else {
                NewToolbar_button.setAttribute("tooltiptext", "Toolbar On");
              };
            }
         });
    
        function tb_toggle() {
           for (let win of Services.wm.getEnumerator("navigator:browser")) {
             const toolbar = win.document.getElementById("new_toolbar");
             const browserArea = win.document.getElementById("browser");
             const button = win.document.getElementById("NewToolbar_button");
             toolbar.classList.toggle("off-mode");
             browserArea.classList.toggle("off-mode_b");
             button.classList.toggle("off-mode_btn");
             const ntb_visible = !toolbar.classList.contains("off-mode");
             Services.prefs.setBoolPref(pref_new_toolbar_state, ntb_visible);
             }
        };
    
        function tb_toggle_uno() {
             new_toolbar.classList.toggle("off-mode");
             browser.classList.toggle("off-mode_b");
             NewToolbar_button.classList.toggle("off-mode_btn");
             const ntb_visible = !new_toolbar.classList.contains("off-mode");
             Services.prefs.setBoolPref(pref_new_toolbar_state, ntb_visible);
        };
    
        // Position initial state
        if (new_tb_loc === 0) {
             toolbox_new.classList.add("right_mode");
             browser.classList.add("right_mode_b");
             NewToolbar_button.classList.add("right_mode_btn");
           }
        else if (new_tb_loc === 1) {
             toolbox_new.classList.add("left_mode");
             browser.classList.add("left_mode_b");
             NewToolbar_button.classList.add("left_mode_btn");
           }
        else if (new_tb_loc === 2) {
             toolbox_new.classList.add("bottom_mode");
             browser.classList.add("bottom_mode_b");
             NewToolbar_button.classList.add("bottom_mode_btn");
           }
        else if (new_tb_loc === 3) {
            toolbox_new.classList.add("top_mode");
            browser.classList.add("top_mode_b");
            NewToolbar_button.classList.add("top_mode_btn");
        }
    
        let toolbarEnabled = true;
        try {
            toolbarEnabled = Services.prefs.getBoolPref(pref_new_toolbar_state);
        } catch(e) {
                Services.prefs.setBoolPref(pref_new_toolbar_state, new_tb_off === 0);
                toolbarEnabled = new_tb_off === 0;
               }
        if (!toolbarEnabled) {
            new_toolbar.classList.add("off-mode");
            browser.classList.add("off-mode_b");
            NewToolbar_button.classList.add("off-mode_btn");
            NewToolbar_button.setAttribute("tooltiptext", "Toolbar Off");
        }
    
        // Background color
        if (new_tb_color) {
             new_toolbar.classList.add("ntb_bg_color");
           }
    
        // Code by Aris => Attach handlers for buttons moved outside #navigator-toolbox
        const customHandlers = {
        	  "unified-extensions-button": (el, e) => gUnifiedExtensions.togglePanel(e),
        	  "fxa-toolbar-menu-button":   (el, e) => gSync.toggleAccountPanel(el, e),
        	  "firefox-view-button":       (el, e) => FirefoxViewHandler.openToolbarMouseEvent(e),
        	  "downloads-button":          (el, e) => DownloadsIndicatorView.onCommand(e),
        	  "pageActionButton":          (el, e) => BrowserPageActions.mainButtonClicked(e),
        	  "alltabs-button":            (el, e) => gTabsPanel.showAllTabsPanel(e, "alltabs-button"),
        	  "library-button":            (el, e) => PanelUI.showSubView("appMenu-libraryView", el, e),
        	  "import-button":             (el, e) => MigrationUtils.showMigrationWizard(window, {
      	  entrypoint: MigrationUtils.MIGRATION_ENTRYPOINTS.BOOKMARKS_TOOLBAR,
      	  }),
        };
    		document.getElementById("new_toolbar").addEventListener("mousedown", (e) => {
    		  const button = e.target.closest("toolbarbutton");
    		  if (button?.id && customHandlers[button.id]) customHandlers[button.id](button, e);
    		});
    
        // Position switch context menu item
        const pref_position = "userchrome.new_toolbar.position";
        function getPositionPref() {
            try {
                return Services.prefs.getCharPref(pref_position);
            } catch (e) {
                return "right"; // Standardwert
            }
        }
        function setPositionPref(value) {
            Services.prefs.setCharPref(pref_position, value);
        }
    
        let menuitem_SW = document.createXULElement("menuitem");
        menuitem_SW.setAttribute('id', 'NewToolbar_position_Con');
        menuitem_SW.setAttribute('closemenu', 'none');
        menuitem_SW.setAttribute('label', 'Toolbar Position');
        menuitem_SW.style.setProperty('-moz-context-properties', 'fill, stroke, fill-opacity, stroke-opacity');
        menuitem_SW.classList.add('menuitem-iconic');
    
        let menu_SW = document.getElementById('toolbar-context-menu');
        let separator_SW = document.querySelector('.viewCustomizeToolbar');
        menu_SW.insertBefore(menuitem_SW, separator_SW);
    
        let menuseparator_sw = document.createXULElement("menuseparator");
        menuseparator_sw.setAttribute('id', 'sw_separator');
        menu_SW.insertBefore(menuseparator_sw, menuitem_SW.nextSibling);
    
        // Context menuitem only vivible in this button and toolbar
        menu_SW.addEventListener("popupshowing", (event) => {
          let trigger = menu_SW.triggerNode;
          let isntbButton = trigger && trigger.id === "NewToolbar_button";
          let isInsideNewToolbar = false;
          if (trigger) {
            let toolbar = trigger.closest("#new_toolbar");
            isInsideNewToolbar = !!toolbar;
          }
          let visible = isntbButton || isInsideNewToolbar;
          menuitem_SW.hidden = !visible;
          menuseparator_sw.hidden = !visible;
        });
    
        // Disable menuitems for moving button out of toolbars or overflow menu
        if (menu_SW) {
          menu_SW.addEventListener("popupshowing", onContextMenuShowing);
        }
        let overflowMenu = document.getElementById("customizationPanelItemContextMenu");
        if (overflowMenu) {
          overflowMenu.addEventListener("popupshowing", onContextMenuShowing);
        }
    
        function onContextMenuShowing(event) {
          const menu = event.currentTarget;
          const trigger = menu.triggerNode;
          if (!trigger) return;
    
          const isPopupButtonOrWrapper =
            trigger.id === "NewToolbar_button" ||
            trigger.id === "wrapper-NewToolbar_button" ||
            !!trigger.closest?.("#wrapper-NewToolbar_button, #NewToolbar_button");
    
          const removeFromToolbarItem =
            menu.querySelector(".customize-context-removeFromToolbar");
          const removeFromPanelItem =
            menu.querySelector(".customize-context-removeFromPanel");
          const moveToPanelItem =
            menu.querySelector(".customize-context-moveToPanel");
    
          const inNewToolbar = trigger.closest("#new_toolbar");
    
          const tbLike = trigger.closest(
            "#NewToolbar_button, #wrapper-NewToolbar_button, toolbarbutton, toolbarpaletteitem, toolbaritem, .toolbarbutton-1"
          );
    
          if (inNewToolbar && !tbLike) {
            if (removeFromToolbarItem)
              removeFromToolbarItem.setAttribute("disabled", "true");
            if (removeFromPanelItem)
              removeFromPanelItem.setAttribute("disabled", "true");
            if (moveToPanelItem)
              moveToPanelItem.setAttribute("disabled", "true");
            return;
          }
    
          function setStateForItem(item) {
            if (!item) return;
            if (isPopupButtonOrWrapper) {
              item.setAttribute("disabled", "true");
            } else {
              item.removeAttribute("disabled");
            }
          }
          setStateForItem(removeFromToolbarItem);
          setStateForItem(removeFromPanelItem);
        };
    
        // functions position
         function applyPosition(pos) {
            toolbox_new.classList.remove("left_mode", "bottom_mode", "right_mode", "top_mode");
            browser.classList.remove("left_mode_b", "bottom_mode_b", "right_mode_b", "top_mode_b");
            NewToolbar_button.classList.remove("left_mode_btn", "bottom_mode_btn", "right_mode_btn", "top_mode_btn");
            NewToolbar_position_Con.classList.remove("left_mode_sw", "bottom_mode_sw", "right_mode_sw", "top_mode_sw");
            if (pos === "left") {
                toolbox_new.classList.add("left_mode");
                browser.classList.add("left_mode_b");
                NewToolbar_button.classList.add("left_mode_btn");
                NewToolbar_position_Con.classList.add("left_mode_sw");
            } else if (pos === "bottom") {
                toolbox_new.classList.add("bottom_mode");
                browser.classList.add("bottom_mode_b");
                NewToolbar_button.classList.add("bottom_mode_btn");
                NewToolbar_position_Con.classList.add("bottom_mode_sw");
            } else if (pos === "top") {
                toolbox_new.classList.add("top_mode");
                browser.classList.add("top_mode_b");
                NewToolbar_button.classList.add("top_mode_btn");
                NewToolbar_position_Con.classList.add("top_mode_sw");
            } else if (pos === "right") {
                toolbox_new.classList.add("right_mode");
                browser.classList.add("right_mode_b");
                NewToolbar_button.classList.add("right_mode_btn");
                NewToolbar_position_Con.classList.add("right_mode_sw");
            }
         }
         let savedPos = getPositionPref();
         applyPosition(savedPos);
    
         document.getElementById("NewToolbar_position_Con").addEventListener('click', event => {
            if (event.button === 0 || event.button === 2) {
              if (!new_tb_uno_sw) {
                poser();
              }
              else {
                poser_uno();
              };
            }
         });
    
        function poser() {
            for (let win of Services.wm.getEnumerator("navigator:browser")) {
                const toolbox = win.document.getElementById("toolbox_new");
                const browserArea = win.document.getElementById("browser");
                const button = win.document.getElementById("NewToolbar_button");
                const button_con = win.document.getElementById("NewToolbar_position_Con");
                if (toolbox.classList.contains("right_mode")) {
                    toolbox.classList.replace("right_mode", "left_mode");
                    browserArea.classList.replace("right_mode_b", "left_mode_b");
                    button.classList.replace("right_mode_btn", "left_mode_btn");
                    button_con.classList.replace("right_mode_sw", "left_mode_sw");
                    setPositionPref("left");
                }
                else if (toolbox.classList.contains("left_mode")) {
                    toolbox.classList.replace("left_mode", "bottom_mode");
                    browserArea.classList.replace("left_mode_b", "bottom_mode_b");
                    button.classList.replace("left_mode_btn", "bottom_mode_btn");
                    button_con.classList.replace("left_mode_sw", "bottom_mode_sw");
                    setPositionPref("bottom");
                }
                else if (toolbox.classList.contains("bottom_mode")) {
                    toolbox.classList.replace("bottom_mode", "top_mode");
                    browserArea.classList.replace("bottom_mode_b", "top_mode_b");
                    button.classList.replace("bottom_mode_btn", "top_mode_btn");
                    button_con.classList.replace("bottom_mode_sw", "top_mode_sw");
                    setPositionPref("top");
                }
                else if (toolbox.classList.contains("top_mode")) {
                    toolbox.classList.replace("top_mode", "right_mode");
                    browserArea.classList.replace("top_mode_b", "right_mode_b");
                    button.classList.replace("top_mode_btn", "right_mode_btn");
                    button_con.classList.replace("top_mode_sw", "right_mode_sw");
                    setPositionPref("right");
                }
            }
        };
    
        function poser_uno() {
            if (toolbox_new.classList.contains("right_mode")) {
                toolbox_new.classList.replace("right_mode", "left_mode");
                browser.classList.replace("right_mode_b", "left_mode_b");
                NewToolbar_button.classList.replace("right_mode_btn", "left_mode_btn");
                NewToolbar_position_Con.classList.replace("right_mode_sw", "left_mode_sw");
                setPositionPref("left");
            }
            else if (toolbox_new.classList.contains("left_mode")) {
                toolbox_new.classList.replace("left_mode", "bottom_mode");
                browser.classList.replace("left_mode_b", "bottom_mode_b");
                NewToolbar_button.classList.replace("left_mode_btn", "bottom_mode_btn");
                NewToolbar_position_Con.classList.replace("left_mode_sw", "bottom_mode_sw");
                setPositionPref("bottom");
            }
            else if (toolbox_new.classList.contains("bottom_mode")) {
                toolbox_new.classList.replace("bottom_mode", "top_mode");
                browser.classList.replace("bottom_mode_b", "top_mode_b");
                NewToolbar_button.classList.replace("bottom_mode_btn", "top_mode_btn");
                NewToolbar_position_Con.classList.replace("bottom_mode_sw", "top_mode_sw");
                setPositionPref("top");
            }
            else if (toolbox_new.classList.contains("top_mode")) {
                toolbox_new.classList.replace("top_mode", "right_mode");
                browser.classList.replace("top_mode_b", "right_mode_b");
                NewToolbar_button.classList.replace("top_mode_btn", "right_mode_btn");
                NewToolbar_position_Con.classList.replace("top_mode_sw", "right_mode_sw");
                setPositionPref("right");
            }
        };
    
        // Move button back if removed from toolbars or overflow menu
        let previousPlacement = null;
        window.addEventListener("beforecustomization", () => {
          previousPlacement = CustomizableUI.getPlacementOfWidget("NewToolbar_button");
        });
        function ensureTestButtonNotInPalette() {
          let placement = CustomizableUI.getPlacementOfWidget("NewToolbar_button");
          if (!placement) {
            if (previousPlacement) {
              CustomizableUI.addWidgetToArea(
                "NewToolbar_button",
                previousPlacement.area,
                previousPlacement.position
              );
            } else {
              CustomizableUI.addWidgetToArea(
                "NewToolbar_button",
                CustomizableUI.AREA_NAVBAR
              );
            }
          }
        };
        window.addEventListener("aftercustomization", ensureTestButtonNotInPalette);
    
        // On quitting Firefox: delete Prefs, if new_tb_save = false
        if (!new_tb_save) {
             Services.obs.addObserver(function observer(subject, topic, data) {
                 if (topic === "quit-application-granted") {
                     try {
                         Services.prefs.clearUserPref(pref_new_toolbar_state);
                         Services.prefs.clearUserPref(pref_position);
                     } catch (e) { }
                     Services.obs.removeObserver(observer, "quit-application-granted");
                 }
             }, "quit-application-granted");
          };
    
    let css =`
    
    #main-window {
        --ug-newbar_basewidth: calc(2 * ${new_tb_btn_size} + 16px);  /* Minimalgroesse = Groesse Buttons */
        --ug-newbar_width: calc(var(--ug-newbar_basewidth) + ${new_tb_border_width} + 2 * `+new_tb_size+`);
    }
    
    /*- Buttons -*/
    
    /* Buttons sizes */
    #new_toolbar {
        --toolbarbutton-inner-padding: ${new_tb_btn_size} !important;
        --toolbarbutton-outer-padding: 0px !important;
    }
    
    /*  On/Off Button  */
    #NewToolbar_button.off-mode_btn:not(:hover, :active) .toolbarbutton-icon {
        opacity: 0.4;
    }
    
    /*  Button adjusts to Toolbar Position  */
    #NewToolbar_button.left_mode_btn .toolbarbutton-icon,
    #NewToolbar_position_Con.left_mode_sw :is(image, img) {
        transform: rotate(180deg);
    }
    #NewToolbar_button.bottom_mode_btn .toolbarbutton-icon,
    #NewToolbar_position_Con.bottom_mode_sw :is(image, img) {
        transform: rotate(90deg);
    }
    #NewToolbar_button.top_mode_btn .toolbarbutton-icon,
    #NewToolbar_position_Con.top_mode_sw :is(image, img) {
        transform: rotate(-90deg);
    }
    
    /*  Menuitem  */
    #NewToolbar_position_Con :is(image, img) {
        fill: currentColor !important;
        list-style-image: url("${ImagePathSW}");
        content: url("${ImagePathSW}") !important;
    }
    #main-window[customizing] :is(#NewToolbar_position_Con, #sw_separator) {
        display: none !important;
    }
    
    #unified-extensions-button[hidden] {
        visibility: visible !important;
        display: flex !important;
    }
    
    /*--  Browser adjustments  --*/
    
    #browser.right_mode_b {
        transition: padding-right 0.25s ease !important;
    }
    #browser.left_mode_b {
        transition: padding-left 0.25s ease !important;
    }
    #browser.bottom_mode_b {
        transition: padding-bottom 0.25s ease !important;
    }
    #browser.top_mode_b {
        transition: padding-top 0.25s ease !important;
    }
    
    #browser:not(.off-mode_b).right_mode_b {
        padding-right: var(--ug-newbar_width) !important;
    }
    #browser:not(.off-mode_b).left_mode_b {
        padding-left: var(--ug-newbar_width) !important;
    }
    #browser:not(.off-mode_b).bottom_mode_b {
        padding-bottom: var(--ug-newbar_width) !important;
    }
    #browser:not(.off-mode_b).top_mode_b {
        padding-top: var(--ug-newbar_width) !important;
    }
    
    /*--  Basics / Right  --*/
    
    #toolbox_new {
        position: fixed;
        z-index: 2 !important;
        display: flex;
        width: fit-content;
        top: var(--height_newbar_top);
        right: 0px;
    }
    #new_toolbar {
        display: flex;
        min-width: var(--ug-newbar_width) !important;
        width: var(--ug-newbar_width) !important;
        min-height: var(--ug-newbar_basewidth) !important;
        height: var(--height_newbar) !important;
        align-items: center !important;
        overflow: hidden !important;
        padding-block: 8px;
        border-width: 0px;
        border-style: solid !important;
        border-color: ${new_tb_border_color} !important;
        border-left-width: ${new_tb_border_width};
        border-right-width: 0px;
        margin-inline: 0px;
        padding-inline: 0px;
    }
    
    #toolbox_new:not(.bottom_mode, .top_mode) #new_toolbar:not([customizing]) {
        max-width: var(--ug-newbar_width) !important;
        transition: width 0.25s ease, max-width 0.25s ease, min-width 0.25s ease, border-left-width 0.125s ease;
    }
    
    #toolbox_new #new_toolbar:not([customizing]).off-mode {
        min-width: 0px !important;
        width: 0px !important;
        max-width: 0px !important;
        min-height: unset !important;
        max-height: unset !important;
        border-width: 0px !important;
        box-shadow: none !important;
    }
    
    #new_toolbar:not([customizing]).off-mode > :is(.toolbarbutton-1, toolbaritem) {
        opacity: 0 !important;
    }
    #new_toolbar > :is(.toolbarbutton-1, toolbaritem),
    #new_toolbar toolbarpaletteitem > :is(.toolbarbutton-1, toolbaritem) {
        margin-block: ${new_tb_distance} !important;
        margin-inline: var(--toolbarbutton-outer-padding) !important;
        transition: opacity 0.125s ease;
    }
    
    /*--  Left  --*/
    
    #toolbox_new.left_mode {
        right: unset;
        left: 0px;
    }
    #toolbox_new.left_mode #new_toolbar:not([customizing]) {
        border-left-width: 0px;
        border-right-width: ${new_tb_border_width};
        transition: width 0.25s ease, max-width 0.25s ease, min-width 0.25s ease, border-right-width 0.125s ease;
    }
    
    /*--  Bottom / Top --*/
    
    #toolbox_new.bottom_mode {
        top: unset;
        bottom: 0px;
    }
    
    #toolbox_new.top_mode #new_toolbar:not([customizing]),
    #toolbox_new.bottom_mode #new_toolbar:not([customizing]) {
        flex-direction: row !important;
        min-height: 0px !important;
        height: var(--ug-newbar_width) !important;
        max-height: var(--ug-newbar_width) !important;
        min-width: 0px !important;
        width: 100vw !important;
        padding-block: 0px;
        padding-inline: 8px;
        border-inline-width: 0px;
        border-top-width: ${new_tb_border_width};
        /*justify-content: center !important;*/    /* content centererd, optional */
        transition: height 0.25s ease, max-height 0.25s ease, min-height 0.25s ease, border-top-width 0.125s ease !important;
    }
    
    #toolbox_new:where(.bottom_mode, .top_mode) #new_toolbar:not([customizing]).off-mode {
        min-height: 0px !important;
        height: 0px !important;
        max-height: 0px !important;
        max-width: unset !important;
    }
    
    #toolbox_new:where(.bottom_mode, .top_mode) #new_toolbar:not([customizing]) > :is(.toolbarbutton-1, toolbaritem) {
        margin-block: var(--toolbarbutton-outer-padding) !important;
        margin-inline: ${new_tb_distance} !important;
    }
    
    /*--  Top  --*/
    
    #toolbox_new.top_mode #new_toolbar:not([customizing]) {
        border-top-width: 0px;
        border-bottom-width: ${new_tb_border_width};
        transition: height 0.25s ease, max-height 0.25s ease, min-height 0.25s ease, border-bottom-width 0.125s ease !important;
    }
    
    /*--  Fullscreen  --*/
    
    /* Mac / Video Fullscreen only */
    #main-window[inDOMFullscreen]:not([customizing]) #toolbox_new {
        visibility: collapse !important;
    }
    #main-window[inDOMFullscreen]:not([customizing]) #browser {
        padding: 0 !important;
    }
    /* Windows Fullscreen Video + Normal */
    @media (-moz-platform: windows) {
    #main-window[inFullscreen]:not([customizing]) #toolbox_new {
        visibility: collapse !important;
    }
    #main-window[inFullscreen]:not([customizing]) #browser {
        padding: 0 !important;
    }
    }
    
    /*--  customizing  --*/
    
    #main-window[customizing] #toolbox_new {
        top: unset !important;
        bottom: 0px !important;
        right: 0px !important;
        left: unset !important;
    }
    #new_toolbar[customizing] {
        height: calc(100vh - var(--height_newbar_c)) !important;
        width: initial !important;
        transition: none !important;
    }
    #new_toolbar[customizing]::after {
        content:"";
        position: absolute;
        top: 0px;
        right: 0px;
        height: 100%;
        width: 100%;
        outline: calc(-1 * ${new_tb_border_width} + 1px) solid ${new_tb_border_color};
        pointer-events: none;
    }
    #main-window:not([customizing]) #new_toolbar[customizing].off-mode {
        min-width: 0px !important;
        width: 0px !important;
        min-height: 0px !important;
        height: 0px !important;
        border-width: 0px !important;
    }
    #customization-container {
        margin-right: var(--ug-newbar_width) !important;
    }
    
    /*-  Background colors  -*/
    
    /* Custom toolbar background color if enabled */
    #new_toolbar.ntb_bg_color {
        background-color: ${new_tb_bg_color} !important;
    }
    
    /*- Background themes, if background images are tiled, try theme_fix options above -*/
    :root[lwtheme] #new_toolbar:not(.ntb_bg_color) {
        background-color: var(--lwt-accent-color, var(--toolbar-bgcolor)) !important;
    }
    :root[lwtheme][lwtheme-image] #new_toolbar:not(.ntb_bg_color) {
        background-image: var(--lwt-header-image) !important;
        background-position: right 0px top 0px !important;
    }
    
    /*-  test colors  -*/
    /*
    #new_toolbar image {
        outline: 1px solid green !important;
        outline-offset: -1px !important;
    }
    */
    
     `;
    
    if (theme_fix) {
      css += `
    /*-  Fix #1 for themes with tiled background images  -*/
    
    :root[lwtheme][lwtheme-image] #new_toolbar:not(.ntb_bg_color) {
        background: var(--lwt-header-image) !important;
        background-repeat: no-repeat !important;
        background-size: cover !important;
        background-position: right 0px top 0px !important;
    }
    :root[lwtheme][lwtheme-image] #toolbox_new:is(.bottom_mode, .top_mode) #new_toolbar:not(.ntb_bg_color) {
        background-size: auto !important;
    }
     `;
    }
    
    if (theme_fix_2) {
      css += `
    /*-  Fix #2b width for themes with tiled background images  -*/
    
    :root[lwtheme][lwtheme-image] #toolbox_new #new_toolbar:not(.ntb_bg_color) {
         background: transparent !important;
    }
    
    :root[lwtheme][lwtheme-image] #new_toolbar:not(.ntb_bg_color)::before {
        content: "" ;
        position: absolute;
        top: 0px;
        right: 0px;
        min-width: var(--height_newbar) !important;
        width: var(--height_newbar) !important;
        min-height: var(--ug-newbar_width) !important;
        height: var(--ug-newbar_width) !important;
        pointer-events: none;
        z-index: -1 !important;
        background: var(--lwt-header-image) !important;
        background-repeat: no-repeat !important;
        transform: rotate(-90deg) translateX(var(--ug-newbar_width)) !important;
        transform-origin: 100% 100% !important;
    }
    
    :root[lwtheme][lwtheme-image] #new_toolbar:not(.ntb_bg_color, [customizing])::before {
        transition: height 0.25s ease, max-height 0.25s ease, min-height 0.25s ease, margin-top 0.25s ease;
        margin-top: 0px;
    }
    
    :root[lwtheme][lwtheme-image] #new_toolbar:not(.ntb_bg_color, [customizing]).off-mode::before {
        min-height: 0px !important;
        height: 0px !important;
        max-height: 0px !important;
        margin-top: var(--ug-newbar_width);
    }
    
    :root[lwtheme][lwtheme-image] #toolbox_new:is(.bottom_mode, .top_mode) #new_toolbar:not(.ntb_bg_color, [customizing])::before {
        transform: scaleX(-1) !important;
        transform-origin: 50% 50% !important;
        min-height: var(--ug-newbar_width) !important;
        height: var(--ug-newbar_width) !important;
        min-width: 0px !important;
        width: 100vw !important;
        transition: height 0.25s ease, max-height 0.25s ease, min-height 0.25s ease;
        margin-top: unset;
    }
    
    :root[lwtheme][lwtheme-image] #toolbox_new:is(.bottom_mode, .top_mode) #new_toolbar:not(.ntb_bg_color, [customizing]).off-mode::before {
        min-height: 0px !important;
        height: 0px !important;
        max-height: 0px !important;
        margin-top: unset;
    }
    
    :root[lwtheme][lwtheme-image] #new_toolbar:not(.ntb_bg_color)[customizing]::before {
        width: calc(100vh - var(--height_newbar_c)) !important;
    }
    
    #main-window:not([customizing]) #toolbox_new #new_toolbar:not(.ntb_bg_color)[customizing].off-mode::before {
        min-width: 0px !important;
        width: 0px !important;
        min-height: 0px !important;
        max-height: 0px !important;
        height: 0px !important;
        border-width: 0px !important;
        margin-top: unset !important;
    }
     `;
    }
    
    if (separator_fix) {
      css += `
    /* Adjustments for Separator Scripts  */
    
    #new_toolbar toolbarseparator {
        width: calc(var(--ug-newbar_width) - ${new_tb_border_width} - 6px) !important;
        margin: 5px 0px !important;
        border-block-color: hsl(0, 0%, 0%, 0.45) hsl(0, 0%, 100%, 0.55) !important;
        transition: width 0.125s ease !important;
    }
    #new_toolbar :is(toolbarspacer, toolbarspring, toolbarseparator) {
        min-width: 0px !important;
    }
    #new_toolbar:not([customizing]).off-mode toolbarseparator {
        width: 0px !important;
    }
    #toolbox_new:where(.bottom_mode, .top_mode) #new_toolbar:not([customizing]) toolbarseparator {
        transform: rotate(-90deg) !important;
        margin: 0px !important;
    }
    #new_toolbar[customizing] toolbarseparator {
        margin-block: 16px !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


    Version 18; Code reduziert, Button im Overflowmenü kann auch Position ändern, weitere Optimierungen.

    JavaScript
    // Firefox Javascript, Additional toolbar
    // Choice of vertical left, right, and horizontal bottom, top position
    // Button to turn toolbar On/Off
    // Switch toolbar position via right-click/contextmenu, only available on this button and this toolbar
    
    // Use filename starting with 00 for custom button functions !! =>
    // 00_extra_toolbars_V18.uc.js
    
    // Based on:
    // Aris: https://github.com/Aris-t2/CustomJSforFx/blob/master/scripts/addonbar_vertical.uc.js
    // Latest versions and icons =>
    // Forum topic: https://www.camp-firefox.de/forum/thema/139927-eigene-zusatzleisten
    // Kudos to Aris, Mitleser and Mira_Belle
    
    // ATTENTION: Some system buttons can still be moved to additional/custom toolbars, but they will have no function.
    // There is a patch by @BrokenHeart: https://www.camp-firefox.de/forum/thema/138875-fix-toolbar-buttons-reagieren-nicht-mehr-ab-ff-134/
    // Different patch by Aris re. the issue included in this script, experimental
    
    // Version V18
    
    (function() {
    
        if (location.href !== 'chrome://browser/content/browser.xhtml')
            return;
    
    // User settings
    // After script changes, restart with Clear StartUp Cache => about:support
    
       // Icons
    
            // false = use Firefox Icon, true = Custom Icon
            let custom_tb_icon  = false;       // On/Off Button
            let custom_tb_icon_sw  = false;    // Position switch button
    
            // Custom icon files
            let Icon_tb = 'toolbar_4.svg';           // On/Off Button
            let Icon_sw = 'toolbar_switch_4.svg';    // Position switch menuitem
    
            // Firefox icons, or absolute file path if custom_tb_icon/ custom_tb_icon_sw = false
            let Icon_tb_Fx = 'chrome://browser/skin/sidebars-right.svg';      // On/Off Button
            let Icon_sw_Fx = 'chrome://global/skin/icons/arrow-right.svg';    // Position switch menuitem
    
            // Custom Icons expected in profile-name/chrome/icons folder ("icons" folder needs to be created)
            // Get path to profile folder
            let ProfilePath = PathUtils.toFileURI(PathUtils.join(PathUtils.profileDir));
            // Path to icon folder named "icons" inside profile folder
            let IconPath = '/chrome/icons/';
    
       // Custom background color: false = Off ; true = On (overwrites themes)
            let new_tb_color = false;
            // background color if true
            let new_tb_bg_color = 'hsla(200, 45%, 87%, 1)';
    
       // Border width, 0px = off
            let new_tb_border_width = '1px';
       // Border color
            //let new_tb_border_color = 'red';                                              // Fixed color
            //let new_tb_border_color = 'var(--sidebar-border-color)';                      // Firefox default
            let new_tb_border_color = 'color-mix(in srgb, currentColor 30%, transparent)';  // Custom self-adjusting color
    
    // Size of toolbar and buttons changes, must be px values, all 3 settings are related ==>
    
            // Change button sizes via padding, 8px default, changes toolbar size as well
            let new_tb_btn_size = '6px';
    
            // Width vertical toolbar / height horizontal toolbar, increased by this value on both sides
            // Increases distance of buttons to edges, 0px => toolbar size = button size + border
            let new_tb_size = '1px';
    
            // Distance between buttons, 2px default, doesn't change toolbar size
            let new_tb_distance = '5px';
    
    // Expert mode ===>>>
    // Saving changes, initial states ==>
    
       // true = save states toolbar On/Off / position on quitting Firefox, false = don't save (prefs deleted)
            // 2x restart required once after change, to make the the option stick
            let new_tb_save = true;
    
       // Initial state toolbar visibility: true = On, false = Off, only for new_tb_save = false (not saved)
            let new_tb_off = true;
       // Position initial state: right, left, bottom, top, only for new_tb_save = false (not saved)
            let new_tb_loc = "right";
    
       // Extra: false = Button switches toolbar On/Off / changes Position for all open windows ; true = only active window
            let new_tb_uno = false;       // On/Off Button
            let new_tb_uno_sw = false;    // Position button
    
    // Possible problem solutions, if required, experimental ==>
    
       // Fix #1 for themes with low/ tiling background images, true / false, best to only use one of both
            let theme_fix = false;
            // Fix #2, overwrites Fix #1
            let theme_fix_2 = false;
    
       // Adjustments for Restore 'Space & Separator' items script for Firefox 102+ by Aris, true / false
            // https://github.com/Aris-t2/CustomJSforFx/blob/master/scripts/space_and_separator_restorer.uc.js
            let separator_fix = true;
    
    // End of user settings
    
        // Icons stuff
        let ImagePath = ProfilePath + IconPath + Icon_tb;
        if (!custom_tb_icon) {
           ImagePath = Icon_tb_Fx;
           }
        let ImagePathSW = ProfilePath + IconPath + Icon_sw;
        if (!custom_tb_icon_sw) {
           ImagePathSW = Icon_sw_Fx;
           }
    
        // Enable .svg icons properties
        if (Services.prefs.getBoolPref('svg.context-properties.content.enabled') == false) {
        	Services.prefs.setBoolPref('svg.context-properties.content.enabled', true );
        }
    
    // Toolbar
        const pref_new_toolbar_state = "userchrome.new_toolbar.enabled";
    
        let ntb_box = document.createXULElement('toolbox');
        ntb_box.id = 'toolbox_new';
        ntb_box.setAttribute('orient','horizontal');
    
        let ntb = document.createXULElement('toolbar');
        ntb.id = 'new_toolbar';
        ntb.setAttribute('customizable', true);
        ntb.setAttribute("class","toolbar-primary chromeclass-toolbar browser-toolbar customization-target");
        ntb.setAttribute('mode', 'icons');
        ntb.setAttribute('context', 'toolbar-context-menu');
        ntb.setAttribute('label', 'New Toolbar');
        ntb.setAttribute('orient', 'vertical');
        ntb.setAttribute("accesskey","");
    
        ntb_box.appendChild(ntb);
        document.getElementById('browser').parentNode.appendChild(ntb_box);
    
        CustomizableUI.registerArea('new_toolbar', {legacy: true});
        CustomizableUI.registerToolbarNode(ntb);
    
        let observer_custom = new MutationObserver(function(mutations) {
          for (let mutation of mutations) {
            try {
              const customContainer = document.getElementById('customization-container');
              if (!customContainer) return;
              const rect = customContainer.getBoundingClientRect();
              document.getElementById('toolbox_new').style.setProperty('--height_newbar_c', rect.top + 'px');
            } catch (e) { }
          }
        });
        observer_custom.observe(document.querySelector('#main-window'), {
          attributes: true,
          attributeFilter: ['customizing'],
        });
    
        let navbar_size = document.getElementById("browser");
        let observer = new ResizeObserver(() => {
        let rect = navbar_size.getBoundingClientRect();
        document.getElementById('toolbox_new').style.setProperty('--height_newbar', rect.height + 'px');
        document.getElementById('toolbox_new').style.setProperty('--height_newbar_top', rect.top + 'px');
        });
        observer.observe(navbar_size);
    
    // On/Off button
        try {
            CustomizableUI.createWidget({
              id: 'NewToolbar_button',
              defaultArea: CustomizableUI.AREA_NAVBAR,
              tooltiptext: 'Toolbar On',
              label: 'Toggle New Toolbar',
              onCreated: (this_button) => {
                 this_button.setAttribute('closemenu', 'none');
                 this_button.style.MozContextProperties = 'fill, stroke, fill-opacity, stroke-opacity';
                 this_button.style.listStyleImage = 'url("' + ImagePath + '")';
                 this_button.style.minWidth = 'fit-content';
              }
            });
        } catch(e) { }
    
        // Button function
        NewToolbar_button.addEventListener('click', event => {
            if (event.button === 0 ) {
              if (!new_tb_uno) {
                tb_toggle();
              }
              else {
                tb_toggle_uno();
              };
              if (NewToolbar_button.classList.contains("off_mode")) {
                 NewToolbar_button.setAttribute("tooltiptext", "Toolbar Off");
                }
              else {
                NewToolbar_button.setAttribute("tooltiptext", "Toolbar On");
              };
            }
        });
    
        const elsOff = [new_toolbar, browser, NewToolbar_button];
    
        function tb_toggle() {
           for (let win of Services.wm.getEnumerator("navigator:browser")) {
             const toolbar = win.document.getElementById("new_toolbar");
             const browserArea = win.document.getElementById("browser");
             const button = win.document.getElementById("NewToolbar_button");
             [toolbar, browserArea, button].forEach(el => el.classList.toggle("off_mode"));
             const ntb_visible = !toolbar.classList.contains("off_mode");
             Services.prefs.setBoolPref(pref_new_toolbar_state, ntb_visible);
           }
        }
    
        function tb_toggle_uno() {
           elsOff.forEach(el => el.classList.toggle("off_mode"));
           const ntb_visible = !new_toolbar.classList.contains("off_mode");
           Services.prefs.setBoolPref(pref_new_toolbar_state, ntb_visible);
        }
    
        let toolbarEnabled = true;
        try {
            toolbarEnabled = Services.prefs.getBoolPref(pref_new_toolbar_state);
        } catch(e) {
                Services.prefs.setBoolPref(pref_new_toolbar_state, new_tb_off);
                toolbarEnabled = new_tb_off;
               }
        if (!toolbarEnabled) {
            elsOff.forEach(el => el.classList.add("off_mode"));
            NewToolbar_button.setAttribute("tooltiptext", "Toolbar Off");
        }
    
    // Position switch context menu item
        // Save state
        const pref_position = "userchrome.new_toolbar.position";
    
        function getPositionPref() {
            try {
                return Services.prefs.getCharPref(pref_position);
            } catch (e) {
                return new_tb_loc;  // Initial state
            }
        }
        function setPositionPref(value) {
            Services.prefs.setCharPref(pref_position, value);
        }
    
        // Toolbars menuitem
        let menuitem_sw = document.createXULElement("menuitem");
        menuitem_sw.setAttribute('id', 'NewToolbar_position_Con');
        menuitem_sw.setAttribute('closemenu', 'none');
        menuitem_sw.setAttribute('label', 'Toolbar Position');
        menuitem_sw.style.setProperty('-moz-context-properties', 'fill, stroke, fill-opacity, stroke-opacity');
        menuitem_sw.classList.add('menuitem-iconic');
    
        let toolbarMenu = document.getElementById('toolbar-context-menu');
        let sibling_sw = toolbarMenu.querySelector('.viewCustomizeToolbar');
    
        let menuseparator_sw = document.createXULElement("menuseparator");
        menuseparator_sw.setAttribute('id', 'sw_separator');
    
        toolbarMenu.insertBefore(menuitem_sw, sibling_sw);
        toolbarMenu.insertBefore(menuseparator_sw, menuitem_sw.nextSibling);
    
        // Overflow menuitem
        let menuitem_sw_Clone = menuitem_sw.cloneNode(true);
        menuitem_sw_Clone.classList.add('NewToolbar_position_Con_Over');
        let menuseparator_sw_Clone = menuseparator_sw.cloneNode(true);
    
        let overflowMenu = document.getElementById("customizationPanelItemContextMenu");
        let sibling_sw_over = overflowMenu.querySelector(".viewCustomizeToolbar");
    
        overflowMenu.insertBefore(menuitem_sw_Clone, sibling_sw_over);
        overflowMenu.insertBefore(menuseparator_sw_Clone, menuitem_sw_Clone.nextSibling);
    
        let Menuitem_sw_over = document.querySelector(".NewToolbar_position_Con_Over");
    
        // Apply all functions
        if (toolbarMenu) {
          toolbarMenu.addEventListener("popupshowing", onContextMenuShowing);
          toolbarMenu.addEventListener("popupshowing", trigger_limit);
          NewToolbar_position_Con.addEventListener('click', ntb_toggle);
        }
        if (overflowMenu) {
          overflowMenu.addEventListener("popupshowing", onContextMenuShowing);
          overflowMenu.addEventListener("popupshowing", trigger_limit);
          Menuitem_sw_over.addEventListener('click', ntb_toggle);
        }
    
        // Context menuitem only vivible on this button and toolbar
        function trigger_limit() {
          let trigger = toolbarMenu.triggerNode || overflowMenu.triggerNode;
          let isntbButton = trigger && trigger.id === "NewToolbar_button";
          let isInsideNewToolbar = false;
    
          if (trigger) {
            let toolbar = trigger.closest("#new_toolbar");
            isInsideNewToolbar = !!toolbar;
          }
          let visible = isntbButton || isInsideNewToolbar;
          menuitem_sw.hidden = !visible;
          menuseparator_sw.hidden = !visible;
          menuitem_sw_Clone.hidden = !visible;
          menuseparator_sw_Clone.hidden = !visible;
        };
    
        // Disable menuitems for moving button out of toolbars or overflow menu
        function onContextMenuShowing(event) {
           const menu = event.currentTarget;
           const trigger = menu.triggerNode;
           if (!trigger) return;
    
           const isPopupButtonOrWrapper =
             trigger.id === "NewToolbar_button" ||
             trigger.id === "wrapper-NewToolbar_button" ||
             !!trigger.closest?.("#wrapper-NewToolbar_button, #NewToolbar_button");
    
          const removeFromToolbarItem =
             menu.querySelector(".customize-context-removeFromToolbar");
          const removeFromPanelItem =
             menu.querySelector(".customize-context-removeFromPanel");
          const moveToPanelItem =
             menu.querySelector(".customize-context-moveToPanel");
    
          const inNewToolbar = trigger.closest("#new_toolbar");
          const tbLike = trigger.closest(
            "#NewToolbar_button, #wrapper-NewToolbar_button, toolbarbutton, toolbarpaletteitem, toolbaritem, .toolbarbutton-1"
          );
    
          if (inNewToolbar && !tbLike) {
            if (removeFromToolbarItem)
              removeFromToolbarItem.setAttribute("disabled", "true");
            if (removeFromPanelItem)
              removeFromPanelItem.setAttribute("disabled", "true");
            if (moveToPanelItem)
              moveToPanelItem.setAttribute("disabled", "true");
            return;
          }
    
          function setStateForItem(item) {
            if (!item) return;
            if (isPopupButtonOrWrapper) {
              item.setAttribute("disabled", "true");
            } else {
              item.removeAttribute("disabled");
            }
          }
          setStateForItem(removeFromToolbarItem);
          setStateForItem(removeFromPanelItem);
        };
    
        // Functions position
        const els = [toolbox_new, browser, NewToolbar_button, NewToolbar_position_Con, Menuitem_sw_over];
    
        // Apply saved state
        function applyPosition(pos) {
            if (pos === "left") {
               els.forEach(el => el.classList.add("left_mode"));
            } else if (pos === "bottom") {
               els.forEach(el => el.classList.add("bottom_mode"));
            } else if (pos === "top") {
               els.forEach(el => el.classList.add("top_mode"));
            } else if (pos === "right") {
               els.forEach(el => el.classList.add("right_mode"));
            }
        }
        let savedPos = getPositionPref();
        applyPosition(savedPos);
    
        function ntb_toggle() {
            if (event.button === 0 || event.button === 2) {
              if (!new_tb_uno_sw) {
                poser();
              }
              else {
                poser_uno();
              };
            }
        };
    
        function poser() {
            for (let win of Services.wm.getEnumerator("navigator:browser")) {
                const toolbox = win.document.getElementById("toolbox_new");
                const browserArea = win.document.getElementById("browser");
                const button = win.document.getElementById("NewToolbar_button");
                const button_con = win.document.getElementById("NewToolbar_position_Con");
                const button_con_over = win.document.querySelector(".NewToolbar_position_Con_Over");
                const elsW = [toolbox, browserArea, button, button_con, button_con_over];
                if (toolbox.classList.contains("top_mode")) {
                    elsW.forEach(el => el.classList.replace("top_mode", "left_mode"));
                    setPositionPref("left");
                }
                else if (toolbox.classList.contains("left_mode")) {
                    elsW.forEach(el => el.classList.replace("left_mode", "bottom_mode"));
                    setPositionPref("bottom");
                }
                else if (toolbox.classList.contains("bottom_mode")) {
                    elsW.forEach(el => el.classList.replace("bottom_mode", "right_mode"));
                    setPositionPref("right");
                }
                else if (toolbox.classList.contains("right_mode")) {
                    elsW.forEach(el => el.classList.replace("right_mode", "top_mode"));
                    setPositionPref("top");
                }
            }
        };
    
        function poser_uno() {
                if (toolbox_new.classList.contains("top_mode")) {
                    els.forEach(el => el.classList.replace("top_mode", "left_mode"));
                    setPositionPref("left");
                }
                else if (toolbox_new.classList.contains("left_mode")) {
                    els.forEach(el => el.classList.replace("left_mode", "bottom_mode"));
                    setPositionPref("bottom");
                }
                else if (toolbox_new.classList.contains("bottom_mode")) {
                    els.forEach(el => el.classList.replace("bottom_mode", "right_mode"));
                    setPositionPref("right");
                }
                else if (toolbox_new.classList.contains("right_mode")) {
                    els.forEach(el => el.classList.replace("right_mode", "top_mode"));
                    setPositionPref("top");
                }
        };
    
    // Move button back if removed from toolbars or overflow menu
        let previousPlacement = null;
        window.addEventListener("beforecustomization", () => {
          previousPlacement = CustomizableUI.getPlacementOfWidget("NewToolbar_button");
        });
        function ensureTestButtonNotInPalette() {
          let placement = CustomizableUI.getPlacementOfWidget("NewToolbar_button");
          if (!placement) {
            if (previousPlacement) {
              CustomizableUI.addWidgetToArea(
                "NewToolbar_button",
                previousPlacement.area,
                previousPlacement.position
              );
            } else {
              CustomizableUI.addWidgetToArea(
                "NewToolbar_button",
                CustomizableUI.AREA_NAVBAR
              );
            }
          }
        };
        window.addEventListener("aftercustomization", ensureTestButtonNotInPalette);
    
    // Code by Aris => Attach handlers for buttons moved outside #navigator-toolbox
        const customHandlers = {
        	  "unified-extensions-button": (el, e) => gUnifiedExtensions.togglePanel(e),
        	  "fxa-toolbar-menu-button":   (el, e) => gSync.toggleAccountPanel(el, e),
        	  "firefox-view-button":       (el, e) => FirefoxViewHandler.openToolbarMouseEvent(e),
        	  "downloads-button":          (el, e) => DownloadsIndicatorView.onCommand(e),
        	  "pageActionButton":          (el, e) => BrowserPageActions.mainButtonClicked(e),
        	  "alltabs-button":            (el, e) => gTabsPanel.showAllTabsPanel(e, "alltabs-button"),
        	  "library-button":            (el, e) => PanelUI.showSubView("appMenu-libraryView", el, e),
        	  "import-button":             (el, e) => MigrationUtils.showMigrationWizard(window, {
      	  entrypoint: MigrationUtils.MIGRATION_ENTRYPOINTS.BOOKMARKS_TOOLBAR,
      	  }),
        };
    		document.getElementById("new_toolbar").addEventListener("mousedown", (e) => {
    		  const button = e.target.closest("toolbarbutton");
    		  if (button?.id && customHandlers[button.id]) customHandlers[button.id](button, e);
    		});
    
        // Background color
        if (new_tb_color) {
             new_toolbar.classList.add("ntb_bg_color");
           }
    
    // On quitting Firefox: delete Prefs, if new_tb_save = false
        if (!new_tb_save) {
             Services.obs.addObserver(function observer(subject, topic, data) {
                 if (topic === "quit-application-granted") {
                     try {
                         Services.prefs.clearUserPref(pref_new_toolbar_state);
                         Services.prefs.clearUserPref(pref_position);
                     } catch (e) { }
                     Services.obs.removeObserver(observer, "quit-application-granted");
                 }
             }, "quit-application-granted");
          };
    
    let css =`
    
    #main-window {
        --ug-newbar_basewidth: calc(2 * ${new_tb_btn_size} + 16px);  /* Minimalgroesse = Groesse Buttons */
        --ug-newbar_width: calc(var(--ug-newbar_basewidth) + ${new_tb_border_width} + 2 * `+new_tb_size+`);
    }
    
    /*--  Buttons  --*/
    
    /* Button sizes */
    #new_toolbar {
        --toolbarbutton-inner-padding: ${new_tb_btn_size} !important;
        --toolbarbutton-outer-padding: 0px !important;
    }
    
    /*  On/Off Button  */
    #NewToolbar_button.off_mode:not(:hover, :active) .toolbarbutton-icon {
        opacity: 0.4;
    }
    
    /*  Button icon adjusts to Toolbar Position  */
    #NewToolbar_button.left_mode .toolbarbutton-icon,
    #NewToolbar_position_Con.left_mode :is(image, img) {
        transform: rotate(180deg);
    }
    #NewToolbar_button.bottom_mode .toolbarbutton-icon,
    #NewToolbar_position_Con.bottom_mode :is(image, img) {
        transform: rotate(90deg);
    }
    #NewToolbar_button.top_mode .toolbarbutton-icon,
    #NewToolbar_position_Con.top_mode :is(image, img) {
        transform: rotate(-90deg);
    }
    
    /*  Menuitem  */
    #NewToolbar_position_Con :is(image, img) {
        fill: currentColor !important;
        list-style-image: url("${ImagePathSW}");
        content: url("${ImagePathSW}") !important;
    }
    #main-window[customizing] :is(#NewToolbar_position_Con, #sw_separator) {
        display: none !important;
    }
    
    #unified-extensions-button[hidden] {
        visibility: visible !important;
        display: flex !important;
    }
    
    /*--  Browser adjustments  --*/
    
    #browser.right_mode {
        transition: padding-right 0.25s ease !important;
    }
    #browser.top_mode {
        transition: padding-top 0.25s ease !important;
    }
    #browser.left_mode {
        transition: padding-left 0.25s ease !important;
    }
    #browser.bottom_mode {
        transition: padding-bottom 0.25s ease !important;
    }
    
    #browser:not(.off_mode).right_mode {
        padding-right: var(--ug-newbar_width) !important;
    }
    #browser:not(.off_mode).left_mode {
        padding-left: var(--ug-newbar_width) !important;
    }
    #browser:not(.off_mode).bottom_mode {
        padding-bottom: var(--ug-newbar_width) !important;
    }
    #browser:not(.off_mode).top_mode {
        padding-top: var(--ug-newbar_width) !important;
    }
    
    /*--  Basics / Right  --*/
    
    #toolbox_new {
        position: fixed;
        z-index: 2 !important;
        display: flex;
        width: fit-content;
        top: var(--height_newbar_top);
        right: 0px;
    }
    #new_toolbar {
        display: flex;
        min-width: var(--ug-newbar_width) !important;
        width: var(--ug-newbar_width) !important;
        min-height: var(--ug-newbar_basewidth) !important;
        height: var(--height_newbar) !important;
        align-items: center !important;
        overflow: hidden !important;
        margin-inline: 0px;
        padding-block: 8px;
        padding-inline: 0px;
        border-width: 0px;
        border-style: solid !important;
        border-color: ${new_tb_border_color} !important;
        border-left-width: ${new_tb_border_width};
        border-right-width: 0px;
    }
    
    #toolbox_new:not(.bottom_mode, .top_mode) #new_toolbar:not([customizing]) {
        max-width: var(--ug-newbar_width) !important;
        transition: width 0.25s ease, max-width 0.25s ease, min-width 0.25s ease, border-left-width 0.125s ease;
    }
    
    #toolbox_new #new_toolbar:not([customizing]).off_mode {
        min-width: 0px !important;
        width: 0px !important;
        max-width: 0px !important;
        min-height: unset !important;
        max-height: unset !important;
        border-width: 0px !important;
        box-shadow: none !important;
    }
    
    #new_toolbar:not([customizing]).off_mode > :is(.toolbarbutton-1, toolbaritem) {
        opacity: 0 !important;
    }
    #new_toolbar > :is(.toolbarbutton-1, toolbaritem),
    #new_toolbar toolbarpaletteitem > :is(.toolbarbutton-1, toolbaritem) {
        margin-block: ${new_tb_distance} !important;
        margin-inline: var(--toolbarbutton-outer-padding) !important;
        opacity: 1 !important;
        transition: opacity 0.125s ease-out;
    }
    
    /*--  Left  --*/
    
    #toolbox_new.left_mode {
        right: unset;
        left: 0px;
    }
    #toolbox_new.left_mode #new_toolbar:not([customizing]) {
        border-left-width: 0px;
        border-right-width: ${new_tb_border_width};
        transition: width 0.25s ease, max-width 0.25s ease, min-width 0.25s ease, border-right-width 0.125s ease;
    }
    
    /*--  Bottom / Top  --*/
    
    #toolbox_new.bottom_mode {
        top: unset;
        bottom: 0px;
    }
    
    #toolbox_new:is(.bottom_mode, .top_mode) #new_toolbar:not([customizing]) {
        flex-direction: row !important;
        min-height: 0px !important;
        height: var(--ug-newbar_width) !important;
        max-height: var(--ug-newbar_width) !important;
        min-width: 0px !important;
        width: 100vw !important;
        padding-block: 0px;
        padding-inline: 8px;
        border-inline-width: 0px;
        border-top-width: ${new_tb_border_width};
        /*justify-content: center !important;*/    /* content position, "center" or "flex-end", optional */
        transition: height 0.25s ease, max-height 0.25s ease, min-height 0.25s ease, border-top-width 0.125s ease !important;
    }
    
    #toolbox_new:where(.bottom_mode, .top_mode) #new_toolbar:not([customizing]).off_mode {
        min-height: 0px !important;
        height: 0px !important;
        max-height: 0px !important;
        max-width: unset !important;
    }
    
    #toolbox_new:where(.bottom_mode, .top_mode) #new_toolbar:not([customizing]) > :is(.toolbarbutton-1, toolbaritem) {
        margin-block: var(--toolbarbutton-outer-padding) !important;
        margin-inline: ${new_tb_distance} !important;
    }
    
    /*--  Top  --*/
    
    #toolbox_new.top_mode #new_toolbar:not([customizing]) {
        border-top-width: 0px;
        border-bottom-width: ${new_tb_border_width};
        transition: height 0.25s ease, max-height 0.25s ease, min-height 0.25s ease, border-bottom-width 0.125s ease !important;
    }
    
    /*--  Fullscreen  --*/
    
    /* Mac / Video Fullscreen only */
    #main-window[inDOMFullscreen]:not([customizing]) #toolbox_new {
        visibility: collapse !important;
    }
    #main-window[inDOMFullscreen]:not([customizing]) #browser {
        padding: 0 !important;
    }
    /* Windows Fullscreen Video + Normal */
    @media (-moz-platform: windows) {
    #main-window[inFullscreen]:not([customizing]) #toolbox_new {
        visibility: collapse !important;
    }
    #main-window[inFullscreen]:not([customizing]) #browser {
        padding: 0 !important;
    }
    }
    
    /*--  customizing  --*/
    
    #main-window[customizing] #toolbox_new {
        top: unset !important;
        bottom: 0px !important;
        right: 0px !important;
        left: unset !important;
    }
    #new_toolbar[customizing] {
        height: calc(100vh - var(--height_newbar_c)) !important;
        width: initial !important;
        transition: none !important;
        border-color: transparent !important;
    }
    #new_toolbar[customizing]::after {
        content:"";
        position: absolute;
        top: 0px;
        right: 0px;
        height: 100%;
        width: calc(100% - ${new_tb_border_width});
        outline: 1px solid ${new_tb_border_color};
        pointer-events: none;
    }
    #main-window:not([customizing]) #new_toolbar[customizing].off_mode {
        min-width: 0px !important;
        width: 0px !important;
        min-height: 0px !important;
        height: 0px !important;
        border-width: 0px !important;
    }
    #customization-container {
        margin-right: var(--ug-newbar_width) !important;
    }
    
    /*--  Background colors  --*/
    
    /* Custom toolbar background color if enabled */
    #new_toolbar.ntb_bg_color {
        background-color: ${new_tb_bg_color} !important;
    }
    
    /*- Background for themes, if background images are tiled, try theme_fix options above -*/
    :root[lwtheme] #new_toolbar:not(.ntb_bg_color) {
        background-color: var(--lwt-accent-color, var(--toolbar-bgcolor)) !important;
    }
    :root[lwtheme][lwtheme-image] #new_toolbar:not(.ntb_bg_color) {
        background-image: var(--lwt-header-image) !important;
        background-position: right 0px top 0px !important;
    }
    
    /*-  test colors  -*/
    /*
    #new_toolbar image {
        outline: 1px solid green !important;
        outline-offset: -1px !important;
    }
    */
    
     `;
    
    if (theme_fix) {
      css += `
    /*-  Fix #1 for themes with tiled background images  -*/
    
    :root[lwtheme][lwtheme-image] #new_toolbar:not(.ntb_bg_color) {
        background: var(--lwt-header-image) !important;
        background-repeat: no-repeat !important;
        background-size: cover !important;
        background-position: right 0px top 0px !important;
    }
    :root[lwtheme][lwtheme-image] #toolbox_new:is(.bottom_mode, .top_mode) #new_toolbar:not(.ntb_bg_color) {
        background-size: auto !important;
    }
     `;
    }
    
    if (theme_fix_2) {
      css += `
    /*-  Fix #2b width for themes with tiled background images  -*/
    
    :root[lwtheme][lwtheme-image] #toolbox_new #new_toolbar:not(.ntb_bg_color) {
         background: transparent !important;
    }
    
    :root[lwtheme][lwtheme-image] #new_toolbar:not(.ntb_bg_color)::before {
        content: "" ;
        position: absolute;
        top: 0px;
        right: 0px;
        min-width: var(--height_newbar) !important;
        width: var(--height_newbar) !important;
        min-height: var(--ug-newbar_width) !important;
        height: var(--ug-newbar_width) !important;
        pointer-events: none;
        z-index: -1 !important;
        background: var(--lwt-header-image) !important;
        background-repeat: no-repeat !important;
        transform: rotate(-90deg) translateX(var(--ug-newbar_width)) !important;
        transform-origin: 100% 100% !important;
    }
    
    :root[lwtheme][lwtheme-image] #new_toolbar:not(.ntb_bg_color, [customizing])::before {
        transition: height 0.25s ease, max-height 0.25s ease, min-height 0.25s ease, margin-top 0.25s ease;
        margin-top: 0px;
    }
    
    :root[lwtheme][lwtheme-image] #new_toolbar:not(.ntb_bg_color, [customizing]).off_mode::before {
        min-height: 0px !important;
        height: 0px !important;
        max-height: 0px !important;
        margin-top: var(--ug-newbar_width);
    }
    
    :root[lwtheme][lwtheme-image] #toolbox_new:is(.bottom_mode, .top_mode) #new_toolbar:not(.ntb_bg_color, [customizing])::before {
        transform: scaleX(-1) !important;
        transform-origin: 50% 50% !important;
        min-height: var(--ug-newbar_width) !important;
        height: var(--ug-newbar_width) !important;
        min-width: 0px !important;
        width: 100vw !important;
        transition: height 0.25s ease, max-height 0.25s ease, min-height 0.25s ease;
        margin-top: unset;
    }
    
    :root[lwtheme][lwtheme-image] #toolbox_new:is(.bottom_mode, .top_mode) #new_toolbar:not(.ntb_bg_color, [customizing]).off_mode::before {
        min-height: 0px !important;
        height: 0px !important;
        max-height: 0px !important;
        margin-top: unset;
    }
    
    :root[lwtheme][lwtheme-image] #new_toolbar:not(.ntb_bg_color)[customizing]::before {
        width: calc(100vh - var(--height_newbar_c)) !important;
    }
    
    #main-window:not([customizing]) #toolbox_new #new_toolbar:not(.ntb_bg_color)[customizing].off_mode::before {
        min-width: 0px !important;
        width: 0px !important;
        min-height: 0px !important;
        max-height: 0px !important;
        height: 0px !important;
        border-width: 0px !important;
        margin-top: unset !important;
    }
     `;
    }
    
    if (separator_fix) {
      css += `
    /* Adjustments for Separator Scripts  */
    
    #new_toolbar toolbarseparator {
        width: calc(var(--ug-newbar_width) - ${new_tb_border_width} - 6px) !important;
        margin: 5px 0px !important;
        border-block-color: hsl(0, 0%, 0%, 0.45) hsl(0, 0%, 100%, 0.55) !important;
        transition: width 0.125s ease !important;
    }
    #new_toolbar :is(toolbarspacer, toolbarspring, toolbarseparator) {
        min-width: 0px !important;
    }
    #new_toolbar:not([customizing]).off_mode toolbarseparator {
        width: 0px !important;
    }
    #toolbox_new:where(.bottom_mode, .top_mode) #new_toolbar:not([customizing]) toolbarseparator {
        transform: rotate(-90deg) !important;
        margin: 0px !important;
    }
    #new_toolbar[customizing] toolbarseparator {
        margin-block: 16px !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

    Icons, unverändert: icons.zip

  • ShadowRoot: Neue Aufruf-Methode für CSS-Regeln

    • Horstmann
    • 23. Dezember 2025 um 14:50

    Ich bin 100% pro Separierung von CSS und JS! :)
    Auch wegen der Darstellung im Editor, und des einfachen Live Bearbeiten in den Browser Werkzeugen.
    Beim Bauen und Testen von JS Scripts benutze ich solange es geht separate CSS Dateien, oder benutze ein CSS Editor Fenster zur Fehlersuche im CSS Teil.

    Aber versucht das mal den Leuten zu verkaufen. ;)
    Abgesehen von diesem hier, fällt mir kein JS Script ein, das kein integriertes CSS benutzt, und nicht versucht möglichst alle User Einstellungen oben zu sammeln.

    In diesem speziellen Fall fand ich es nur praktisch alles in einer Datei zu haben; vermutlich sind die meisten ::part Modifikationen eher übersichtlich.

    shadow-root scheint generell in JS Scripts zu funktionieren, wenn man etwa sss.loadAndRegisterSheet(uri, sss.AUTHOR_SHEET); statt ....AGENT_SHEET benutzt. :/

  • ShadowRoot: Neue Aufruf-Methode für CSS-Regeln

    • Horstmann
    • 23. Dezember 2025 um 13:30

    Ich habe das mal etwas reduziert, scheint soweit zu funktionieren. :/
    Icons in shadow-root könnte man damit im Prinzip auch ändern mit einem relativen Pfad, dazu habe ich aber keine komplett überzeugende Lösung gefunden.

    Der Unterschied zum Original ist, dass man nur das JS Script benötigt, in das man die ::part Veränderungen direkt einträgt, ohne zusätzliche CSS Datei.

    JavaScript
    // shadow_edit.uc.js
    // Based on script by BrokenHeart ==>
    // https://www.camp-firefox.de/forum/thema/132865-shadowroot-neue-aufruf-methode-fuer-css-regeln/
    // After script changes, restart with Clear StartUp Cache => about:support
    
    (function() {
      if (!window.gBrowser) return;
      
        const css = `
    
        /* Hamburger Menü */
    
        #appMenu-popup::part(content) {
            padding: 20px !important;
            border-width: 4px !important;
            border-color: red !important;
        }
    
        /* Scrollbuttons(Pfeile links und rechts) in Tableiste umranden */
    
        #tabbrowser-arrowscrollbox::part(scrollbutton-up),
        #tabbrowser-arrowscrollbox::part(scrollbutton-down) {
            outline: 2px solid red !important;
            outline-offset: -2px !important;
        }
    
        /* Rahmen um Lesezeichen-Hinzufügen-Dialog */
    
        #editBookmarkPanel::part(content) {
          border: 3px solid red !important;
          filter: drop-shadow(1px 1px 2px rgba(16,16,16,0.66)) !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.AUTHOR_SHEET);
    
    })();
    Alles anzeigen
  • Sidebar für FF 146 - Erster Versuch

    • Horstmann
    • 23. Dezember 2025 um 11:02
    Zitat von BrokenHeart

    Auch dein Szenario kann ich nicht nachstellen. Ich vermute mal, dass das, was du meinst auch mit dem Schließen-Button in der Sidebar zusammenhängt. Wenn du mal diesen Button nicht benutzt, zeigt er dann das gleiche Verhalten?

    Das Problem ist halt, dass es das Problem hier gibt, aber nicht geben sollte. ;)
    Wobei ich glaube dass Sören auch Macs benutzt, evtl. liegt darin die Ursache, wenn das bei dir nicht reproduzierbar ist. :/

    Würde mich zwar etwas wundern, aber es gibt schon ein paar OS spezifische Feinheiten in der Sidebar und drum herum.

  • Sidebar für FF 146 - Erster Versuch

    • Horstmann
    • 23. Dezember 2025 um 09:12
    Zitat von BrokenHeart

    Natürlich sollte keine leere Sidebar erscheinen, aber dieses Problem ist entweder gar nicht existent oder man ist genau einmal damit konfrontiert und aktiviert dann die Sidebar.

    Hier mal 2 Szenarien mit leerer Sidebar, am Mac im Nigthly.
    S. links oben der Buttonstatus, und unten die Sidebar anzeigen Einstellung.
    Dann noch das erwähnte Problem, das sich in manchen Kombinationen die Sidebar nicht mehr rechts/links verschieben lässt.

  • Sidebar für FF 146 - Erster Versuch

    • Horstmann
    • 22. Dezember 2025 um 23:51
    Zitat von BrokenHeart

    Keine Ahnung, warum er bei dir dieses Verhalten zeigt. Ich habe allerdings etliche Anpassungen, aber kann mir kaum vorstellen, dass es damit was zu tun haben könnte, dass es wie beschrieben bei mir läuft. :/

    Spiel das ein paarmal durch.
    ZB Sidebar deaktivieren mit dem Sidebar Button in der Toolbar, schauen was passiert bei hover in dem designierten Bereich; gleiches testen mit Sidebar versuchen zu deaktivieren bzw. schliessen mit dem Close Button in der Sidebar, oder der Option im Sidebar ... Menü, etc..

  • Sidebar für FF 146 - Erster Versuch

    • Horstmann
    • 22. Dezember 2025 um 21:05

    Der Sidebar Header bleibt anscheinend dauernd bestehen, und bei deaktivierter Sidebar ist die Hover-Aktivierungs-Fläche (...) noch aktiv, ruft aber eben noch diesen Header auf, nur der Rest vom Inhalt ist versteckt.

    Der Sinn vom Code könnte sein, eine aktivierte Sidebar nur bei hover zu zeigen, sonst eben nicht. :/

    Abgesehen davon ist das Hoververhalten, bzw. das automatische Einklappen, inkonsistent.
    Das CSS passt einfach nicht, und die Einbindung von Styles im JS Code macht das Troubleshooting nicht leichter.

  • Sidebar für FF 146 - Erster Versuch

    • Horstmann
    • 22. Dezember 2025 um 18:27

    Ah, danke für die Erklärung. :)
    Also nur hover. ;)

    Das hier ist vermutlich nicht mehr aktuell, soweit ich die aktuellen Diskussionen zur Sidebar verstanden habe; aber wie von Sören schon erwähnt, sind die Funktionen bis auf hover schon gegeben, oder via CSS zugänglich.

    Hover Verhalten lässt sich - meiner beschränkten Erfahrung nach - idR komplett mit CSS regeln, für die dynamische Berechnung der Positionierung könnte JS von Vorteil sein, va wegen fixed, aber das nur als Gedanken dazu.

  • Sidebar für FF 146 - Erster Versuch

    • Horstmann
    • 22. Dezember 2025 um 17:00

    Kann mir jemand erklären, was das Script eigentlich macht, ausser dem Hoververhalten, und dass man sie nicht mehr sauber abschalten kann ohne Neustart? :/

    Für das Hoverdingens gibt es schon ewig CSS Lösungen, den Rest an Funktionen seh ich nicht direkt.
    Vielleicht noch ein Link zu übliche Sidebar von Alice0775, ich kenn mich ja nicht so aus mit diesen Scripts. ?(

  • Icon für Lesezeichen-Ordner nicht mehr in Farbe (CSS-Code streikt)

    • Horstmann
    • 21. Dezember 2025 um 17:06
    Zitat von .DeJaVu

    Frage: muss es für die Menüzeile jetzt zwingend base64 sein? Da ich diese dahingehend nie nutze, ist mir erst jetzt aufgefallen, dass die Ordnersymbole die von Firefox sind. Als Pfad nimmt Firefox es nicht, nur als base64.

    Diese base64 Icons sind direkt in den Code geschrieben, was man auch mit .svg Icons machen könnte.
    Ist aber sehr unelegant.

    Am Mac kann ich die Menüleiste nicht ändern, aber das Prinzip wäre generell sowas, die Lösung von Mitleser , von da wo du auch schon vorher gefragt hattest. ;)

  • Suchfeld hellblau und leert sich nicht mehr, Scriptfehler?

    • Horstmann
    • 21. Dezember 2025 um 15:27
    Zitat von Mira_Belle

    Zur Unterstützung nutzte ich Perplexity, eine KI mit Internetzugriff, da ich Hilfe benötigte bei den Internas von Mozilla.

    Ein Bekannter hat Perplexity in letzter Zeit auch ab und zu probiert; das ist zwar besser als Chat Gpt, analysiert aber nicht den Firefox Code an sich, sondern nur externe Referenzen zum jeweiligen Thema und Zusammenhang.
    D.h., wenn nicht jemand ausserhalb von Mozilla was dazu geschrieben hat, kannste das Ganze knicken. ;)

  • Tab Leiste nach angehefteten Tabs vergrößern

    • Horstmann
    • 19. Dezember 2025 um 21:21

    Oder du benutzt bei Gelegenheit auch mal die Suchfunktion.
    Ausserdem: *{ ;)

  • Tab Leiste nach angehefteten Tabs vergrößern

    • Horstmann
    • 19. Dezember 2025 um 19:31
    Zitat von .DeJaVu

    Bei vor/zurück/reload funktioniert es, die nutzen diese Elemente, nur steht das weiter oben auch noch mal für verschiedene (separat). Nur das untere wird nicht verändert, wo es für Erweiterungen angezeigt wird. Steht auch ausserhalb com body-Element.

    Tooltips kann man nur begrenzt mit normalem CSS ändern, für Einige muss man über JS oder das shadowchrome Dingens gehen.
    S. auch die Links im Script das Andreas gerade gepostet hat.

  • Seitennavigation - Fly Out Menü

    • Horstmann
    • 18. Dezember 2025 um 21:55

    Wer hat hier mit Popups angefangen? :whistling:

    Kleiner Test; quasi wie ein schlechteres Overflow Menü, der Button lässt sich aber beliebig verschieben.

    JavaScript
    // Firefox
    // 00-popup_toolbar-test3.uc.js
    // Popup panel with toolbar inside
    // Kudos to Aris and Mitleser
    
    // Open / close panel with button, no autoclose
    // Rotate toolbar via right-click/contextmenu, only on this button or this toolbar
    // User settings in JS and CSS code blocks
    // Last states are saved on restart
    // Preferences found in about:config, search for userChrome.popup
    
    // User settings in JS and CSS block
    
    // ATTENTION: Some system buttons can still be moved to additional/custom toolbars, but they will have no function.
    // There is a patch by @BrokenHeart: https://www.camp-firefox.de/forum/thema/138875-fix-toolbar-buttons-reagieren-nicht-mehr-ab-ff-134/
    
    // Version Test 3
    // Bugs: likely; Extension buttons don't work in this toolbar
    
    (function() {
      if (!window.gBrowser)
        return;
    
      if (Services.prefs.getBoolPref('svg.context-properties.content.enabled') == false) {
        Services.prefs.setBoolPref('svg.context-properties.content.enabled', true);
      }
    
    // User settings
    // After script changes, restart with Clear StartUp Cache => about:support
    
      // Icons
    
      // Choose icon: true = custom icon , false = Firefox icon
      const custom_icon = false;
    
      // Icon files
      const btn_icon = 'toolbar_switch_4.svg';  // Custom icon
      const btn_iconFx = 'chrome://global/skin/icons/arrow-right.svg';  // Firefox icon
    
      // Custom Icons expected in profile-name/chrome/icons folder ("icons" folder needs to be created)
      // path to icon folder named "icons" inside profile folder
      const iconPath = '/chrome/icons/';
    
    // End of user settings
    
      // get path to profile folder
      const curProfDir = PathUtils.toFileURI(PathUtils.join(PathUtils.profileDir));
    
      let ImagePath = btn_iconFx;
      if (custom_icon) {
         ImagePath = curProfDir + iconPath + btn_icon;
         }
    
    // Button
      try {
        CustomizableUI.createWidget({
          id: 'popup_button',
          defaultArea: CustomizableUI.AREA_NAVBAR,
          label: 'Popup Button',
          tooltiptext: 'Popup',
          overflows: false,
          onCreated: (this_button) => {
            this_button.style.MozContextProperties = 'fill, stroke, fill-opacity, stroke-opacity';
            this_button.style.listStyleImage = 'url("' + ImagePath + '")';
            this_button.style.minWidth = 'fit-content';
          }
        });
      } catch (e) {}
    
    // Popup panel
      let panel = document.createXULElement("panel");
      panel.setAttribute("id", "tool_popup");
      panel.setAttribute("type", "arrow");
      panel.setAttribute("noautohide", "true");
      panel.setAttribute("flip", "both");
      panel.setAttribute("role", "group");
      panel.classList.add("panel-no-padding");
    
      // let box = document.createXULElement("vbox");
      let box = document.createXULElement("toolbox");
    
      box.setAttribute("id", "tool_pop_box");
      panel.appendChild(box);
    
      PopupSet = document.getElementById("mainPopupSet");
      PopupSet.appendChild(panel);
    
       // position
      function openPopupWithSmartPosition(button, savedPosition = null) {
      let position = savedPosition || "bottomright topright";
    
      if (!savedPosition) {
        let btnRect = button.getBoundingClientRect();
        let winWidth = window.innerWidth;
    
        let margin = winWidth * 0.35; // 5 %
    
        if (btnRect.left < margin) {
          position = "bottomleft topleft";
        } else if (btnRect.right > winWidth - margin) {
          position = "bottomright topright";
        }
        Services.prefs.setCharPref("userChrome.popup_position", position);
      }
        panel.openPopup(button, position);
      }
    
    // toolbar
      const toolbar = document.createXULElement('toolbar');
          toolbar.id = 'pop_toolbar';
      	  //toolbar.setAttribute('orient', 'vertical');
          toolbar.setAttribute('customizable', true);
      	  toolbar.setAttribute('mode', 'icons');
      	  toolbar.setAttribute('context', 'toolbar-context-menu');
      	  toolbar.setAttribute('class','toolbar-primary chromeclass-toolbar browser-toolbar customization-target');
          toolbar.setAttribute('label', 'Popup Toolbar');
          toolbar.setAttribute("accesskey","");
    
      CustomizableUI.registerArea('pop_toolbar', {legacy: true});
      CustomizableUI.registerToolbarNode(toolbar);
    
      box.appendChild(toolbar);
    
      // disable extension buttons
      setTimeout(() => {
        let extBtns = panel.querySelectorAll('.unified-extensions-item-action-button');
        extBtns.forEach(btn => {
          btn.addEventListener("command", e => e.stopPropagation(), true);
          btn.addEventListener("click", e => e.stopPropagation(), true);
        });
      }, 200);
    
      // disable moving to overflow menu
      document.addEventListener("aftercustomization", () => {
        const btn = document.getElementById("popup_button");
        if (!btn) return;
    
        const parent = btn.closest("#widget-overflow-fixed-list");
        if (parent) {
          CustomizableUI.addWidgetToArea('popup_button', CustomizableUI.AREA_NAVBAR);
        }
      });
    
      // disable menuitem move to overflow menu
      let moveMenu = document.getElementById("toolbar-context-menu");
    
      moveMenu.addEventListener("popupshowing", (event) => {
        const trigger = moveMenu.triggerNode;
        if (!trigger) return;
        const isPopupButtonOrWrapper =
          trigger.id === "popup_button" || trigger.id === "wrapper-popup_button";
    
        const moveToPanelItem = moveMenu.querySelector(".customize-context-moveToPanel");
        if (moveToPanelItem) {
          if (isPopupButtonOrWrapper) {
            moveToPanelItem.setAttribute("disabled", "true");
          } else {
            moveToPanelItem.removeAttribute("disabled");
          }
        }
      });
    
      (function pop_button() {
        let btn_exists = document.getElementById('popup_button');
        if (btn_exists) {
          btn_exists.addEventListener('click', event => {
            if (event.button === 0) {
              if (panel.state === "open") {
                  panel.hidePopup();
                  Services.prefs.setBoolPref("userChrome.popup_open", false);
                } else {
                  openPopupWithSmartPosition(event.currentTarget);
                  Services.prefs.setBoolPref("userChrome.popup_open", true);
                }
             }
          });
        } else {
          setTimeout(pop_button, 100);
        }
      })();
    
      let savedPopupState = false;
      let savedPosition = "bottomright topright";
    
      try {
        savedPopupState = Services.prefs.getBoolPref("userChrome.popup_open");
        savedPosition = Services.prefs.getCharPref("userChrome.popup_position");
      } catch (e) {}
    
      if (savedPopupState) {
        setTimeout(() => {
          const btn = document.getElementById("popup_button");
          if (btn && panel.state !== "open")
            openPopupWithSmartPosition(btn, savedPosition);
        }, 200);
      }
    
    	// Force display during customization, code by Aris
    	document.addEventListener("beforecustomization", () => {
    	  document.getElementById("navigator-toolbox").appendChild(toolbar);
    	});
    
      document.addEventListener("aftercustomization", () => {
        box.appendChild(toolbar);
        const wasOpen = Services.prefs.getBoolPref("userChrome.popup_open", false);
        if (wasOpen) {
          setTimeout(() => {
            const btn = document.getElementById("popup_button");
            if (btn && panel.state !== "open") openPopupWithSmartPosition(btn);
          }, 200);
        }
      });
    
    // menuitem contextmenu rotate
      let menu = document.getElementById('toolbar-context-menu');
      let menuitem_pop = document.createXULElement("menuitem");
      menuitem_pop.id = "pop_direction_Context";
      menuitem_pop.setAttribute("label", "Popup Direction");
      menuitem_pop.setAttribute("closemenu", "none");
      menuitem_pop.classList.add("menuitem-iconic");
      menu.insertBefore(menuitem_pop, document.querySelector(".viewCustomizeToolbar"));
    
      let menuseparator_pop = document.createXULElement("menuseparator");
      menuseparator_pop.id = "pop_separator";
      menu.insertBefore(menuseparator_pop, menuitem_pop.nextSibling);
    
      menu.addEventListener("popupshowing", (event) => {
        let trigger = menu.triggerNode;
        let isTestButton = trigger && trigger.id === "popup_button";
        let isInsideZusatzToolbar = false;
        if (trigger) {
          let toolbar = trigger.closest("#pop_toolbar");
          isInsideZusatzToolbar = !!toolbar;
        }
        let visible = isTestButton || isInsideZusatzToolbar;
        menuitem_pop.hidden = !visible;
        menuseparator_pop.hidden = !visible;
      });
    
      document.getElementById('pop_direction_Context').addEventListener("click", rota_pop);
      function rota_pop(event) {
        if (event.button === 0) {
          const new_popbarrotate = document.getElementById('pop_toolbar');
          new_popbarrotate.classList.toggle("pop_horizontal");
          const isRotated = new_popbarrotate.classList.contains("pop_horizontal");
          Services.prefs.setBoolPref("userChrome.popup_rotate", isRotated);
        }
      }
    
      let savedState_p = false;
      try {
        savedState_p = Services.prefs.getBoolPref("userChrome.popup_rotate");
      } catch(e) {}
      if (savedState_p) {
        toolbar.classList.add("pop_horizontal");
      }
    
      const css = `
    
    
    :root {
        --ug-popbar_width: calc(2 * var(--toolbarbutton-inner-padding) + 16px);
    
    /*--  user settings  --*/
    
        --ug-popbar_addSize: 1px;
    
        --ug-popbar_bg_color: hsla(200, 45%, 87%, 1);
        --ug-popbar_radius: 8px;
    
        --ug-pop_border_width: 1px;
        --ug-pop_border_color: orange;
    
        /* Use default background/radius */
        /*
        --ug-popbar_bg_color: var(--arrowpanel-background);
        --ug-popbar_radius: var(--arrowpanel-border-radius);
        --ug-pop_border_color: var(--arrowpanel-border-color);
         */
    
        --ug-icon_direction: 90deg;
    }
    
    /*--  user settings end  --*/
    
    #tool_popup {
        --panel-background: var(--ug-popbar_bg_color) !important;
        border-radius: var(--ug-popbar_radius);
        border-color: var(--ug-pop_border_color);
        border-style: solid !important;
        border-width: var(--ug-pop_border_width);
    }
    
    #tool_pop_box {
        overflow: hidden !important;
        background: none !important;
    /*     justify-content: center !important;
        align-items: center !important; */
    }
    
    #pop_toolbar {
        flex-direction: column !important;
        overflow: hidden !important;
        padding: 4px var(--ug-popbar_addSize) !important;
        min-height: var(--ug-popbar_width) !important;
        height: fit-content;
        min-width: var(--ug-popbar_width) !important;
        width: fit-content;
        z-index: 4 !important;
        background-color: transparent !important;
    }
    
    #pop_toolbar > :is(.toolbarbutton-1, toolbaritem),
    #pop_toolbar toolbarpaletteitem > :is(.toolbarbutton-1, toolbaritem) {
        margin-inline: 0px !important;
        margin-block: 2px !important;
        padding-inline: 0px !important;
        z-index: 8 !important;
    }
    
    /*--  horizontal  --*/
    
    #pop_toolbar.pop_horizontal:not([customizing]) {
        flex-direction: row !important;
        padding: var(--ug-popbar_addSize) 4px !important;
    }
    #pop_toolbar.pop_horizontal:not([customizing]) > :is(.toolbarbutton-1, toolbaritem) {
        margin-inline: 2px !important;
        margin-block: 0px !important;
    }
    
    /*--   drag menu item   --*/
    
    #pop_direction_Context {
        -moz-context-properties: fill, fill-opacity !important;
        fill: currentColor !important;
    }
    #pop_direction_Context :is(image, img) {
        list-style-image: url(chrome://global/skin/icons/reload.svg);
        content: url(chrome://global/skin/icons/reload.svg) !important;
        height: 14px !important;
        width: 14px !important;
    }
    
    /*--   button   --*/
    
    #popup_button:not([open], :hover, :active) image {
        opacity: 0.45;
    }
    #popup_button[open]:not(:hover, :active) image {
        background-color: transparent !important;
    }
    #popup_button image {
        transform: rotate(var(--ug-icon_direction));
    }
    
    /*- extension buttons disabled -*/
    
    #pop_toolbar .unified-extensions-item {
        color: hsla(0, 100%, 50%, 1) !important;
    /*     pointer-events: none !important; */
    }
    #pop_toolbar .unified-extensions-item-action-button {
        position: relative;
    }
    #pop_toolbar .unified-extensions-item-action-button::after {
        box-sizing: border-box;
        position: absolute;
        display: flex;
        content: url(chrome://global/skin/icons/close.svg);
        color: hsla(0, 100%, 50%, 0.6) !important;
        top: 0;
        right: 0;
        width: 100%;
        height: 100%;
        padding: 3px;
    }
    
    /*---  customizing  ---*/
    
    :root[customizing] #tool_popup {
      visibility: hidden !important;
      pointer-events: none !important;
    }
    #pop_toolbar[customizing] {
        position: fixed;
        top: 50%;
        left: 0px;
        transform: translateY(-50%);
        align-items: center !important;
        padding-inline: 2px !important;
        background-color: var(--ug-popbar_bg_color) !important;
        width: initial !important;
        padding-bottom: 48px !important;
        border-radius: 0 var(--ug-popbar_radius) var(--ug-popbar_radius) 0;
        outline: var(--ug-pop_border_width, 1px) solid var(--ug-pop_border_color, grey);
        outline-offset: 0px;
    }
    #customization-content-container {
        margin-left: var(--ug-popbar_width) !important;
    }
    
    /*-  test colors  -*/
    /*
    #pop_toolbar image {
        outline: 1px solid green !important;
        outline-offset: -1px !important;
    }
    */
    
    /* shadow-root, this panel only */
    #tool_popup::part(content) {
        margin: 0px !important;
        border-width: 0px !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);
      sss.loadAndRegisterSheet(uri, sss.AUTHOR_SHEET);
    
    })();
    Alles anzeigen

    toolbar_switch_4.svg.zip

  • In about:addons werden Themes nicht komplett angezeigt

    • Horstmann
    • 17. Dezember 2025 um 17:16
    Zitat von BrokenHeart

    Ja, das ist die Lösung, welche ich schon 2021 im Eingangsbeitrag beschrieben hatte.

    Hoppla, etwas zu schnell durchgelesen.... ;)

  • In about:addons werden Themes nicht komplett angezeigt

    • Horstmann
    • 17. Dezember 2025 um 16:55
    Zitat von BrokenHeart

    Das Problem hatte ich (und wohl auch ein paar andere) auch schon. Lösung war, wenn ich das jetzt richtig zusammenfasse, sich eine neue IP-Adresse zu besorgen (Router Reset oder VPN). Kannst ja mal den ganzen Thread durchackern:

    Danke für die Antwort! :)

    Die Thread bin ich durchgegangen, letztlich hat aber das funktioniert:

    In about:addons Theme entfernen (Themename merken), Neustart, Theme finden und neu installieren.
    Das Theme wird dann wieder komplett angezeigt in about:addons.

    Ohne Neustart wird hier das Theme nicht komplett entfernt, satt installieren bekommt man aktivieren bei einem Versuch das Theme wieder reinzuholen. :/

  • In about:addons werden Themes nicht komplett angezeigt

    • Horstmann
    • 17. Dezember 2025 um 13:58

    In einem meiner Profile - nur dort - das ich heftig missbrauche als Testprofil für CSS und JS, werden plötzlich In about:addons die gespeicherten Themes nicht mehr komplett angezeigt - die Übersichtsbilder fehlen.

    Jüngste JS und CSS Codes habe ich deaktiviert, Erweiterungen wurden nicht hinzugefügt oder entfernt.
    Das Problem besteht auch beim Starten im Fehlerbehebungsmodus.

    Irgendeine Idee, ob da eine Präferenzdatei korrupt sein kann, die man löschen könnte? :/

  • Seitennavigation - Fly Out Menü

    • Horstmann
    • 14. Dezember 2025 um 19:24
    Zitat von FuchsFan

    Durch die Tests der anderen Varianten auf der rechten Seite gefällt es mir auch dort.

    Eine Sache, die den Aufwand für und Umfang von Leistenscripts - und eigentlich allen Scripts - massiv erhöht, ist das Bereitstellen von Varianten und extra Funktionen für den User. :|
    Die Möglichkeiten sind auch endlos, und jede(r) hätte gerne eine eigene Version. ;)

    Wenn ich eine Zusatzleiste haben wollte, würde ich eine von Aris vorschlagen, aber persönlich meine nehmen ;) ; meine extra Buttons sitzen eh einfach nur in einem getunten Overflow Menü - den Overflow Button klicken, alles ist im Popup, und wieder weg wenn das Popup schliesst. :)

  • Seitennavigation - Fly Out Menü

    • Horstmann
    • 14. Dezember 2025 um 17:26
    Zitat von FuchsFan

    Nun brauche ich nur noch hübsch zu machen, funktioniert. Prima!:thumbup::)

    Naja, etwas Arbeit bräuchte es schon noch um sauber zu funktionieren, aber ist quasi auch nur eine Fingerübung. ;)
    Wollte schon immer wissen wie ein frei verschiebbares Dingens klappen könnte - ob es Sinn macht oder nicht, das ist eine andere Frage. ^^

  • Seitennavigation - Fly Out Menü

    • Horstmann
    • 14. Dezember 2025 um 15:20
    Zitat von FuchsFan

    Nun wird für dich aber die Aufgabe bestehen, das auch für die horizontale Nutzung einzurichten. Also frisch voran!;):)

    Der Druck ... ;)

    Also denne, verschieben wieder mit dem ersten Button in der Leiste aktivieren/deaktivieren, Ausrichtung horizontal/vertikal über Kontextmenü (Rechtsklick).
    Ein paar User Einstellungen gibt es oben im JS Teil, und unten im CSS Bereich.

    Icons hängen an, können auch im JS Bereich auf Fx Icons umgestellt, oder eben für eigene Icons getauscht werden.

    JavaScript
    // Firefox Javascript
    
    // 00-dragger_leiste_test7.uc.js
    
    // Draggable toolbar
    // Show / hide toolbar button
    // Enable/disable dragging by clicking drag button in the new toolbar
    // Rotate dragbar via context menu of the new toolbar or toolbar button
    
    // ATTENTION: Some system buttons can still be moved to additional/custom toolbars, but they will have no function.
    // There is a patch by @BrokenHeart: https://www.camp-firefox.de/forum/thema/138875-fix-toolbar-buttons-reagieren-nicht-mehr-ab-ff-134/
    
    // User settings located at the beginning of JS and CSS code blocks
    
    // Dragleiste Test 7
    
    (function() {
      if (!window.gBrowser) return;
    
        if (Services.prefs.getBoolPref('svg.context-properties.content.enabled') == false) {
        	Services.prefs.setBoolPref('svg.context-properties.content.enabled', true );
        }
    
    // User settings JS
    // After script changes, restart with Clear StartUp Cache => about:support
    
        // false = use Firefox Icon, true = Custom Icon
        let custom_drag_icon  = false;         // On/Off Button
        let custom_drag_icon_drag  = false;    // Drag switch button in toolbar
    
        // Custom Icons
        let ButtonIcon = 'toolbar_4.svg';      // On/Off Button
        let ButtonIconDrag = 'drag_1.svg';     // Drag switch button
    
        // Firefox icons
        let ButtonIcon_Fx = 'chrome://browser/skin/sidebars-right.svg';         // On/Off Button
        let ButtonIconDrag_Fx = 'chrome://global/skin/icons/autoscroll.svg';    // Drag switch button
    
        // Custom Icons expected in profile-name/chrome/icons folder ("icons" folder needs to be created)
        // Get path to profile folder
        let ProfilePath = PathUtils.toFileURI(PathUtils.join(PathUtils.profileDir));
        // Path to icon folder named "icons" inside profile folder
        let IconPath = '/chrome/icons/';
    
        // Custom background color: false = Off ; true = On
        let drag_bg_color = true;
    
    // User settings JS end
    
        let ImagePath = ProfilePath + IconPath + ButtonIcon;
        if (!custom_drag_icon) {
           ImagePath = ButtonIcon_Fx;
           }
        let ImagePath_drag = ProfilePath + IconPath + ButtonIconDrag;
        if (!custom_drag_icon_drag) {
           ImagePath_drag = ButtonIconDrag_Fx;
           }
    
    // Toolbar
        let dragbox_New = document.createXULElement('toolbox');
        dragbox_New.setAttribute('orient','horizontal');
        dragbox_New.setAttribute('id','dragbox_New');
    
        let dragtb = document.createXULElement('toolbar');
        dragtb.id = 'new_dragbar';
    
        dragtb.setAttribute('customizable', true);
        dragtb.setAttribute("class","toolbar-primary chromeclass-toolbar browser-toolbar customization-target");
        dragtb.setAttribute('orient', 'vertical');
        dragtb.setAttribute('mode', 'icons');
        dragtb.setAttribute('context', 'toolbar-context-menu');
        dragtb.setAttribute("toolbarname", "Drag Toolbar");
        dragtb.setAttribute("label", "Drag Toolbar");
    
        dragbox_New.appendChild(dragtb);
    
        const drag_element = document.createElement("div");
        drag_element.id = "drag_diver";
        drag_element.appendChild(dragbox_New);
    
        document.getElementById('browser').parentNode.appendChild(drag_element);
    
        CustomizableUI.registerArea('new_dragbar', {legacy: true});
        CustomizableUI.registerToolbarNode(dragtb);
    
    // On/Off button
        try {
            CustomizableUI.createWidget({
              id: 'dragbar_off_button',
              defaultArea: CustomizableUI.AREA_NAVBAR,
              tooltiptext: 'Toggle Dragbar',
              label: 'Toggle Dragbar',
                onCreated: (this_button) => {
                this_button.style.setProperty('list-style-image', 'url("' + ImagePath + '")');
                this_button.style.MozContextProperties = 'fill, stroke, fill-opacity, stroke-opacity';
                this_button.style.minWidth = 'fit-content';
                }
            });
        } catch(e) { }
    
        document.getElementById('dragbar_off_button').addEventListener( "click", drag_offbar );
        function drag_offbar(event) {
          if (event.button === 0) {
            const new_dragbarer = document.getElementById('drag_diver');
            new_dragbarer.classList.toggle("dragbar_off_mode");
    
            const new_dragbarerBtn = document.getElementById('dragbar_off_button');
            new_dragbarerBtn.classList.toggle("dragbar_off_mode");
    
            const state = new_dragbarer.classList.contains("dragbar_off_mode");
            Services.prefs.setBoolPref("userChrome.drag_diver.off", state);
          }
        };
    
        let savedState = false;
        try {
          savedState = Services.prefs.getBoolPref("userChrome.drag_diver.off");
        } catch(e) {}
        if (savedState) {
           drag_element.classList.add("dragbar_off_mode");
           document.getElementById('dragbar_off_button').classList.add("dragbar_off_mode");
         };
    
    // Drag On/Off button
        try {
            CustomizableUI.createWidget({
              id: 'ntb_drag_btn',
              defaultArea: CustomizableUI.AREA_NAVBAR,
              label: 'Drag Toolbar',
              tooltiptext: 'Drag-mode On/Off',
              removable: false,
                onCreated: (drag_button) => {
                drag_button.style.setProperty('list-style-image', 'url("' + ImagePath_drag + '")');
                drag_button.style.MozContextProperties = 'fill, stroke, fill-opacity, stroke-opacity';
                drag_button.style.minWidth = 'fit-content';
                }
            });
        } catch(e) { }
    
        // Button in toolbar
        let add_parent = document.getElementById('new_dragbar');
        let add_btn = document.getElementById('ntb_drag_btn');
    
        let separator_dragbtn = document.createXULElement("toolbarseparator");
        separator_dragbtn.setAttribute('id', 'dragbtn_separator');
        // separator_dragbtn.setAttribute("class","chromeclass-toolbar-additional");
        // separator_dragbtn.setAttribute("customizableui-areatype","toolbar");
    
        // Button 1st child
        add_parent.insertBefore(separator_dragbtn, add_parent.firstChild);
        add_parent.insertBefore(add_btn, separator_dragbtn);
    
        // Button last child
        // setTimeout(() => {
        // add_parent.appendChild(add_btn);
        // add_parent.insertBefore(separator_dragbtn, add_btn);
        // }, 50);
    
        document.getElementById('ntb_drag_btn').addEventListener( "click", let_drag);
        function let_drag() {
            if (event.button === 0 ) {
            drag_diver.classList.toggle("drag_mode");
           }
        };
    
    // Context menu menuitem
        let menuitem_drag = document.createXULElement("menuitem");
        menuitem_drag.setAttribute('id', 'Drag_direction_Context');
        menuitem_drag.setAttribute('closemenu', 'none');
        menuitem_drag.setAttribute('label', 'Rotate Toolbar');
        menuitem_drag.style.setProperty('-moz-context-properties', 'fill, stroke, fill-opacity, stroke-opacity');
        menuitem_drag.classList.add('menuitem-iconic');
    
        let menu_drag = document.getElementById('toolbar-context-menu');
        let menu_refitem = document.querySelector('.viewCustomizeToolbar');
        menu_drag.insertBefore(menuitem_drag, menu_refitem);
    
        let menuseparator_drag = document.createXULElement("menuseparator");
        menuseparator_drag.setAttribute('id', 'drag_separator');
        menu_drag.insertBefore(menuseparator_drag, menuitem_drag.nextSibling);
    
        // fix rotation right edge
        document.getElementById('Drag_direction_Context').addEventListener("click", rota_bar);
        function rota_bar(event) {
          if (event.button === 0 || event.button === 2) {
            const new_dragbarer = document.getElementById('drag_diver');
            new_dragbarer.classList.toggle("dragbar_rotate");
    
            if (dragtb.getAttribute('orient') === 'vertical') {
              dragtb.setAttribute('orient', 'horizontal');
            } else {
              dragtb.setAttribute('orient', 'vertical');
            }
            const isRotated = new_dragbarer.classList.contains("dragbar_rotate");
            Services.prefs.setBoolPref("userChrome.rotate_drag_diver", isRotated);
    
            setTimeout(() => {
              const pos = clampPosition(drag_element.offsetLeft, drag_element.offsetTop);
              drag_element.style.left = pos.left + "px";
              drag_element.style.top  = pos.top  + "px";
            }, 50);
          }
        };
    
        // fix rotation right edge customize
        window.addEventListener("aftercustomization", () => {
          const drag_element = document.getElementById("drag_diver");
          if (!drag_element) return;
    
          setTimeout(() => {
            const pos = clampPosition(drag_element.offsetLeft, drag_element.offsetTop);
            drag_element.style.left = pos.left + "px";
            drag_element.style.top  = pos.top  + "px";
          }, 100);
        });
    
        let savedState_r = false;
        try {
          savedState_r = Services.prefs.getBoolPref("userChrome.rotate_drag_diver");
        } catch(e) {}
    
        if (savedState_r) {
          drag_element.classList.add("dragbar_rotate");
          dragtb.setAttribute('orient', 'horizontal');
        } else {
          dragtb.setAttribute('orient', 'vertical');
        }
    
        // Context menuitem only vivible in this button and toolbar
        menu_drag.addEventListener("popupshowing", (event) => {
          let trigger = menu_drag.triggerNode;
          let isntbButton = trigger && trigger.id === "dragbar_off_button";
          let isInsideNewToolbar = false;
          if (trigger) {
            let toolbar = trigger.closest("#new_dragbar");
            isInsideNewToolbar = !!toolbar;
          }
          let visible = isntbButton || isInsideNewToolbar;
          menuitem_drag.hidden = !visible;
          menuseparator_drag.hidden = !visible;
        });
    
    // Drag functions
        const PREF_REL_X = "userchrome.drag_diver.relX";
        const PREF_REL_Y = "userchrome.drag_diver.relY";
    
        // Fallback position
        let relX = 0.1;
        let relY = 0.3;
    
        try {
          if (Services.prefs.prefHasUserValue(PREF_REL_X)) {
            relX = parseFloat(Services.prefs.getCharPref(PREF_REL_X));
          }
          if (Services.prefs.prefHasUserValue(PREF_REL_Y)) {
            relY = parseFloat(Services.prefs.getCharPref(PREF_REL_Y));
          }
        } catch (ex) {}
    
        function clampPosition(left, top) {
          const winWidth  = window.innerWidth;
          const winHeight = window.innerHeight;
          const elemWidth  = drag_element.offsetWidth;
          const elemHeight = drag_element.offsetHeight;
    
          const navbar = document.getElementById("navigator-toolbox");
          const TOP_LIMIT = navbar ? navbar.getBoundingClientRect().bottom + 0 : 100;
    
          if (left < 0) left = 0;
          if (top  < TOP_LIMIT) top = TOP_LIMIT;
          if (left > winWidth - elemWidth)  left = winWidth - elemWidth;
          if (top  > winHeight - elemHeight) top = winHeight - elemHeight;
    
          return { left, top };
        }
    
        function applyPositionFromRelative() {
          const winWidth  = window.innerWidth;
          const winHeight = window.innerHeight;
    
          let left = relX * winWidth;
          let top  = relY * winHeight;
    
          const pos = clampPosition(left, top);
          drag_element.style.left = pos.left + "px";
          drag_element.style.top  = pos.top  + "px";
        }
        // hide / delay at startup / new window
        setTimeout(() => {
          applyPositionFromRelative();
          dragtb.classList.add("complete");
        }, 100);
    
        let isDragging = false;
        let offsetX = 0;
        let offsetY = 0;
    
        // mouse in element #3
        drag_element.addEventListener("mousedown", e => {
          if (document.documentElement.hasAttribute("customizing")) return;
          if (!drag_element.classList.contains("drag_mode")) return;
          if (e.target.closest("#ntb_drag_btn")) return;
    
          e.preventDefault();
          isDragging = true;
    
          const measure = () => {
            const rect = drag_element.getBoundingClientRect();
            if (rect.width === 0 || rect.height === 0) {
              setTimeout(measure, 100);
              return;
            }
            // offsetX = e.clientX - rect.left;
            // offsetY = e.clientY - rect.top;
    
            offsetX = rect.width / 2;
            offsetY = rect.height / 2;
    
            drag_element.style.transition = "none";
          };
          measure();
        });
    
        window.addEventListener("mousemove", e => {
          if (!isDragging) return;
    
          let newLeft = e.clientX - offsetX;
          let newTop  = e.clientY - offsetY;
    
          const pos = clampPosition(newLeft, newTop);
          drag_element.style.left = pos.left + "px";
          drag_element.style.top  = pos.top  + "px";
        });
    
        window.addEventListener("mouseup", () => {
          if (!isDragging) return;
          isDragging = false;
    
          let left = drag_element.offsetLeft;
          let top  = drag_element.offsetTop;
          const pos = clampPosition(left, top);
    
          drag_element.style.left = pos.left + "px";
          drag_element.style.top  = pos.top  + "px";
    
          const winWidth  = window.innerWidth;
          const winHeight = window.innerHeight;
    
          relX = pos.left / winWidth;
          relY = pos.top  / winHeight;
    
          try {
            Services.prefs.setCharPref(PREF_REL_X, String(relX));
            Services.prefs.setCharPref(PREF_REL_Y, String(relY));
          } catch (ex) {}
        });
    
        window.addEventListener("resize", () => {
          applyPositionFromRelative();
        });
    
    let css = `
    
    :root {
        --ug-dragbar_min_width: calc(2 * var(--toolbarbutton-inner-padding) + 16px);
        --ug-dragbar_width: calc(var(--ug-dragbar_min_width) + 2*var(--ug-drag_border_width) + 2*var(--ug-dragbar_add_width));
    
    /*--  User settings CSS  --*/
    
        --ug-dragbar_add_width: 2px;         /* add width, 0px => inner toolbar = button-width */
        --ug-dragbar_btn_distance: 2px;      /* distance between buttons */
    
        --ug-dragbar_bg_color: gainsboro;    /* background, corner radius */
        --ug-dragbar_radius: 8px;
    
        --ug-drag_border_width: 1px;         /* border */
        --ug-drag_border_color: grey;
    
        --ug-drag_active_color: darkorange;  /* highlight color in drag mode */
    }
    
    /*--  User settings CSS end --*/
    
    #drag_diver {
        position: fixed;
        display: flex;
        z-index: 4 !important;
        user-select: none !important;
        -moz-window-dragging: no-drag;
    }
    
    #dragbox_New {
        display: flex;
        flex-direction: column !important;
        z-index: 5 !important;
        margin: calc(-1*var(--ug-drag_border_width));
    }
    
    #new_dragbar {
        display: flex;
        min-width: var(--ug-dragbar_width) !important;
        width: var(--ug-dragbar_width);
        min-height: var(--ug-dragbar_width) !important;
        overflow: hidden !important;
        padding: 4px 0px;
        justify-content: center !important;
        border-color: var(--ug-drag_border_color);
        border-style: solid !important;
        border-width: var(--ug-drag_border_width);
        border-radius: var(--ug-dragbar_radius);
        opacity: 0;
        transition: opacity 0.2s ease-in;
    }
    #new_dragbar.complete {
        opacity: 1;
    }
    
    #new_dragbar > :is(.toolbarbutton-1, toolbaritem),
    #new_dragbar toolbarpaletteitem > :is(.toolbarbutton-1, toolbaritem) {
        margin: var(--ug-dragbar_btn_distance) 0px !important;
        padding-inline: 0px !important;
    }
    
    /*--  rotate mode  --*/
    
    #main-window:not([customizing]) #drag_diver.dragbar_rotate #new_dragbar {
        height: var(--ug-dragbar_width) !important;
        width: fit-content !important;
        padding: 0px 4px;
    }
    #main-windowt:not([customizing]) #drag_diver.dragbar_rotate #new_dragbar > :is(.toolbarbutton-1, toolbaritem) {
        margin: 0px var(--ug-dragbar_btn_distance) !important;
    }
    
    /*--  menu item rotate  --*/
    
    #Drag_direction_Context :is(image, img) {
        list-style-image: url(chrome://global/skin/icons/reload.svg);
        content: url(chrome://global/skin/icons/reload.svg) !important;
        height: 14px !important;
        width: 14px !important;
        fill: currentColor !important;
        transform: rotate(0deg);
        transition: fill 0.25s ease, transform 0.25s ease !important;
    }
    #Drag_direction_Context:active :is(image, img)  {
        fill: var(--ug-drag_active_color) !important;
        transform: rotate(110deg);
    }
    #Drag_direction_Context label  {
         padding-inline: 2px !important;
    }
    
    /*--  drag button  --*/
    
    #main-window #ntb_drag_btn  {
        cursor: move;
    }
    #main-window:not([customizing]) #drag_diver:not(.drag_mode) #ntb_drag_btn:not(:hover, :active) image {
        opacity: 0.5;
    }
    
    /*--   drag mode   --*/
    
    #main-window:not([customizing]) #drag_diver.drag_mode {
        cursor: grab;
    }
    #main-window:not([customizing]) #drag_diver.drag_mode #new_dragbar  {
        outline: 2px solid var(--ug-drag_active_color) !important;
        outline-offset: -1px !important;
    }
    :root:not([customizing]) #drag_diver.drag_mode toolbarbutton:not(#ntb_drag_btn) {
        pointer-events: none !important;
    }
    /* drag button drag mode */
    #main-window:not([customizing]) #drag_diver.drag_mode #ntb_drag_btn {
        color: var(--ug-drag_active_color) !important;
        opacity: 1;
    }
    #main-window:not([customizing]) #drag_diver.drag_mode #ntb_drag_btn image {
        outline: 1px solid var(--ug-drag_active_color) !important;
        outline-offset: -1px !important;
    }
    
    /*--  off mode  --*/
    
    #main-window:not([customizing]) #drag_diver.dragbar_off_mode {
        /*display: none;*/
        visibility: hidden;
    }
    #dragbar_off_button.dragbar_off_mode {
        opacity: 0.5;
    }
    
    /*---  customizing  ---*/
    
    #main-window[customizing] #drag_diver {
        visibility: hidden;
    }
    
    #main-window[customizing] #dragbox_New {
        position: fixed;
        top: 50%;
        left: 0px;
        transform: translateY(-50%);
        visibility: visible;
    }
    
    #new_dragbar[customizing] {
        flex-direction: column !important;
        align-items: center !important;
        width: initial !important;
        padding-bottom: 48px !important;
        border-radius: 0 var(--ug-dragbar_radius) var(--ug-dragbar_radius) 0 !important;
    }
    
    #customization-content-container {
        margin-left: var(--ug-dragbar_width) !important;
    }
    
    #new_dragbar[customizing] #dragbtn_separator {
        width: calc(var(--ug-dragbar_width) - 8px - 2*var(--ug-drag_border_width)) !important;
        margin-inline: 0px !important;
    }
    
    #main-window[customizing] :is(#Drag_direction_Context, #drag_separator) {
        display: none !important;
    }
    
    /*-  test colors  -*/
    /*
    #dragbox_New image {
        outline-offset: -1px !important;
        outline: 1px solid green !important;
    }
    */
    
    `;
    
    if (drag_bg_color) {
      css += `
    
    /*-  Custom background color  -*/
    
    #new_dragbar {
        background-color: var(--ug-dragbar_bg_color) !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

    drag_icons.zip

Unterstütze uns!

Jährlich (2026)

32,8 %

32,8% (213,31 von 650 EUR)

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