ist dir vielleicht ein Fehler beim Einfügen unterlaufen.
Schließe ich aus, aber schau ab Zeile 79.
CSS
// ==UserScript==
// @name zzzz-MultiRowTab_LiteforFx48.uc.js
// @namespace http://space.geocities.yahoo.co.jp/gl/alice0775
// @description 多段タブもどき実験版 CSS入れ替えまくりLiteバージョン
// @include main
// @compatibility Firefox128esr Firefox131+
// @author Alice0775
// @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() {
// -- Config --
const // タブバーの段数を指定するか無制限にするか選択する。
TabBar_Rows = true ,// [false] = 無制限
// true = 段数指定
Maximum_Rows = 2 ,// 段数指定(デフォルト3段)
// ProtonUI タブの見た目を変更する。
ProtonUI = false ,// [true] = タブをProtonUIのままにする。
// タブバーの高さはUI密度に上下の空白を足した高さです。
// false = Firefox90以前には出来ていたbrowser.proton.enabledをfalseに設定した時の見た目にする。
// タブの周りにある空白を0にしてUI密度の高さに調整します。
// タブバーの位置を変更する。
TabBar_Position = 1 ,// [0] = 初期位置
// 1 = ツールバーの下
// 2 = ウインドウの下
// UI密度 タブの高さ
UI_Density_Compact = 24 ,// デフォルト 29px コンパクト
UI_Density_Normal = 24 ,// デフォルト 36px 通常
UI_Density_Touch = 24 ,// デフォルト 41px タッチ
// 同じ様なCSSを書いた場合userChrome.cssの方が反映されます。
// タブの横幅
// 指定する数値を両方同じにすると横幅が固定化されます。
Tab_Min_Width = 271 ,// 最小値 デフォルト 76px
Tab_Max_Width = 271 ,// 最大値 デフォルト 225px
// 同じ様なCSSを書いた場合userChrome.cssの方が反映されます。
// .tab-drop-indicator アイコン差し替え。
Tab_Drop_Indicator = false ,// [false] = ピン📍のようなアイコン
// true = 赤線(2px × 29px)アイコン
// タブの左右に境界線を表示する。
Tab_Separators = false ,// [false] = 表示しない
// true = 表示する
// Firefox90以前には出来ていたbrowser.proton.enabledをfalseに設定したら表示する様になっていた境界線のCSSを抽出して調整しています。
// タブバードラッグ領域
Left_Drag_Area = 0 ,// 左のドラッグ領域:デフォルト 40px
Right_Drag_Area = 0 ,// 右のドラッグ領域:デフォルト 40px
Window_Maximize_Left_Drag_Area = false ,// true = ウィンドウを最大化した時、非表示になる 左のドラッグ領域が表示出来ます。
Fullscreen_Drag_Area = false ,// true = フルスクリーンにした時、非表示になる 左右のドラッグ領域が表示出来ます。
// ピン留めタブの位置を変更する。
Separate_Tabs_and_PinnedTabs = false ,// [false] = 初期位置
// true = ピン留めタブをタブの行から分離して上に出来る行へ移動する。
// タブを一覧表示するボタン
All_Tabs_Button = false ,// [false] = 非表示
// true = 表示
// -- Config End --
css = `
/*=== Tabschliessen-Button ** nur zu sehen bei Mouseover ===*/
/* Farbe der X-Markierung ändern */
.tab-close-button {
fill: white !important;
/* X grösser machen */
transform: scale(1.5, 1.5) !important;
/* Kreuz zum Schließen bei allen Tabs */
display: block !important;
opacity: 0 !important;
}
.tabbrowser-tab:hover .tab-close-button {
opacity: 1 !important;
color: red !important;
display: block !important;
background: none !important;
}
/* Icon inaktiver Tab verlagert */
.tabbrowser-tab:not([visuallyselected]) .tab-close-button {
margin-top: 1px !important;
}
/*Tab schließen Button verschoben bei Tabstext mittig*/
.tabbrowser-tab > .tab-stack > .tab-content > .tab-close-button {
flex-shrink: 0 !important;
width: 24px !important;
/* display: none !important; */ /* wird total ausgeblendet */
}
/** Tabschliessen-Button ** ENDE **/
/* Tab-Hintergrund */
/*--- selektiert (aktiv) ---*/
#tabbrowser-arrowscrollbox tab.tabbrowser-tab stack.tab-stack vbox.tab-background[selected]{
filter: none !important;
border: 1px solid blue !important;
/* min-height: 25px !important;
max-height: 25px !important; */
margin-top: 0px !important;
background: linear-gradient(45deg, gold, beige, orange) !important;
}
/*--- hover: Multi selektiert ---*/
.tabbrowser-tab:hover > .tab-stack > .tab-background[multiselected]:not([selected]) {
filter: brightness(130%) contrast(100%) !important;
}
/*--- Multi selektiert ---*/
.tab-background[multiselected]:not([selected]) {
filter: brightness(130%) saturate(50%) !important;
}
/* aktiver Tab bei Hover dunkler*/
#main-window .tabbrowser-tab[selected]:hover {
opacity: .5 !important;
}
/* inaktiver Tab */
.tab-background:not([selected]) {
background: linear-gradient( 0.35turn, grey, silver, white, grey) !important;
border: 1px solid #000 !important;
}
/* inaktiver tab farbe bei hover */
.tabbrowser-tab:not([selected]):hover .tab-content {
background: linear-gradient(45deg, grey, white, white, grey) !important;
border-right: 1px solid var(--lwt-background-tab-separator-color, rgba(0, 0, 0, 0.50)) !important;
border-left: 1px solid var(--lwt-background-tab-separator-color, rgba(0, 0, 0, 0.50)) !important;
}
html#main-window body toolbox#navigator-toolbox vbox#titlebar toolbar#TabsToolbar.browser-toolbar.titlebar-color hbox.toolbar-items hbox#TabsToolbar-customization-target.customization-target toolbarbutton#new-tab-button.toolbarbutton-1.chromeclass-toolbar-additional{
display: none !important;
}
/* Schrift im Zentrum des Tabs / ab Version 110 */
.tab-label-container {
height: unset !important;
margin-inline-end: 7px;
display: grid !important;
justify-items: safe center !important;
justify-content: safe center !important;
}
/* Breite für den Container automatisch (Schrift)*/
.tab-label-container {
margin: auto !important;
}
/*Tabtext beim Laden blau*/
.tabbrowser-tab[busy] .tab-label {
color: #cc0000 !important;
}
/* Schrift aktiver Tab */
.tabbrowser-tab[visuallyselected] .tab-label {
font-weight: bold !important;
color: blue !important;
font-size: 1.3em !important;
font-family: "Verdana, Helvetica", serif !important;
font-style: italic !important;
margin-top: -2px !important;
}
/* Text inaktiver Tab */
.tabbrowser-tab .tab-label {
margin-top: 0px !important;
}
/* Hintergrund Navigations- und Lesezeichensymbolleiste ausgeblendet */
#PersonalToolbar {
background: none !important;
opacity: 1.0 !important;
border: none !important;
}
/* Abstand der Tabs zur Lesezeichen-Symbolleiste */
#TabsToolbar{
margin-top: 2px !important;
padding-bottom: 1px !important;
padding-top: 2px !important;
}
/* Abstand Menü-Bar zur Url-Bar */
#toolbar-menubar {
margin-bottom: 1px !important;
margin-top: 1px !important;
}
/* Icon im Tab versetzt */
#TabsToolbar .tab-icon-image {
margin-left: -3px !important;
margin-bottom: 1px !important;
}
#PersonalToolbar{
margin-top: 4px !important;
}
#nav-bar{
appearance: none !important;
background-image: none !important;
background-color: #C2D3ED !important;
border-top: 1px solid grey !important;
border-bottom: 1px solid grey !important;
box-shadow: none !important;
}
#TabsToolbar {
/* UI密度 タブの高さ */
: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 ? `
/* .tab-drop-indicator アイコン差し替え。 background: url() no-repeat center !important; に追記してるのはpngファイルをbase64に変換した赤線(2px × 29px)です。 */
#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 !important;
}
.titlebar-spacer[type="post-tabs"] {
width: ${Right_Drag_Area}px !important;
}
${Window_Maximize_Left_Drag_Area ? `
.titlebar-spacer {
@media (-moz-platform: windows) {
:root:not([sizemode="normal"], [inFullscreen]) &[type="pre-tabs"] {
display: block !important;
}}}` : ``}
${Fullscreen_Drag_Area ? `
.titlebar-spacer {
:root[inFullscreen] &, :root:not([tabsintitlebar]) & {
display: block !important;
}}` : ``}
/* タブ タブバー スクロールバー */
#tabbrowser-arrowscrollbox {
&::part(scrollbox) {
${TabBar_Rows ? `
max-height: calc((var(--tab-min-height) + ${ProtonUI ? 8 : 0}px) * ${Maximum_Rows});
overflow: hidden auto;
& scrollbar {
-moz-window-dragging: no-drag;
}
/* Maximum_Rows を 1 にするとスライダの無いスクロールバーが表示されて気になったので Maximum_Rows を 1 に設定した時だけ非表示にしました。
スクロールバーは非表示になりますが動作はするのでタブバーに2段目以降があると縦方向にスクロール出来ます。 */
${Maximum_Rows !== 1 ? `` : `scrollbar-width: none;`}
` : ``}}
&::part(overflow-start-indicator),
&::part(overflow-end-indicator),
&::part(scrollbutton-up),
&::part(scrollbutton-down) {
display: none;
}
.tabbrowser-tab[fadein]:not([pinned]) {
--tab-min-width: ${Tab_Min_Width}px;
--tab-max-width: ${Tab_Max_Width}px;
max-width: var(--tab-max-width);
}}
/* ピン留めタブとタブの間に出来る空白を0にする。 */
#tabbrowser-tabs[haspinnedtabs]:not([positionpinnedtabs]):not([orient="vertical"]) > #tabbrowser-arrowscrollbox > .tabbrowser-tab:nth-child(1 of :not([pinned], [hidden])) {
margin-inline-start: 0px !important; /* デフォルト 12px */
}
${ProtonUI ? `` : `
/* タブの周りにある空白を0にしてUI密度の高さに調整 */
.toolbarbutton-1 {
margin: 0 !important;
padding: 0 !important;
}
.tabbrowser-tab,
#tabs-newtab-button {
height: var(--tab-min-height);
padding: 0 !important;
}
.tab-background {
box-shadow: none !important;
margin-block: 0 !important;
/* border-radius: 0 !important; */
}
/* コンテナータブ */
.tabbrowser-tab[usercontextid] > .tab-stack > .tab-background > .tab-context-line {
/* タブの周りにある空白を0にする調整で上のカラーバーが隠れるので見える様に調整 */
margin: 1px 2px 0; /* デフォルト margin: -3px 2px 0; */
}`}
${Tab_Separators ? `
.titlebar-spacer[type="pre-tabs"] {
border-inline-end: 1px solid color-mix(in srgb, currentColor 20%, transparent);
}
.tabbrowser-tab::after,
.tabbrowser-tab::before {
border-left: 1px solid color-mix(in srgb, currentColor 50%, transparent);
height: calc(var(--tab-min-height) - 16.5%);
margin-block: auto;
}
.tabbrowser-tab:hover::after,.tabbrowser-tab[multiselected]::after,
#tabbrowser-tabs:not([movingtab]) .tabbrowser-tab:has(+ .tabbrowser-tab:hover)::after,
#tabbrowser-tabs:not([movingtab]) .tabbrowser-tab:has(+ [multiselected])::after {
height: 100%;
}
.tabbrowser-tab::after,
#tabbrowser-tabs[movingtab] .tabbrowser-tab[visuallyselected]::before {
content: "";
display: block;
}` : ``}
${All_Tabs_Button ? `` : `
/* タブを一覧表示するボタン */
#alltabs-button {
display: none;
}`}
}
/* 多段タブ */
scrollbox[part][orient="horizontal"] {
&:has(+ spacer) > slot,
.scrollbox-clip > & {
flex-wrap: wrap;
}}
${Separate_Tabs_and_PinnedTabs ? `
/* ピン留めタブをタブの行から分離して上に出来る行へ移動する。 */
scrollbox[part][orient="horizontal"] {
&:has(+ spacer) > slot::after,
.scrollbox-clip > &::after {
display: flow-root list-item;
content: "";
flex-basis: -moz-available;
height: 0;
overflow: hidden;
}}
#TabsToolbar {
#tabbrowser-tabs[haspinnedtabs] {
.tabbrowser-tab:not([pinned]) {
&, & + :not(#tabs-newtab-button) {
order: 1;
}}}}` : ``}
${TabBar_Position === 0 ? `
/* タイトルバーボタン[-□×] */
#TabsToolbar {
.titlebar-buttonbox-container {
height: calc(var(--tab-min-height) + ${ProtonUI ? 8 : 0}px);
margin-bottom: 0 !important;
}}` : `
#nav-bar {
:root:not([inFullscreen]) #toolbar-menubar:not([inactive]) + & > .titlebar-buttonbox-container {
display: none;
}
.titlebar-button {
padding-block: 0 !important;
}}`}
${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: .5px solid transparent;
& > #navigator-toolbox {
max-height: 0;
}}}}`}
`,
sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService),
uri = Services.io.newURI("data:text/css;charset=UTF=8," + encodeURIComponent(css));
if (TabBar_Rows == false) {
["0", "2"].find(type => {
if(sss.sheetRegistered(uri, type)) sss.unregisterSheet(uri, type); sss.loadAndRegisterSheet(uri, type);
});
} else {
["0", "2", "SSTabRestored", "TabMove", "TabOpen", "TabSelect"].find(type => {
if(sss.sheetRegistered(uri, type)) sss.unregisterSheet(uri, type); sss.loadAndRegisterSheet(uri, type);
gBrowser.tabContainer.addEventListener(type, (e) => { e.target.scrollIntoView({ block: "nearest" }); });
});
}
if (TabBar_Position !== 0) {
if (TabBar_Position === 1) {
document.getElementById("navigator-toolbox").prepend(
document.getElementById("toolbar-menubar"),
document.getElementById("nav-bar"),
document.getElementById("PersonalToolbar"),
document.getElementById("titlebar"),
);
} else {
document.getElementById("navigator-toolbox").prepend(
document.getElementById("toolbar-menubar"),
document.getElementById("nav-bar"),
document.getElementById("PersonalToolbar"),
);
}
document.getElementById("nav-bar").appendChild(
document.querySelector("#TabsToolbar > .titlebar-buttonbox-container")
);
}
if (TabBar_Position === 2) {
document.body.appendChild(
document.createXULElement("tabbox")
).appendChild(
document.importNode(document.getElementById("navigator-toolbox"))
).appendChild(
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;
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 newMarginX, newMarginY;
let newIndex = this._getDropIndex(event);
let children = this.allTabs;
if (newIndex == children.length) {
let tabRect = this._getVisibleTabs().at(-1).getBoundingClientRect();
newMarginX = tabRect.right - rect.left;
newMarginY = tabRect.top - rect.top + tabRect.height / 2 - rect.height / 2;
} else {
let tabRect = children[newIndex].getBoundingClientRect();
newMarginX = tabRect.left - rect.left;
newMarginY = tabRect.top - rect.top + tabRect.height / 2 - rect.height / 2;
}
ind.hidden = false;
newMarginX += ind.clientWidth / 2;
ind.style.transform = "translate(" + Math.round(newMarginX) + "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 oldTranslate = Math.round(draggedTab._dragData.translatePos);
let tabSize = Math.round(draggedTab._dragData.tabSize);
let translateOffset = oldTranslate % tabSize;
let newTranslate = oldTranslate - translateOffset;
if (oldTranslate > 0 && translateOffset > tabSize / 2) {
newTranslate += tabSize;
} else if (oldTranslate < 0 && -translateOffset > tabSize / 2) {
newTranslate -= tabSize;
}
let dropIndex;
if (draggedTab._dragData.fromTabList) {
dropIndex = this._getDropIndex(event);
} else {
dropIndex = this._getDropIndex(event);
// "animDropIndex" in draggedTab._dragData &&
// draggedTab._dragData.animDropIndex;
}
let incrementDropIndex = true;
if (dropIndex && dropIndex > movingTabs[0]._tPos) {
dropIndex--;
incrementDropIndex = false;
}
if (oldTranslate && oldTranslate != newTranslate && !gReduceMotion) {
for (let tab of movingTabs) {
tab.toggleAttribute("tabdrop-samewindow", true);
tab.style.transform = this.verticalMode
? "translateY(" + newTranslate + "px)"
: "translateX(" + newTranslate + "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;
}
}
};
Alles anzeigen