- Firefox-Version
 - 138.0b3
 - Betriebssystem
 - Win11 24H2
 
Seit ner Weile funktioniert bei mir mit dem Script für Mehrzeilige Tableisten die Tableiste nicht mehr richtig. Also d.h es hat nun immer ein leerer Bereich unter den Tabs. Dieser verschwindet, wenn ich die 2. Tabreihe mit Tabs auffülle. Also dieser Leere Bereich (sieht aus wie eine leere Tabreihe) ist nur da, solange ich nicht genug Tabs für mehrere Zeilen offen habe. ![]()
Ich finde einfach nicht heraus, an was das liegt. Ich habe die userChrome.css gelöscht, es liegt nicht an der.
Hat jemand eine Ahnung, wie man das beheben kann? Ich nutze folgenden Code:
CSS
		
					
				// ==UserScript==
// @name           zzzz-MultiRowTab_LiteforFx48.uc.js
// @namespace      http://space.geocities.yahoo.co.jp/gl/alice0775
// @description    Mehrzeilige Tableiste - Experimentelle CSS Version
// @include        main
// @compatibility  Firefox 128esr Firefox 131+
// @author         Alice0775
// @version        2024/09/30 12:00 Firefox 131+
// @version        2016/08/05 00:00 Firefox 48
// @version        2016/05/01 00:01 hide favicon if busy
// @version        2016/03/09 00:01 Bug 1222490 - Actually remove panorama for Fx45+
// @version        2016/02/09 00:01 workaround css for lwt
// @version        2016/02/09 00:00
// ==/UserScript==
"use strict";
MultiRowTabLiteforFx();
function MultiRowTabLiteforFx() {
if (!window.gBrowser) { return; }
   // -- Config --
   // Vergleichbarer CSS Code in userChrome.css Datei wird vorrangig behandelt!
   const                                        // Tab-Leistenzeilen Anzahl
   TabBar_Rows =                          false   ,// [false] = unbegrenzt
                                                // true    = Begrenzte Tabzeilen - Anzahl der Zeilen
   Max_Rows =                             3       ,// Tabzeilen angeben (Standard: 3 Zeilen)
                                                // Anzahl der Tab-Leistenzeilen für „true“ Normalerweise auf 1 Zeile eingestellt und
                         // die zweite und die folgenden Zeilen werden bis zur angegebenen Anzahl von Zeilen
                         // angezeigt, wenn der Mauszeiger über die Tab-Leiste bewegt wird.
   MultiRowTab_on_MouseOver =             false   ,// [false] = Standard
                                                // true = Standard 1 Zeile
   TabBar_MouseOver_DisplayTime =         1       ,// Sie können die Anzeigezeit (Sekunden) festlegen, nachdem die zweite und die folgenden
                                             // Zeilen beim Mouseover angezeigt werden. Das Display zeigt den eingestellten Wert
                                // (Sekunden) an und kehrt dann zur ersten Zeile zurück.
                                                        
                                                // ProtonUI Erscheinungsbild der Tabs ändern
   Proton_Margins =                       false    ,// [true] = Darstellung ProtonUI
                                                // Die Höhe der Tab-Leiste entspricht der Höhe derUI-Dichte plus dem Leerraum darüber
                         // und darunter.                                                 
                         // false  = Darstellung wie bei browser.proton.enabled auf false, was man vor Firefox 90
                          // noch einstellen konnte.
                                                // Wenn der Leerraum um die Registerkarte auf 0 und die Höhe auf die UI-Dichte eingestellt
                                                // ist, ist sie 4 Pixel breiter und 8 Pixel niedriger als die Standardeinstellung.
                                                // Ränder auf der linken und rechten Seite der Tabs
   Tab_Separators  =                   false   ,// [false] = Nicht anzeigen
                                                // true    = Anzeigen
                                                // Rahmen CSS wurde extrahiert und angepasst, an Aussehen wie bei browser.proton.enabled
                         // auf false, was man vor Firefox 90 noch einstellen konnte.
                                                // Position der Tab-Leiste.
   TabBar_Position =                      0   ,// [0] = Standard
                                                // 1   = unter der Symbolleiste
                                                // 2   = unter dem Fenster
                                                // Standardposition der Tableiste Blenden Sie die Titelleistenschaltfläche [-□×] 
                         // aus und verwenden Sie die Breite der Tableiste entsprechend
   TitleBar_Button_Autohide =             false    ,// [false] = Aktiviert
                                                // true    = Deaktiviert
                                                // Äußeren Rahmen der Titelleistenschaltfläche [-□×] reduzieren und transparent machen.
                         // Obere rechte Ecke der Tab-Leiste auf ihre ursprüngliche Größe zurücksetzen und
                         // Transparenz aufheben.
   TitleBar_Button_DisplayTime =       0.6    ,// Dauer der Anzeige in Sekunden, nach der Rückkehr zur Originalgröße und dem Aufheben
                                             // der Transparenz per Mouseover angeben.
   
                                                // Tab-Höhe „UI-Dichte“
   UI_Density_Compact =                   16    ,// Standard = 29 Pixelbei Kompakt
   UI_Density_Normal =                    16    ,// Standard = 36 Pixel bei Normal
   UI_Density_Touch =                     16    ,// Standard = 41 Pixel bei Touch
                                                // Entsprechender CSS Code in UserChrome.css wird vorrangig behandelt!
                                                // Tab-Breite
                                                // Bei gleichen Werten bei Min und Max, wird Tabbreite fixiert!
   Tab_Min_Width =                        129    ,// Standard - Mindestwert = 76px
   Tab_Max_Width =                        129    ,// Standard - Maxwert = 225px
                                                // Entsprechender CSS Code in UserChrome.css wird vorrangig behandelt!
                                                // „Tab schließen“ Schaltfläche
   Tab_Close_Button =                     2    ,// [0] = Standard
                                                //  1  = Ausgeblendet
                                                //  2  = Auf allen Tabs anzeigen
                         //  3  = Nur bei Mausberührung anzeigen
                                                // .Tab-Drop-Indikator-Icon-Ersetzung.
   Tab_Drop_Indicator =                   false    ,// [false] = Stecknadel Symbol 📍
                                                // true    = Rote Linie (2px × 29px) als Symbol
                                                // Angeheftete Tabs neu positionieren
   Separate_Tabs_and_PinnedTabs =         false    ,// [false] = Standard
                                                // true    = Angeheftete Tabs von der Tab-Leiste lösen und in die darüber liegende 
                         // Zeile verschieben. Breite der angehefteten Tabs für die Position der 
                         // angehefteten Tabs „true“ anpassen.
   PinnedTab_Width =                   false    ,// [false] = Kein Standard
                                                //  true   = Breite angehefteter Tabs anpassen, z. B. „Tab-Breite“.
   PinnedTab_Min_Width =               129       ,// Standard Mindestbreite =  76 Pixel
   PinnedTab_Max_Width =               129       ,// Standard Maximalbreite = 225 Pixel
                                                // Bei gleichen Werten ist die Breite fixiert.
                                                // Tab-Leisten-Ziehbereich
   Left_Drag_Area =                       0    ,// Linker Ziehbereich Breite: Standard 40 Pixel
   Right_Drag_Area =                      0    ,// Rechter Ziehbereich Breite: Standard 40 Pixel
   Maximize_Left_Drag_Area =           false   ,// true = Linken Ziehbereich bei maximiertem Fenster anzeigen. Standard ausgeblendet.
   Fullscreen_Drag_Area =                 false    ,// true = Linken und rechten Ziehbereich bei Vollbild anzeigen. Standard ausgeblendet.
                                                // Alle Tabs Schaltfläche
   All_Tabs_Button =                      false    ,// [false] = ausblenden
                                                // true    = anzeigen
                                                // Firefox132 oder höher?
                                                // Breite beim Öffnen/schließen, beim fahren mit der Maus über die vertikale Tab-Leiste
   VerticalTabs_MouseOver_OpenClose =  false    ,// [false] Kein Standard. Drücken Sie im vertikalen Tab-Modus die Seitenleistentaste,  
                                             // um die Breite zu vergrößern oder zu verkleinern.
                                                // true  Unabhängig davon, welche Seitenleistenschaltfläche Sie im vertikalen Tab-Modus  
                         // auswählen, können Sie die Breite vergrößern oder verkleinern, indem Sie mit der Maus
                                                // darüber fahren.
   // -- Config End --
   css = `
   #TabsToolbar:has([orient="horizontal"]) {
     :root[uidensity="compact"] & {
       --tab-min-height: ${UI_Density_Compact}px;
     }
     :root:not([uidensity]) & {
       --tab-min-height: ${UI_Density_Normal}px;
     }
     :root[uidensity="touch"] & {
        --tab-min-height: ${UI_Density_Touch}px;
     }
     ${Tab_Drop_Indicator ? `
       #tabbrowser-tabs > .tab-drop-indicator {
         background: url(
           data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAdCAIAAAAPVCo9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAASSURBVBhXY3growJEQ5+SUQEAOb1EM8kwskcAAAAASUVORK5CYII=
         ) no-repeat center !important;
       }
     ` : ``}
     .titlebar-spacer[type="pre-tabs"] {
       width: ${Left_Drag_Area}px;
     }
     .titlebar-spacer[type="post-tabs"] {
       width: ${Right_Drag_Area}px;
     }
     ${Maximize_Left_Drag_Area ? `
       .titlebar-spacer {
         :root[tabsintitlebar]:not([sizemode="normal"], [inFullscreen]) &[type="pre-tabs"] {
           display: block !important;
         }
       }
     ` : ``}
     ${Fullscreen_Drag_Area ? `
       .titlebar-spacer {
         :root[tabsintitlebar][inFullscreen] & {
           display: block !important;
         }
       }
     ` : ``}
     ${All_Tabs_Button ? `` : `
       #alltabs-button {
         display: none;
       }
     `}
     ${Separate_Tabs_and_PinnedTabs ? `
       #tabbrowser-tabs {
         padding: 0 !important;
         & + #new-tab-button {
           display: none !important;
         }
         #tabbrowser-arrowscrollbox {
           &:has(> .tabbrowser-tab[fadein][pinned]) {
             &::part(scrollbox) {
               &:has(+ spacer) > slot::after,
               .scrollbox-clip > &::after {
                 display: flow-root list-item;
                 content: "";
                 flex-basis: -moz-available;
                 height: 0;
                 overflow: hidden;
               }
             }
           }
           .tabbrowser-tab[fadein] {
             &:not([pinned]) {
               #tabbrowser-tabs[haspinnedtabs] & {
                 &, & + :not(#tabs-newtab-button) {
                   order: 1;
                 }
               }
             }
             &[pinned] {
               .tab-loading-burst:after {
                 content: "📌";
                 font-size: 11px;
                 right: -2px;
                 position: absolute;
                 top: -2px;
               }
             }
             ${PinnedTab_Width ? `
               &[pinned] {
                 flex: 100 100;
                 max-width: ${PinnedTab_Max_Width}px;
                 min-width: ${PinnedTab_Min_Width}px;
               }
               .tab-throbber, .tab-icon-pending, .tab-icon-image, .tab-sharing-icon-overlay, .tab-icon-overlay {
                 &[pinned] {
                   margin-inline-end: 5.5px !important;
                 }
               }
             ` : ``}
           }
         }
       }
     ` : ``}
     #tabbrowser-arrowscrollbox {
       &::part(scrollbox) {
         &:has(+ spacer) > slot,
         .scrollbox-clip > & {
           flex-wrap: wrap;
         }
         ${TabBar_Rows ? `
           ${MultiRowTab_on_MouseOver ? `
             max-height: calc(var(--tab-min-height) + ${Proton_Margins ? 8 : 0}px);
             scrollbar-width: none;
             transition: all 0s ease-in-out ${TabBar_MouseOver_DisplayTime}s;
             &:hover {
               max-height: calc((var(--tab-min-height) + ${Proton_Margins ? 8 : 0}px) * ${Max_Rows}) !important;
               scrollbar-width: auto !important;
               transition: none 0s !important;
             }
           ` : `
             max-height: calc((var(--tab-min-height) + ${Proton_Margins ? 8 : 0}px) * ${Max_Rows});
           `}
           overflow: hidden auto;
           & scrollbar {
             -moz-window-dragging: no-drag;
           }
         ` : ``}
       }
       &::part(overflow-start-indicator),
       &::part(overflow-end-indicator),
       &::part(scrollbutton-up),
       &::part(scrollbutton-down) {
         display: none;
       }
       .tabbrowser-tab[fadein]:not([pinned]) {
         max-width: ${Tab_Max_Width}px;
         min-width: ${Tab_Min_Width}px;
         ${Tab_Close_Button == 1 ? `
           .tab-close-button {
             display: none !important;
           }
         ` : Tab_Close_Button == 2 ? `
           .tab-close-button {
             display: block !important;
           }
         ` : Tab_Close_Button == 3 ? `
           .tab-close-button {
             opacity: 0;
           }
           &:hover .tab-close-button {
             display: block !important;
             opacity: 1;
           }
         ` : Tab_Close_Button == 4 ? `
           .tab-close-button {
             opacity: 0;
           }
           &:hover .tab-close-button,
           .tab-close-button[selected] {
             display: block !important;
             opacity: 1;
           }
         ` : ``}
       }
       #tabbrowser-tabs[haspinnedtabs]:not([positionpinnedtabs]):not([orient="vertical"]) > & {
         &  > .tabbrowser-tab:nth-child(1 of :not([pinned], [hidden])) {
           margin-inline-start: 0 !important;
         }
       }
     }
     ${Tab_Separators ? `
       .titlebar-spacer[type="pre-tabs"] {
         border-inline-end: 1px solid color-mix(in srgb, currentColor 20%, transparent);
       }
       .tabbrowser-tab {
         &::after,
         &::before {
           border-left: 1px solid color-mix(in srgb, currentColor 50%, transparent);
           height: calc(var(--tab-min-height) - 15%);
           margin-block: auto;
         }
         &:hover::after,
         &[multiselected]::after,
         #tabbrowser-tabs:not([movingtab]) &:has(+ .tabbrowser-tab:hover)::after,
         #tabbrowser-tabs:not([movingtab]) &:has(+ [multiselected])::after {
           height: 100%;
         }
         &::after,
         #tabbrowser-tabs[movingtab] &[visuallyselected]::before {
           display: block;
           content: "";
         }
       }
     ` : ``}
     ${Proton_Margins ? `` : `
       .tabbrowser-tab,
       .toolbarbutton-1 {
         padding: 0 !important;
       }
       .tabbrowser-tab,
       #tabs-newtab-button {
         height: var(--tab-min-height) !important;
       }
       .tab-background {
         box-shadow: none !important;
         margin-block: 0 !important;
       }
       .tabbrowser-tab[usercontextid] > .tab-stack > .tab-background > .tab-context-line {
         margin-block-start: 1px !important;
       }
     `}
   ${TabBar_Position == 0 ? `
     .titlebar-buttonbox-container {
       height: calc(var(--tab-min-height) + ${Proton_Margins ? 8 : 0}px);
     }
     ${TitleBar_Button_Autohide ? `
       .titlebar-buttonbox-container {
         background-color: color-mix(in srgb, currentColor 20%, transparent);
         height: 6px !important;
         opacity: 0;
         position: fixed;
         right: 0;
         transition: all 0s ease-in-out ${TitleBarButton_DisplayTime}s;
         z-index: 2147483647;
         .titlebar-button {
           opacity: 0;
           padding: 0;
           transition: all 0s ease-in-out ${TitleBarButton_DisplayTime}s;
         }
         &:hover {
           height: calc(var(--tab-min-height) + ${Proton_Margins ? 8 : 0}px) !important;
           opacity: 1;
           transition: none 0s;
           .titlebar-button {
             opacity: 1;
             padding: 8px 17px;
             transition: none 0s;
           }
         }
       }
     ` : ``}
   }` : `}
     #nav-bar {
       :root:not([inFullscreen]) #toolbar-menubar:not([inactive]) + & {
         & > .titlebar-buttonbox-container {
           display: none;
         }
       }
       .titlebar-button {
         padding-block: 0;
       }
     }
     ${TabBar_Position == 2 ? `
       body {
         & > #fullscr-toggler[hidden] + tabbox,
         :root[inFullscreen] & > tabbox:hover {
           border-top: 0.5px solid var(--toolbar-bgcolor);
         }
         & > tabbox > #navigator-toolbox {
           border-block: none !important;
         }
         :root[inFullscreen] & {
           & > #navigator-toolbox {
             transition: none;
             &:has(~ tabbox:hover) {
               margin-top: 0 !important;
             }
             &:hover ~ tabbox > #navigator-toolbox {
               max-height: 100%;
           }}
           & > tabbox:not(:hover) {
             border-top: 0.5px solid transparent;
             & > #navigator-toolbox {
               max-height: 0;
             }
           }
         }
       }
     ` : ``}
   `}
   ${VerticalTabs_MouseOver_OpenClose ? `
     #sidebar-main:has(sidebar-main > [collapsed="false"]) {
       sidebar-main {
         #tabbrowser-arrowscrollbox {
           &[overflowing]:not([scrolledtoend]) {
             mask-image: none !important;
           }
         }
         &[expanded] {
           #tabbrowser-tabs[haspinnedtabs] {
             #vertical-pinned-tabs-container-separator {
               display: block !important;
             }
           }
         }
       }
       &:hover {
         sidebar-main {
           &[expanded] {
             #vertical-pinned-tabs-container-separator {
               width: 226px !important;
             }
             #tabbrowser-arrowscrollbox {
               .tabbrowser-tab {
                 .tab-close-button {
                   padding-inline-start: 4px !important;
                 }
               }
             }
           }
           &:not([expanded]) {
             #tabbrowser-tabs[haspinnedtabs] {
               #vertical-pinned-tabs-container {
                 display: flex !important;
                 flex-direction: column !important;
               }
             }
             .tabbrowser-tab {
               #vertical-pinned-tabs-container &,
               #tabbrowser-arrowscrollbox & {
                 width: 234px !important;
                 transition: none;
                 max-width: 234px !important;
                 .tab-background {
                   width: 226px !important;
                   max-width: 226px !important;
                 }
                 &:hover .tab-close-button,
                 .tab-close-button[selected],
                 .tab-label-container {
                   display: block !important;
                 }
               }
               #vertical-pinned-tabs-container & {
                 .tab-close-button {
                   padding-inline-start: 0px !important;
                 }
               }
               #tabbrowser-arrowscrollbox {
                 .tabbrowser-tab {
                   .tab-close-button {
                     padding-inline-end: 2px !important;
                   }
                 }
               }
               #tabbrowser-arrowscrollbox & {
                 #tabbrowser-tabs[overflow] & {
                   .tab-background {
                     width: 218px !important;
                   }
                 }
               }
               .tab-icon-image {
                 #vertical-pinned-tabs-container & {
                   margin-inline: 7px !important;
                 }
                 #tabbrowser-arrowscrollbox & {
                   padding-inline-end: 7.5px !important;
                 }
               }
             }
             [id*="tabs-newtab-button"] {
               width: 226px !important;
               .toolbarbutton-icon {
                 margin-inline-end: 2px !important;
               }
               .toolbarbutton-text {
                 display: block !important;
               }
             }
           }
         }
       }
       &:not(:hover) {
         * {
           font-size: 0 !important;
         }
         sidebar-main {
           width: 55px !important;
           #tabbrowser-arrowscrollbox::part(scrollbox),
           #vertical-pinned-tabs-container {
             scrollbar-width: none !important;
           }
           &[expanded] {
             #vertical-pinned-tabs-container {
               .tabbrowser-tab {
                width: 38px !important;
               }
             }
             #vertical-pinned-tabs-container-separator {
               #tabbrowser-tabs[haspinnedtabs] & {
                 width: 36px !important;
               }
             }
             #tabbrowser-arrowscrollbox {
               .tabbrowser-tab {
                  width: 56px !important;
                 .tab-close-button {
                   display: none !important;
                 }
               }
             }
           }
         }
       }
     }
     #sidebar-main:has(sidebar-main:not([hidden]) > [collapsed="true"]) {
       &:not([expanded]) {
         width: 165px;
       }
     }
     .wrapper {
       :not(:hover) button-group:not(.bottom-actions) {
         moz-button {
           width: 55px !important;
         }
       }
       &:has(.bottom-actions) {
         moz-button {
           width: 170px !important;
         }
       }
     }
     button > span {
       &.button-background {
           width: 226px !important;
         &.labelled {
           & > img {
             margin-inline-start: 2px;
           }
         }
         &:not(.labelled) {
           width: 226px !important;
           max-width: 100%;
           & > img {
             margin-inline-start: 7px;
             & + label {
               text-align: start;
               width: 226px !important;
               & > slot:after {
                 font-size: var(--font-size-large);
                 font-weight: var(--font-weight);
                 margin-inline-start: 7px;
               }
             }
             &[src*="view-syncedtabs"] + label > slot:after {
               content: "他の端末からのタブ";
             }
             &[src*="view-history"] + label > slot:after {
               content: "履歴";
             }
             &[src*="bookmark-hollow"] + label > slot:after {
               content: "ブックマーク";
             }
             &[src*="category-general"] + label > slot:after {
               content: "サイドバーをカスタマイズ";
             }
           }
         }
       }
     }
   ` : ``}
   `,
   sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService),
   uri = Services.io.newURI("data:text/css;charset=UTF=8," + encodeURIComponent(css));
   ["0", "2", "dragend", "SSTabRestored", "TabAttrModified"].find(eventType => {
     if(!sss.sheetRegistered(uri, eventType)) sss.loadAndRegisterSheet(uri, eventType);
     if (TabBar_Rows == true) {
       gBrowser.tabContainer.addEventListener(eventType, (e) => {
         e.target.scrollIntoView({ behavior: "instant", block: "nearest" })
       })
     }
   })
   if (TabBar_Position == 1 || TabBar_Position == 2) {
     document.getElementById("nav-bar").appendChild(
       document.querySelector("#TabsToolbar > .titlebar-buttonbox-container")
     )
     document.getElementById("navigator-toolbox").prepend(
       document.getElementById("toolbar-menubar"),
       document.getElementById("nav-bar"),
       document.getElementById("PersonalToolbar"),
       document.adoptNode(document.getElementById("titlebar")),
     )
   }
   if (TabBar_Position == 2) {
     document.body.appendChild(
       document.createXULElement("tabbox")
     ).appendChild(
       document.importNode(document.getElementById("navigator-toolbox"))
     ).appendChild(
       document.adoptNode(document.getElementById("titlebar"))
     )
   }
   gBrowser.tabContainer.addEventListener("dragover", function(event) { this._on_dragover(event); }, false)
   gBrowser.tabContainer.addEventListener("drop", function(event) { this._on_drop(event); }, false)
   gBrowser.tabContainer.on_dragover = function(event) { return false; }
   gBrowser.tabContainer.on_drop = function(event) { return false; }
   gBrowser.tabContainer._on_dragover = function(event) {
     var effects = this.getDropEffectForTabDrag(event);
     var ind = this._tabDropIndicator;
     if (effects == "" || effects == "none") {
       ind.hidden = true;
       return;
     }
     event.preventDefault();
     event.stopPropagation();
     var arrowScrollbox = this.arrowScrollbox;
     // autoscroll the tab strip if we drag over the scroll
     // buttons, even if we aren't dragging a tab, but then
     // return to avoid drawing the drop indicator
     var pixelsToScroll = 0;
     if (this.overflowing) {
       switch (event.originalTarget) {
         case arrowScrollbox._scrollButtonUp:
           pixelsToScroll = arrowScrollbox.scrollIncrement * -1;
           break;
         case arrowScrollbox._scrollButtonDown:
           pixelsToScroll = arrowScrollbox.scrollIncrement;
           break;
       }
       if (pixelsToScroll) {
         arrowScrollbox.scrollByPixels(
           (RTL_UI ? -1 : 1) * pixelsToScroll,
           true
         );
       }
     }
     if (this.verticalMode) {
     let draggedTab = event.dataTransfer.mozGetDataAt(TAB_DROP_TYPE, 0);
     if (
       (effects == "move" || effects == "copy") &&
       this == draggedTab.container &&
       !draggedTab._dragData.fromTabList
     ) {
       ind.hidden = true;
       if (!this._isGroupTabsAnimationOver()) {
         // Wait for grouping tabs animation to finish
         return;
       }
       this._finishGroupSelectedTabs(draggedTab);
       if (effects == "move") {
         // Pinned tabs in expanded vertical mode are on a grid format and require
         // different logic to drag and drop
         if (this._isContainerVerticalPinnedExpanded(draggedTab)) {
           this._animateExpandedPinnedTabMove(event);
           return;
         }
         this._animateTabMove(event);
         return;
       }
     }
     this._finishAnimateTabMove();
     }
     if (effects == "link") {
       let tab = this._getDragTargetTab(event, { ignoreTabSides: true });
       if (tab) {
         if (!this._dragTime) {
           this._dragTime = Date.now();
         }
         if (Date.now() >= this._dragTime + this._dragOverDelay) {
           this.selectedItem = tab;
         }
         ind.hidden = true;
         return;
       }
     }
     var rect = arrowScrollbox.getBoundingClientRect();
     var newMargin, newMarginY;
     if (pixelsToScroll) {
       // if we are scrolling, put the drop indicator at the edge
       // so that it doesn't jump while scrolling
       let scrollRect = arrowScrollbox.scrollClientRect;
       let minMargin = this.verticalMode
         ? scrollRect.top - rect.top
         : scrollRect.left - rect.left;
       let maxMargin = this.verticalMode
         ? Math.min(minMargin + scrollRect.height, scrollRect.bottom)
         : Math.min(minMargin + scrollRect.width, scrollRect.right);
       if (RTL_UI) {
         [minMargin, maxMargin] = [
           this.clientWidth - maxMargin,
           this.clientWidth - minMargin,
         ];
       }
       newMargin = pixelsToScroll > 0 ? maxMargin : minMargin;
     } else {
       let newIndex = this._getDropIndex(event);
       let children = this.allTabs;
       if (newIndex == children.length) {
         let tabRect = this._getVisibleTabs().at(-1).getBoundingClientRect();
         if (this.verticalMode) {
           newMargin = tabRect.bottom - rect.top;
         } else if (RTL_UI) {
           newMargin = rect.right - tabRect.left;
         } else {
           newMargin = tabRect.right - rect.left;
         }
           newMarginY = tabRect.top - rect.top + tabRect.height / 2 - rect.height / 2;
       } else {
         let tabRect = children[newIndex].getBoundingClientRect();
         if (this.verticalMode) {
           newMargin = rect.top - tabRect.bottom;
         } else if (RTL_UI) {
           newMargin = rect.right - tabRect.right;
         } else {
           newMargin = tabRect.left - rect.left;
         }
           newMarginY = tabRect.top - rect.top + tabRect.height / 2 - rect.height / 2;
       }
     }
     ind.hidden = false;
     newMargin += this.verticalMode ? ind.clientHeight : ind.clientWidth / 2;
     if (RTL_UI) {
       newMargin *= -1;
     }
     ind.style.transform = this.verticalMode
       ? "translateY(" + Math.round(newMargin) + "px)"
       : "translate(" + Math.round(newMargin) + "px, " + Math.round(newMarginY) + "px)";
   }
   gBrowser.tabContainer._on_drop = function(event) {
     var dt = event.dataTransfer;
     var dropEffect = dt.dropEffect;
     var draggedTab;
     let movingTabs;
     if (dt.mozTypesAt(0)[0] == TAB_DROP_TYPE) {
       // tab copy or move
       draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
       // not our drop then
       if (!draggedTab) {
         return;
       }
       movingTabs = draggedTab._dragData.movingTabs;
       draggedTab.container._finishGroupSelectedTabs(draggedTab);
     }
     this._tabDropIndicator.hidden = true;
     event.stopPropagation();
     if (draggedTab && dropEffect == "copy") {
       // copy the dropped tab (wherever it's from)
       let newIndex = this._getDropIndex(event);
       let draggedTabCopy;
       for (let tab of movingTabs) {
         let newTab = gBrowser.duplicateTab(tab);
         gBrowser.moveTabTo(newTab, newIndex++);
         if (tab == draggedTab) {
           draggedTabCopy = newTab;
         }
       }
       if (draggedTab.container != this || event.shiftKey) {
         this.selectedItem = draggedTabCopy;
       }
     } else if (draggedTab && draggedTab.container == this) {
       let oldTranslateX = Math.round(draggedTab._dragData.translateX);
       let oldTranslateY = Math.round(draggedTab._dragData.translateY);
       let tabWidth = Math.round(draggedTab._dragData.tabWidth);
       let tabHeight = Math.round(draggedTab._dragData.tabHeight);
       let translateOffsetX = oldTranslateX % tabWidth;
       let translateOffsetY = oldTranslateY % tabHeight;
       let newTranslateX = oldTranslateX - translateOffsetX;
       let newTranslateY = oldTranslateY - translateOffsetY;
       // Update both translate axis for pinned vertical expanded tabs
       if (oldTranslateX > 0 && translateOffsetX > tabWidth / 2) {
         newTranslateX += tabWidth;
       } else if (oldTranslateX < 0 && -translateOffsetX > tabWidth / 2) {
         newTranslateX -= tabWidth;
       }
       if (oldTranslateY > 0 && translateOffsetY > tabHeight / 2) {
         newTranslateY += tabHeight;
       } else if (oldTranslateY < 0 && -translateOffsetY > tabHeight / 2) {
         newTranslateY -= tabHeight;
       }
       let dropIndex;
       if (draggedTab._dragData.fromTabList) {
         dropIndex = this._getDropIndex(event);
       } else {
         dropIndex = this.verticalMode ?
           "animDropIndex" in draggedTab._dragData &&
           draggedTab._dragData.animDropIndex
           : this._getDropIndex(event);
       }
       let incrementDropIndex = true;
       if (dropIndex && dropIndex > movingTabs[0]._tPos) {
         dropIndex--;
         incrementDropIndex = false;
       }
       let shouldTranslate;
       if (this._isContainerVerticalPinnedExpanded(draggedTab)) {
         shouldTranslate =
           ((oldTranslateX && oldTranslateX != newTranslateX) ||
             (oldTranslateY && oldTranslateY != newTranslateY)) &&
           !gReduceMotion;
       } else if (this.verticalMode) {
         shouldTranslate =
           oldTranslateY && oldTranslateY != newTranslateY && !gReduceMotion;
       } else {
         shouldTranslate =
           oldTranslateX && oldTranslateX != newTranslateX && !gReduceMotion;
       }
       if (shouldTranslate) {
         for (let tab of movingTabs) {
           tab.toggleAttribute("tabdrop-samewindow", true);
           tab.style.transform = `translate(${newTranslateX}px, ${newTranslateY}px)`;
           let postTransitionCleanup = () => {
             tab.removeAttribute("tabdrop-samewindow");
             this._finishAnimateTabMove();
             if (dropIndex !== false) {
               gBrowser.moveTabTo(tab, dropIndex);
               if (incrementDropIndex) {
                 dropIndex++;
               }
             }
             gBrowser.syncThrobberAnimations(tab);
           };
           if (gReduceMotion) {
             postTransitionCleanup();
           } else {
             let onTransitionEnd = transitionendEvent => {
               if (
                 transitionendEvent.propertyName != "transform" ||
                 transitionendEvent.originalTarget != tab
               ) {
                 return;
               }
               tab.removeEventListener("transitionend", onTransitionEnd);
               postTransitionCleanup();
             };
             tab.addEventListener("transitionend", onTransitionEnd);
           }
         }
       } else {
         this._finishAnimateTabMove();
         if (dropIndex !== false) {
           for (let tab of movingTabs) {
             gBrowser.moveTabTo(tab, dropIndex);
             if (incrementDropIndex) {
               dropIndex++;
             }
           }
         }
       }
     } else if (draggedTab) {
       // Move the tabs. To avoid multiple tab-switches in the original window,
       // the selected tab should be adopted last.
       const dropIndex = this._getDropIndex(event);
       let newIndex = dropIndex;
       let selectedTab;
       let indexForSelectedTab;
       for (let i = 0; i < movingTabs.length; ++i) {
         const tab = movingTabs[i];
         if (tab.selected) {
           selectedTab = tab;
           indexForSelectedTab = newIndex;
         } else {
           const newTab = gBrowser.adoptTab(tab, newIndex, tab == draggedTab);
           if (newTab) {
             ++newIndex;
           }
         }
       }
       if (selectedTab) {
         const newTab = gBrowser.adoptTab(
           selectedTab,
           indexForSelectedTab,
           selectedTab == draggedTab
         );
         if (newTab) {
           ++newIndex;
         }
       }
       // Restore tab selection
       gBrowser.addRangeToMultiSelectedTabs(
         gBrowser.tabs[dropIndex],
         gBrowser.tabs[newIndex - 1]
       );
     } else {
       // Pass true to disallow dropping javascript: or data: urls
       let links;
       try {
         links = browserDragAndDrop.dropLinks(event, true);
       } catch (ex) {}
       if (!links || links.length === 0) {
         return;
       }
       let inBackground = Services.prefs.getBoolPref(
         "browser.tabs.loadInBackground"
       );
       if (event.shiftKey) {
         inBackground = !inBackground;
       }
       let targetTab = this._getDragTargetTab(event, { ignoreTabSides: true });
       let userContextId = this.selectedItem.getAttribute("usercontextid");
       let replace = !!targetTab;
       let newIndex = this._getDropIndex(event);
       let urls = links.map(link => link.url);
       let csp = browserDragAndDrop.getCsp(event);
       let triggeringPrincipal =
         browserDragAndDrop.getTriggeringPrincipal(event);
       (async () => {
         if (
           urls.length >=
           Services.prefs.getIntPref("browser.tabs.maxOpenBeforeWarn")
         ) {
           // Sync dialog cannot be used inside drop event handler.
           let answer = await OpenInTabsUtils.promiseConfirmOpenInTabs(
             urls.length,
             window
           );
           if (!answer) {
             return;
           }
         }
         gBrowser.loadTabs(urls, {
           inBackground,
           replace,
           allowThirdPartyFixup: true,
           targetTab,
           newIndex,
           userContextId,
           triggeringPrincipal,
           csp,
         });
       })();
     }
     if (draggedTab) {
       delete draggedTab._dragData;
     }
   }
   gBrowser.tabContainer._isContainerVerticalPinnedExpanded = function(tab) {
     return (
       this.verticalMode &&
       tab.hasAttribute("pinned") &&
       this.hasAttribute("expanded")
     );
   }
   gBrowser.tabContainer._animateExpandedPinnedTabMove = function(event) {
     let draggedTab = event.dataTransfer.mozGetDataAt(TAB_DROP_TYPE, 0);
     let movingTabs = draggedTab._dragData.movingTabs;
     if (!this.hasAttribute("movingtab")) {
       this.toggleAttribute("movingtab", true);
       gNavToolbox.toggleAttribute("movingtab", true);
       if (!draggedTab.multiselected) {
         this.selectedItem = draggedTab;
       }
     }
     if (!("animLastScreenX" in draggedTab._dragData)) {
       draggedTab._dragData.animLastScreenX = draggedTab._dragData.screenX;
     }
     if (!("animLastScreenY" in draggedTab._dragData)) {
       draggedTab._dragData.animLastScreenY = draggedTab._dragData.screenY;
     }
     let screenX = event.screenX;
     let screenY = event.screenY;
     if (
       screenY == draggedTab._dragData.animLastScreenY &&
       screenX == draggedTab._dragData.animLastScreenX
     ) {
       return;
     }
     let tabs = this._getVisibleTabs().slice(0, gBrowser._numPinnedTabs);
     let directionX = screenX > draggedTab._dragData.animLastScreenX;
     let directionY = screenY > draggedTab._dragData.animLastScreenY;
     draggedTab._dragData.animLastScreenY = screenY;
     draggedTab._dragData.animLastScreenX = screenX;
     let tabWidth = draggedTab.getBoundingClientRect().width;
     let tabHeight = draggedTab.getBoundingClientRect().height;
     let shiftSizeX = tabWidth * movingTabs.length;
     let shiftSizeY = tabHeight;
     draggedTab._dragData.tabWidth = tabWidth;
     draggedTab._dragData.tabHeight = tabHeight;
     // In expanded vertical mode, 6 is the max number of pinned tabs per row
     const maxTabsPerRow = 6;
     // Move the dragged tab based on the mouse position.
     let firstTabInRow;
     let lastTabInRow;
     if (RTL_UI) {
       firstTabInRow =
         tabs.length >= maxTabsPerRow ? tabs[maxTabsPerRow - 1] : tabs.at(-1);
       lastTabInRow = tabs[0];
     } else {
       firstTabInRow = tabs[0];
       lastTabInRow =
         tabs.length >= maxTabsPerRow ? tabs[maxTabsPerRow - 1] : tabs.at(-1);
     }
     let firstMovingTabScreenX = movingTabs.at(-1).screenX;
     let firstMovingTabScreenY = movingTabs.at(-1).screenY;
     let lastMovingTabScreenX = movingTabs[0].screenX;
     let lastMovingTabScreenY = movingTabs[0].screenY;
     let translateX = screenX - draggedTab._dragData.screenX;
     let translateY = screenY - draggedTab._dragData.screenY;
     let firstBoundX = firstTabInRow.screenX - lastMovingTabScreenX;
     let firstBoundY = firstTabInRow.screenY - lastMovingTabScreenY;
     let lastBoundX =
       lastTabInRow.screenX +
       lastTabInRow.getBoundingClientRect().width -
       (firstMovingTabScreenX + tabWidth);
     let lastBoundY =
       tabs.at(-1).screenY +
       lastTabInRow.getBoundingClientRect().height -
       (firstMovingTabScreenY + tabHeight);
     translateX = Math.min(Math.max(translateX, firstBoundX), lastBoundX);
     translateY = Math.min(Math.max(translateY, firstBoundY), lastBoundY);
     for (let tab of movingTabs) {
       tab.style.transform = `translate(${translateX}px, ${translateY}px)`;
     }
     draggedTab._dragData.translateX = translateX;
     draggedTab._dragData.translateY = translateY;
     // Determine what tab we're dragging over.
     // * Single tab dragging: Point of reference is the center of the dragged tab. If that
     //   point touches a background tab, the dragged tab would take that
     //   tab's position when dropped.
     // * Multiple tabs dragging: All dragged tabs are one "giant" tab with two
     //   points of reference (center of tabs on the extremities). When
     //   mouse is moving from top to bottom, the bottom reference gets activated,
     //   otherwise the top reference will be used. Everything else works the same
     //   as single tab dragging.
     // * We're doing a binary search in order to reduce the amount of
     //   tabs we need to check.
     tabs = tabs.filter(t => !movingTabs.includes(t) || t == draggedTab);
     let firstTabCenterX = lastMovingTabScreenX + translateX + tabWidth / 2;
     let lastTabCenterX = firstMovingTabScreenX + translateX + tabWidth / 2;
     let tabCenterX = directionX ? lastTabCenterX : firstTabCenterX;
     let firstTabCenterY = lastMovingTabScreenY + translateY + tabWidth / 2;
     let lastTabCenterY = firstMovingTabScreenY + translateY + tabWidth / 2;
     let tabCenterY = directionY ? lastTabCenterY : firstTabCenterY;
     let newIndex = -1;
     let oldIndex =
       "animDropIndex" in draggedTab._dragData
         ? draggedTab._dragData.animDropIndex
         : movingTabs[0]._tPos;
     let low = 0;
     let high = tabs.length - 1;
     let shiftNumber = maxTabsPerRow - movingTabs.length;
     let getTabShift = (tab, dropIndex) => {
       if (tab._tPos < draggedTab._tPos && tab._tPos >= dropIndex) {
         // If tab is at the end of a row, shift back and down
         let tabRow = Math.ceil((tab._tPos + 1) / maxTabsPerRow);
         let shiftedTabRow = Math.ceil(
           (tab._tPos + 1 + movingTabs.length) / maxTabsPerRow
         );
         if (tab._tPos && tabRow != shiftedTabRow) {
           return [
             RTL_UI
               ? tabWidth * shiftNumber + tabWidth / 2
               : -tabWidth * shiftNumber - tabWidth / 2,
             shiftSizeY,
           ];
         }
         return [RTL_UI ? -shiftSizeX : shiftSizeX, 0];
       }
       if (tab._tPos > draggedTab._tPos && tab._tPos < dropIndex) {
         // If tab is not index 0 and at the start of a row, shift across and up
         let tabRow = Math.floor(tab._tPos / maxTabsPerRow);
         let shiftedTabRow = Math.floor(
           (tab._tPos - movingTabs.length) / maxTabsPerRow
         );
         if (tab._tPos && tabRow != shiftedTabRow) {
           return [
             RTL_UI
               ? -tabWidth * shiftNumber - tabWidth / 2
               : tabWidth * shiftNumber + tabWidth / 2,
             -shiftSizeY,
           ];
         }
         return [RTL_UI ? shiftSizeX : -shiftSizeX, 0];
       }
       return [0, 0];
     };
     while (low <= high) {
       let mid = Math.floor((low + high) / 2);
       if (tabs[mid] == draggedTab && ++mid > high) {
         break;
       }
       let shift = getTabShift(tabs[mid], oldIndex);
       screenX = tabs[mid].screenX + shift[0];
       screenY = tabs[mid].screenY + shift[1];
       if (screenY + tabHeight < tabCenterY) {
         low = mid + 1;
       } else if (screenY > tabCenterY) {
         high = mid - 1;
       } else if (screenX > tabCenterX) {
         high = mid - 1;
       } else if (screenX + tabWidth < tabCenterX) {
         low = mid + 1;
       } else {
         newIndex = tabs[mid]._tPos;
         break;
       }
     }
     if (newIndex >= oldIndex) {
       newIndex++;
     }
     if (newIndex < 0 || newIndex == oldIndex) {
       return;
     }
     draggedTab._dragData.animDropIndex = newIndex;
     // Shift background tabs to leave a gap where the dragged tab
     // would currently be dropped.
     for (let tab of tabs) {
       if (tab != draggedTab) {
         let [shiftX, shiftY] = getTabShift(tab, newIndex);
         tab.style.transform =
           shiftX || shiftY ? `translate(${shiftX}px, ${shiftY}px)` : "";
       }
     }
   }
}
	
			Alles anzeigen