Danke dir.
Während es bei dem Icon von "Geschlossenen Tab wiederherstellen" tadellos funktioniert, scheinen beide CSS Codes nicht bei "Temporary Containers" Icon zu funktionieren.
Danke dir.
Während es bei dem Icon von "Geschlossenen Tab wiederherstellen" tadellos funktioniert, scheinen beide CSS Codes nicht bei "Temporary Containers" Icon zu funktionieren.
Benötigt man dafür die Entwickler Version von Firefox oder bin ich nur blind? Finde nur Konsole oder Werkzeuge für Web-Entwickler, die eben nicht außerhalb des Inhaltsbereichs arbeitet.
Ah verstehe, habe es für die jeweiligen Icons einzustellen, anstatt für die Position. Wo kriege ich denn die Bezeichnung der beiden betreffenden Addons her? Unter About:support wäre z.B. die UBlock ID: "uBlock0@raymondhill.net"
Besteht denn die Möglichkeit, dass man die Größe von Add-Ons Icons in der Tableiste mit der Tabhöhe gleich setzt?
Das sieht so bei mir aus:
// 'MultiRowTabs.uc.js' V02 by BrokenHeart
// based on 'MultiRowTab_LiteforFx48.uc.js' from 'http://space.geocities.yahoo.co.jp/gl/alice0775' (Alice0775)
// Thanks to aborix...
"use strict";
MultiRowTabs();
function MultiRowTabs() {
if (!window.gBrowser){
return;
}
// ----------------------------
// --- User-Settings: Start ---
// ----------------------------
// Position der Tab-Leiste:
//
var nTabbarPosition = 1; // [1] Tab-Leiste ist oberhalb aller Symbolleisten
// [2] Tab-Leiste ist unterhalb aller Symbolleisten, aber über dem Inhaltsbereich
// [3] Tab-Leiste ist vertikal auf der linken Seite
// [4] Tab-Leiste ist vertikal auf der linken Seite - Tableiste wird erst angezeigt bei Mausbewegung an den linken Rand (Autohide/Autopopup)
// [5] Tab-Leiste ist vertikal auf der rechten Seite
// [6] Tab-Leiste ist unterhalb des Inhaltsbereichs
// Tab-Größenangaben
//
var nTabWidth = 190; // Breite der einzelnen Tabs in Pixeln
var nTabHeight = 24; // Höhe der einzelnen Tabs in Pixeln
var nTabMargin = 1; // Abstand zwischen den Tab-Zeilen in Pixeln
// sonstige Einstellungen
//
var nTabLines = 3; // Anzahl der sichtbaren Tab-Zeilen, darüber hinaus wird gescrollt <nur bei horizontaler Ausrichtung (Position:[1],[2],[6]) - sonst keine Funktion>
var bTabScrollbar = true; // [true] Scrollbar für Tab-Leiste anzeigen, [false] Keine Scrollbar für Tab-Leiste anzeigen (Achtung: [false] = kein Scrollen mehr bei 'drag&drop' von Tabs!)
var bTabTooltips = true; // [true] Tab-Tooltips werden angezeigt, [false] Tab-Tooltips werden nicht angezeigt
// Tab-Schließen-Button
//
var bTabCloseButton = true; // [true] Tab-Schließen-Button anzeigen, [false] Tab-Schließen-Button verbergen
var bTabCloseButRounded = false; // [false] quadratische Darstellung, [true] abgerundete Darstellung
var nTabCloseButTransparency= 0.85; // Transparenzwert des Tab-Schließen-Button in Prozent. Wertebereich: [0]=vollständig durchscheinend bis [1]=vollständig deckend (z.B [0.75])
var nTabCloseIconNr = 1; // [0] Standard-Icon wird angezeigt
// [1] rotes Icon mit weißem Kreuz wird angezeigt
// [2] schwarzes Icon mit weißem Kreuz wird angezeigt
var nTabCloseButSize = 18; // Höhe und Breite des Tab-Schließen-Buttons in Pixeln
// FavIcon
//
var nFavIconSize = 16; // Höhe und Breite des 'FavIcons' und der Ladeanimation,[16] = Standard
// 'Throbber'-Animation
//
var bNewThroberAnimation = true; // [true] Alternative 'Throbber'-Animation auswählen, [false] Standard 'Throbber'-Animation beibehalten
// Hintergrundfarbe der Tabs (für einfarbige Darstellung müssen die RGB-Farbwerte 1 und 2 jeweils identisch sein)
//
var strTabSelColor1 = "103,171,224";// RGB-Farbwert1 selektierter Tab
var strTabSelColor2 = "30,78,115"; // RGB-Farbwert2 selektierter Tab
var strTabNotSelColor1 = "54,72,86"; // RGB-Farbwert1 nicht selektierter Tab
var strTabNotSelColor2 = "28,32,44"; // RGB-Farbwert2 nicht selektierter Tab
var nTabTransparency = 1; // Transparenzwert des unselektierten Tab Hintergrundes. Wertebereich: [0]=vollständig durchscheinend bis [1]=vollständig deckend (z.B [0.75])
// Schriftart und Textdarstellung der Tabs
//
var strTabFontName = "Arial"; // Name der Schriftart
var strTabFontColorSel = "255,255,255";// RGB-Farbwert der Schrift des selektierten Tabs
var strTabFontColorNotSel = "215,215,215";// RGB-Farbwert der Schrift des nicht selektierten Tabs
var nTabFontWeight = 500; // Stärke der Schrift: Wertebereich: [100] = sehr dünn bis [900] = sehr dick(bold). [500] = normal
var nTabFontSize = 12; // Größe/Höhe der Schrift in Pixeln
var bTabFontTextShadow = true; // [true] Text wird mit Schatteneffekt ausgegeben, [false] Text wird ohne Schatteneffekt ausgegeben. (Effekt nur bei selektierten Tabs!)
var bMarkUnreadTab = false; // [true] Kursive Schrift für ungelesene Tabs, [false] ungelesene Tabs werden nicht hervorgehoben
// Rahmen um einzelne Tabs
//
var nTabBorderWidth = 0; // Breite des Tab-Rahmen ([0] = kein sichtbarer Rahmen)
var nTabBorderRadius = 0; // Radius für abgerundete Ecken des Tabs ([0] = rechteckig, [80] = ideal abgerundet ).
var strTabBorderColor = "128,128,128";// RGB-Farbwert des Rahmens
// Neuer-Tab-Button
//
var strNewTabButtonColor = "255,255,255";// RGB-Farbwert des '+'-Zeichens
// Hintergrund der Tab-Leiste (für einfarbige Darstellung müssen die RGB-Farbwerte 1 und 2 jeweils identisch sein)
//
//var strTabBarBgColor1 = "15,24,27"; // RGB-Farbwert1 für Hintergrund der Tab-Leiste
//var strTabBarBgColor2 = "96,123,134"; // RGB-Farbwert2 für Hintergrund der Tab-Leiste
var strTabBarBgColor1 = "21,21,12"; // RGB-Farbwert1 für Hintergrund der Tab-Leiste
var strTabBarBgColor2 = "62,75,84"; // RGB-Farbwert2 für Hintergrund der Tab-Leiste
var nTabBarTransparency = 1; // Transparenzwert des Tab-Leisten Hintergrundes. Wertebereich: [0]=vollständig durchscheinend bis [1]=vollständig deckend
var strTabBarBgImagePath = ""; // Absoluter Dateipfad zu einem gepeicherten Bild (z.B.: "D://Bilder//Firefox//Hintergrund.jpg" )
// "D://Programme%20(Portable)//Firefox%20Portable//FireFox%20ESR%2091//Profilordner//chrome//image//NavToolbarBackground02.png"
var bTabBarBgImageRepeat = false; // [true] Bild wird für den gesamten Bereich mehrfach nebeneinander angezeigt, [false] Bild wird nur einmal angezeigt (Position: linke/obere Ecke)
// Einstellungen für vertikale Tab-Leiste
//
var nVerticalTabbarWidth = 215; // Breite der Vertikalen Tab-Leiste in Pixeln <nur bei vertikaler Ausrichtung (Position:[3],[4],[5]) - sonst keine Funktion>
var nVerticalAutoPopupHover = 2; // Abstand zum linken Fensterrand in Pixeln, ab der die vertikale Tab-Leiste sichtbar gemacht wird <Position[4] - sonst keine Funktion>
var nVerticalAutoPopupAnim = 0.5; // Dauer der Animation beim 'Herausschieben' des vertikalen Tab-Leiste in Sekunden ([0] = keine Animation) <Position[4] - sonst keine Funktion>
// Einstellungen für Maus-Bedienung
//
var bTabWheel = false; // [true]: Tab-Wheel-Selection(=Selektieren des nächsten/vorherigen Tabs mit dem Mausrad) einschalten, [false]: Tab-Wheel-Selection ausschalten
var bPageScroll = true; // [true]: seitenweises Scrollen, [false]: zeilenweises Scrollen
var bDblclickOnTabbarNewTab = true; // [true] Doppel-Klick über Tabbar öffnet neuen Tab, [false] Funktion wird nicht ausgeführt
var bDblclickOnTabReloadTab = true; // [true] Doppel-Klick über Tab lädt diesen neu, [false] Funktion wird nicht ausgeführt
// ----------------------------
// --- User-Settings: Ende ---
// ----------------------------
Alles anzeigen
Hab den Fehler gefunden: Ich habe zwei Addons in die Tableiste gezogen (Geschlossener Tab wiederherstellen, Temporary Containers). Es müssten also die Add-Ons Icons in der Leiste verkleinert werden.
Mit Wert auf 2:
Hab mal weiter getestet. Der Fehler scheint bei mir aufzutreten, sobald die Tabhöhe unter 30 liegt. Ist das Eventuell eine Mindesthöhe für die Tableiste?
Das sollte auf jeden Fall nicht so aussehen wie auf deinen Screenshots. Hast du noch eigene Anpassungen (an der Tableiste?) in der userChrome.css gemacht?
Gerade getestet indem ich alle weiteren Skripts/CSS in den Papierkorb verschoben hatte. Liegt also an dem Skript selbst.
Wie dem auch sei, dass ist ja nur eine Kleinigkeit. Dafür brauchst du dann keine Zeit verschwenden, insbesondere wenn du mit dem neu schreiben des Skripts beschäftigt bist.
Sieht hier so aus
Schätze der Abstand tritt nur auf, wenn man die Tableiste unterhalb der Symbolleiste setzt (Option 2).
Und im Script gibt es doch die Möglichkeit die Breite anzupassen.
Das habe ich auch gemacht. Ich würde mir nur wünschen, dass man die Breite variabel hat. Bei wenigen Tabs in einer Zeile, sollen die Tabs sehr breit sein (um quasi die Leerfläche gut zu nutzen), aber mit zunehmenden Tabs schmaler werden, bis zu einem gewissen Minimum.
Hallo zusammen,
Ich bin gerade von alice0775 Multirow Skript zu dem von BrokenHeart aus dem ersten Post gewechselt.
Mir ist zu einem folgender Fehler aufgefallen:
Wenn man die Menüleiste ausblendet und nicht das MoveMinMaxCloseButton Skript nutzt, kann man, mit betätigen der "Alt"-Taste auf der Tastatur, die Menüleiste einblenden. Das funktioniert auch wie gehabt, nur sind die Buttons MinMaxClose ohne Funktion. Bei eingeblendeter Menüleiste funktionieren diese tadellos.
Außerdem habe ich zwei Fragen:
Besteht die Möglichkeit die Tab Breite variabel zu definieren? Mit dem alten Skript habe ich die Standardbreite auf 240px gehabt, sobald mehrere Tabs in der Zeile waren, ist die Breite auf bis zu 160px geschrumpft.
Solange man nur eine Tab Zeile hat, ist der Abstand zum Fensterinhalt relativ groß und schrumpft, sobald man zwei oder mehr Zeilen hat. Kann man diesen Abstand bereits für nur eine Zeile verringern?
Es gab wieder ein Update des Multirow Skripts. (Weiterhin Variante 04)
Ich habe keine Ahnung welche Änderung dafür verantwortlich ist, aber die Darstellungsprobleme in Kombination mit Alternative_Searchbar Skript sind damit behoben.
Jetzt erst darf der Thread auch wirklich als erledigt angesehen werden. Danke.
Die beiden Einträge befinden sich im Alternate Searchbar Skript.
Wie erwähnt funktioniert jedes Skript für sich genommen tadellos. Bloß wenn man beide in Kombination nutzen will, führt es zu Problemen.
Und diese tauchten erst mit Version 96 von Firefox auf. Davor gab es auch in Kombination kein Problem durch die beiden Skripte.
Mit der kürzlich aktualisierten Version des Multirow Skripts besteht das Problem auch weiterhin.
Dies hat aber nichts mit den Problemen aus dem ersten Post zu tun, sondern hat sich nur zufällig ergeben.
Das eigentliche Problem besteht weiterhin.
Das war nur ein Problem, dass sich beim posten des Problems bemerkbar machte. Es ging dabei nur darum, dass ich herausgefunden habe, warum Codes die ich einfüge nicht korrekt dargestellt werden.
Das Problem der zwei Skripts die Darstellungsprobleme kombiniert verursachen, liegen unverändert fort.
Aus dem Script
// @include *://*
Ergänzen um (Beispiel)
// @exclude */www.camp-firefox.de/*
Damit werden bestimmte Seiten ausgenommen.
Danke hab es in den Violentmonkey Einstellungen des Skripts als Ausnahme hinzugefügt, damit eventuelle Updates nicht überschreiben.
Dies hat aber nichts mit den Problemen aus dem ersten Post zu tun, sondern hat sich nur zufällig ergeben.
Das eigentliche Problem besteht weiterhin.
Hab es aus Notepad++ und Notepad kopiert um sicher zugehen, dass nicht das Programm die Einrückungen geschluckt hat. Eventuell hätte ich es direkt von Github kopieren sollen.
Halte dich an die Schrittfolge, wie ich sie dir beschrieben habe und du hast dann auch eine wunderschöne Formatierung. Das klappt immer.
Habe den Fehler gefunden: Das Userscript/Violentmonkey Skript Absolute Enable Right Click hat interveniert und die Probleme verursacht.
Hat er doch gemacht
Hat aber nicht richtig funktioniert. Und ich habe ihm eine Schritt-für-Schritt-Anleitung gegeben, wie es auf jeden Fall funktioniert und mit Syntax-Hervorhebung.
Hab es aus Notepad++ und Notepad kopiert um sicher zugehen, dass nicht das Programm die Einrückungen geschluckt hat. Eventuell hätte ich es direkt von Github kopieren sollen.
€: Habe es auch penibel genau befolgt, dennoch kam ich aufs selbe Ergebnis. Kann leider nicht sagen warum die Formatierung "geschluckt" wird. Sowohl Notepad++ als auch Windows Notepad zeigen die Formatierung bei mir an.
hab ich den Schalter für alte Darstellung und Namen an in der Suchleiste
Welchen Schalter meinst du damit?
Ansonsten kann ich dein Problem hier nicht bestätigen
Mehrmals Fenstergröße verändert...Neustart..alles Ok hier
Um absolut sicher zu gehen, habe ich noch einmal alles im Chrome Ordner, außer "userChrome.js", "alternative_searchbar.uc.js" und "MultiRowTabLiteforFx.uc.js", in den Papierkorb verschoben. Doch der Fehler tritt weiterhin auf. Er tritt zwar nicht immer auf, aber in den meisten fällen.
Umgekehrt tritt der Fehler nicht mehr auf, wenn ich nur alternative Searchbar lösche oder aber nur Multirow und alles andere bleibt erhalten.
Ich habe keine Ahnung wo noch der Unterschied liegen könnte.
Hier auch einmal die Skripte angehangen, wobei ich ursprünglich dachte die Ansicht über Github ist am bequemsten:
// 'Alternative search bar' script for Firefox 91+ by Aris
//
// Thanks to UndeadStar (aka BoomerangAide) for Fx 69+ improvements
// https://github.com/Aris-t2/CustomJSforFx/issues/11
//
// Thanks to samehb (aka Sameh Barakat) for Fx 68-75+ improvements
// https://github.com/Aris-t2/CustomJSforFx/issues/11
//
// Thanks to anomiex for the setIcon workaround on Fx 77+
// https://github.com/Aris-t2/CustomJSforFx/issues/33
//
// Idea based on 'search revert' script by '2002Andreas':
// https://www.camp-firefox.de/forum/viewtopic.php?f=16&t=112673&start=2010#p1099758
//
// Initial "old search" script ported from old Firefox versions by Aris
//
//
// Feature (not optional): search glass is always visible at search bars end (like with "old" search)
// Feature (not optional): search button shows current search engines icon (like with "old" search)
// Feature (not optional): search buttons dropmarker is always visible (like with "old" search)
//
// Option: clear search input after search
// Option: revert to first search engine in list after search
// Option: old search engine selection popup
// Option: hide 'add engines' '+' indicator
// Option: hide 'oneoff' search engines (engines at popups bottom)
// Option: hide placeholder text 'Search'
// Option: swap the icons of search engine button and go button
// Option: show icons and search engine names instead of only icons
// Option: select search engine by scrolling mouse wheel over search bars button
// [!] Default browser feature: search engine can be changed inside default/modern popup by right-clicking
// search icon and selecting 'Set As Default Search Engine' menuitem.
// Configuration area - start (all 'false' by default)
var clear_searchbar_after_search = false; // clear input after search (true) or not (false)
var revert_to_first_engine_after_search = false; // revert to first engine (true) or not (false)
var old_search_engine_selection_popup = true; // show old search engine selection popup (true) or not (false)
var select_engine_by_scrolling_over_button = false; // select search engine by scrolling mouse wheel over search bars button (true) or not (false)
var select_engine_by_click_oneoffs_button = false; // select search engine by left-clicking search icon (true) or not (false)
var hide_oneoff_search_engines = false; // hide 'one off' search engines (true) or not (false)
var hide_addengines_plus_indicator = false; // hide add engines '+' sign (true) or not (false)
var hide_placeholder = false; // hide placeholder (true) or not (false)
var switch_glass_and_engine_icon = false; // swap icons of search engine button and go button (true) or not (false)
var show_search_engine_names = true; // show search engine names (true) or not (false)
var show_search_engine_names_with_scrollbar = false; // show search engine names with scrollbars (true) or not (false)
var show_search_engine_names_with_scrollbar_height = '170px'; // higher values show more search engines
var initialization_delay_value = 0; // some systems might require a higher value than '1' second (=1000ms) and on some even '0' is enough
var searchsettingslabel = "Ändere Sucheinstellungen";
// Configuration area - end
var isInCustomize = 1; //start at 1 to set it once at startup
Cu.import('resource://gre/modules/Services.jsm');
var AltSearchbar = {
init: async function() {
await Services.search.wrappedJSObject._initObservers.promise;
if (location != 'chrome://browser/content/browser.xhtml')
return;
window.removeEventListener("load", AltSearchbar.init, false);
try {
var searchbar = document.getElementById("searchbar");
var appversion = parseInt(Services.appinfo.version);
if(!old_search_engine_selection_popup)
updateStyleSheet();
if(hide_placeholder)
hideSearchbarsPlaceholder();
if(select_engine_by_scrolling_over_button)
selectEngineByScrollingOverButton();
if(old_search_engine_selection_popup)
createOldSelectionPopup();
if (select_engine_by_click_oneoffs_button)
selectEngineByClickOneoffsButton();
// select search engine by scrolling mouse wheel over search bars button
function selectEngineByScrollingOverButton() {
searchbar.addEventListener("DOMMouseScroll", (event) => {
if (event.originalTarget.classList.contains("searchbar-search-button")) {
searchbar.selectEngine(event, event.detail > 0);
}
}, true);
};
// left click on off select engine
function selectEngineByClickOneoffsButton() {
var searchoneoffs = searchbar.textbox.popup.oneOffButtons;
searchoneoffs.container.addEventListener("click", (event) => {
if (!(event instanceof KeyboardEvent) && (event.button == 0)) {
event.stopPropagation();
event.target.classList.add("search-one-offs-context-set-default");
searchoneoffs._contextEngine = event.target.engine;
searchoneoffs._on_command(event);
searchoneoffs._contextEngine = null;
// let contextEngine = event.target.engine;
// let currentEngine = searchbar.currentEngine;
// if (!searchoneoffs.getAttribute("includecurrentengine")) {
// // Make the target button of the context menu reflect the current
// // search engine first. Doing this as opposed to rebuilding all the
// // one-off buttons avoids flicker.
// let button = searchoneoffs._buttonForEngine(contextEngine);
// button.id = searchoneoffs._buttonIDForEngine(currentEngine);
// let uri = "chrome://browser/skin/search-engine-placeholder.png";
// if (currentEngine.iconURI) {
// uri = currentEngine.iconURI.spec;
// }
// button.setAttribute("image", uri);
// button.setAttribute("tooltiptext", currentEngine.name);
// button.engine = currentEngine;
// }
// searchbar.currentEngine = contextEngine;
}
}, true);
};
// hide placeholder
function hideSearchbarsPlaceholder() {
searchbar.getElementsByClassName('searchbar-textbox')[0].removeAttribute("placeholder");
};
function attachOldPopupToButton(e) {
if(isInCustomize == 1) {
setTimeout(function () { searchbar.getElementsByClassName("searchbar-search-button")[0].setAttribute("popup", "searchbuttonpopup"); }, initialization_delay_value);
}
if(isInCustomize > 0)
isInCustomize--;
}
// old search selection popup
async function createOldSelectionPopup() {
searchbar.engines = await Services.search.getVisibleEngines();
window.addEventListener("beforecustomization", function(e) { isInCustomize++; }, false);
window.addEventListener("aftercustomization", attachOldPopupToButton, false);
// set new search engine
searchbar.setNewSearchEngine = function(index) {
searchbar.currentEngine = searchbar.engines[index];
updateStyleSheet();
};
// create search popup
searchbuttonpopup = document.createXULElement("menupopup");
searchbuttonpopup.setAttribute("id", "searchbuttonpopup");
searchbuttonpopup.setAttribute("width", searchbar.getBoundingClientRect().width - 6 );
searchbuttonpopup.setAttribute("position", "after_start");
try {
var hidden_list = Services.prefs.getStringPref("browser.search.hiddenOneOffs");
hidden_list = hidden_list ? hidden_list.split(",") : [];
for (var i = 0; i <= searchbar.engines.length - 1; ++i) {
if(!hidden_list.includes(searchbar.engines[i].name)) {
menuitem = document.createXULElement("menuitem");;
menuitem.setAttribute("label", searchbar.engines[i].name);
menuitem.setAttribute("tooltiptext", searchbar.engines[i].name);
menuitem.setAttribute("class", "menuitem-iconic searchbar-engine-menuitem menuitem-with-favicon");
if (searchbar.engines[i] == searchbar.currentEngine)
menuitem.setAttribute("selected", "true");
if (searchbar.engines[i].iconURI)
menuitem.setAttribute("image",searchbar.engines[i].iconURI.spec);
menuitem.setAttribute("oncommand", "document.getElementById('searchbar').setNewSearchEngine("+i+")");
searchbuttonpopup.appendChild(menuitem);
}
}
menuseparator_om = document.createXULElement("menuseparator");
searchbuttonpopup.appendChild(menuseparator_om);
menuitem_om = document.createXULElement("menuitem");
menuitem_om.setAttribute("label", searchsettingslabel);
menuitem_om.setAttribute("class", "open-engine-manager");
menuitem_om.setAttribute("oncommand", "openPreferences('search');");
searchbuttonpopup.appendChild(menuitem_om);
updateStyleSheet();
} catch(exc) {
console.log("Exception AltSearchbar: " + exc);
}
document.getElementById("mainPopupSet").appendChild(searchbuttonpopup);
// adjust popup width
setTimeout(function(){
document.getElementById('searchbuttonpopup').setAttribute("width", document.getElementById("searchbar").getBoundingClientRect().width);
},1000);
var observer_width = new MutationObserver(function(mutations,observer) {
observer.disconnect();
try {
document.getElementById('searchbuttonpopup').setAttribute("width", document.getElementById("searchbar").getBoundingClientRect().width );
} catch(e){}
observer.observe(document.getElementById('search-container'), { attributes: true, attributeFilter: ['width'] });
observer.observe(document.getElementById('main-window'), { attributes: true, attributeFilter: ['sizemode'] });
});
try {
observer_width.observe(document.getElementById('search-container'), { attributes: true, attributeFilter: ['width'] });
observer_width.observe(document.getElementById('main-window'), { attributes: true, attributeFilter: ['sizemode'] });
} catch(e){}
// restore "add search engine" menuitem
// attach new popup to search bars search button
try {
attachOldPopupToButton();
}
catch(e) {
console.log("AltSearchbar: Failed to attach new popup to search bar search button");
}
// Refresh the script's search popup (searchbuttonpopup) with any changes made to search engines/options.
async function updateEngines() {
var i;
try {
searchbuttonpopup = document.getElementById("searchbuttonpopup");
searchbar.engines = await Services.search.getVisibleEngines();
try {
while (searchbuttonpopup.childNodes[0].tagName.toLowerCase() != "menuseparator")
searchbuttonpopup.removeChild(searchbuttonpopup.firstChild);
var separator = searchbuttonpopup.childNodes[0];
var hidden_list = Services.prefs.getStringPref("browser.search.hiddenOneOffs");
hidden_list = hidden_list ? hidden_list.split(",") : [];
for (i = 0; i <= searchbar.engines.length - 1; ++i) {
if (!hidden_list.includes(searchbar.engines[i].name)) {
menuitem = document.createXULElement("menuitem");;
menuitem.setAttribute("label", searchbar.engines[i].name);
menuitem.setAttribute("class", "menuitem-iconic searchbar-engine-menuitem menuitem-with-favicon");
menuitem.setAttribute("tooltiptext", searchbar.engines[i].name);
if (searchbar.engines[i] == searchbar.currentEngine)
menuitem.setAttribute("selected", "true");
if (searchbar.engines[i].iconURI)
menuitem.setAttribute("image", searchbar.engines[i].iconURI.spec);
menuitem.setAttribute("oncommand", "document.getElementById('searchbar').setNewSearchEngine(" + i + ")");
searchbuttonpopup.insertBefore(menuitem, separator);
}
}
updateStyleSheet();
} catch (exc) {
console.log(exc);
}
} catch (exc) {
console.log("update altbar exc: " + exc);
}
}
// Used to observe modifications made to search engines. We are only interested in the addition and removal of engines.
Services.obs.addObserver(function observer(subject, topic, data) {
// If a search engine/option is added or removed, we need to refresh the script's popup. We use updateEngines() to do that.
if (data == "engine-added" || data == "engine-removed" || data == "engine-changed") {
updateEngines();
}
}, "browser-search-engine-modified");
// Observe the enabling and disabling of search engines, and update the search popup.
Services.prefs.addObserver("browser.search.hiddenOneOffs", function observer(subject, topic, data) {
updateEngines();
});
// Used to create an add engine item and append it into the script's search popup (searchbuttonpopup). This is the option
// that is displayed as "Add enginename" e.g. Add DuckDuckGo.
function createAddEngineItem(e) {
try {
e.target.removeEventListener(e.type, arguments.callee);
searchbuttonpopup = document.getElementById("searchbuttonpopup");
while (searchbuttonpopup.lastChild.classList.contains("custom-addengine-item")) {
searchbuttonpopup.removeChild(searchbuttonpopup.lastChild);
}
setTimeout(function () { //setTimeout fix an issue where labels don't get displayed
let native_popup_search_add_items_collection = document.getElementsByClassName("searchbar-engine-one-off-add-engine");
var native_popup_search_add_items = new Array();
for(i = 0; i < native_popup_search_add_items_collection.length; i++) {
if(!native_popup_search_add_items_collection[i].parentElement.parentElement.parentElement.parentElement.hasAttribute("class")) {
native_popup_search_add_items.push(native_popup_search_add_items_collection[i]);
}
}
if (native_popup_search_add_items.length != 0) {
if (searchbuttonpopup.lastChild.tagName.toLowerCase() != "menuseparator") {
searchbuttonpopup.appendChild(document.createXULElement("menuseparator"));
searchbuttonpopup.appendChild(document.createXULElement("menuseparator"));
}
for(i = 0; i < native_popup_search_add_items.length; i++) {
menuitem = document.createXULElement("menuitem");
menuitem.setAttribute("label", native_popup_search_add_items[i].getAttribute("label"));
menuitem.setAttribute("class", "menuitem-iconic searchbar-engine-menuitem menuitem-with-favicon custom-addengine-item");
menuitem.setAttribute("tooltiptext", native_popup_search_add_items[i].getAttribute("label"));
menuitem.setAttribute("uri", native_popup_search_add_items[i].getAttribute("uri"));
menuitem.setAttribute("data-id", native_popup_search_add_items[i].id);
menuitem.setAttribute("oncommand", "document.getElementById(\"" + native_popup_search_add_items[i].id + "\").click();");
if (native_popup_search_add_items[i].hasAttribute("image"))
menuitem.setAttribute("image", native_popup_search_add_items[i].getAttribute("image"));
searchbuttonpopup.appendChild(menuitem);
};
}
else {
while (searchbuttonpopup.lastChild.tagName.toLowerCase() == "menuseparator")
searchbuttonpopup.removeChild(searchbuttonpopup.lastChild);
}
}, 0 );
}
catch (exc) {
console.log("custom addengine exc: " + exc);
}
}
searchbar.addEventListener("mousedown", (event) => {
var defaultPopup = document.getElementById("PopupSearchAutoComplete"); // Browser's default search popup.
var scriptPopup = document.getElementById("searchbuttonpopup");
var addEngineItem = document.getElementsByClassName("custom-addengine-item")[0];
var searchButton = document.getElementsByClassName("searchbar-search-button")[0];
// hasAddEnginesAttribute == true means there is a search engine provided by the page, for us to add using "Add enginename."
// You will see a green plus badge on the search button icon, if that is the case.
var hasAddEnginesAttribute = searchButton.hasAttribute("addengines");
// Skip clicks on the search button until searchbuttonpopup is available. Disable propagation, too.
if (!scriptPopup) {
event.stopPropagation();
return;
}
defaultPopup.style.visibility = "visible";
// If the user clicks on any element on the search bar except the search text.
if (event.target.getAttribute("class") != "searchbar-textbox") {
// In case the default search popup is shown, hide it.
defaultPopup.hidePopup();
// Propagation causes PopupSearchAutoComplete to be shown, which in turn causes search-add-engines to be populated.
// We monitor the PopupSearchAutoComplete and after it is shown, we use createAddEngineItem() to create the add
// engine item and populate the script's popup (searchbuttonpopup). Propagation causes PopupSearchAutoComplete to be
// displayed with searchbuttonpopup, at the same time (when the user clicks the search button). Displaying
// PopupSearchAutoComplete with every search button click is inefficient. We allow propagation only when it is needed,
// and we set the PopupSearchAutoComplete visibility to collapse, so we do not see it with the script's popup.
// If there are no changes to be done to the searchbuttonpopup, go ahead and skip propagation.
// If there is an engine to be added, and the engine item is already available on the script's popup, there are no changes.
// If there is no engine to be added, and there is no engine item, that also means that there are no changes needed.
// On the other hand, if hasAddEnginesAttribute and addEngineItem are not synchronized, we need to apply propagation
// to refresh the searchbuttonpopup. We set the addEngineItem visibility to collapse, and allow propagation.
if ((hasAddEnginesAttribute && addEngineItem && addEngineItem.hasAttribute("image") && document.getElementById(addEngineItem.getAttribute("data-id")) && gBrowser.currentURI.spec.includes(addEngineItem.getAttribute("uri").match(/.+:\/\/([^\/]+)\//)[1])) || (!hasAddEnginesAttribute && !addEngineItem))
event.stopPropagation();
else {
defaultPopup.style.visibility = "collapse";
defaultPopup.addEventListener("popupshown", createAddEngineItem, false);
}
}
/*searchbar.focus();*/
}, true);
}; //createOldSelectionPopup
// doSearch function taken from Firefox 85+ internal 'searchbar.js' file and added modifications
searchbar.doSearch = function(aData, aWhere, aEngine, aParams, isOneOff = false) {
let textBox = this._textbox;
let engine = aEngine || this.currentEngine;
// Save the current value in the form history
if (
aData &&
!PrivateBrowsingUtils.isWindowPrivate(window) &&
this.FormHistory.enabled &&
aData.length <=
this.SearchSuggestionController.SEARCH_HISTORY_MAX_VALUE_LENGTH
) {
this.FormHistory.update(
{
op: "bump",
fieldname: textBox.getAttribute("autocompletesearchparam"),
value: aData,
source: engine.name,
},
{
handleError(aError) {
Cu.reportError(
"Saving search to form history failed: " + aError.message
);
},
}
);
}
let submission = engine.getSubmission(aData, null, "searchbar");
// If we hit here, we come either from a one-off, a plain search or a suggestion.
const details = {
isOneOff,
isSuggestion: !isOneOff && this.telemetrySelectedIndex != -1,
url: submission.uri,
};
this.telemetrySelectedIndex = -1;
BrowserSearchTelemetry.recordSearch(
gBrowser.selectedBrowser,
engine,
"searchbar",
details
);
// null parameter below specifies HTML response for search
let params = {
postData: submission.postData,
};
if (aParams) {
for (let key in aParams) {
params[key] = aParams[key];
}
}
openTrustedLinkIn(submission.uri.spec, aWhere, params);
if(clear_searchbar_after_search)
this.value = '';
if(revert_to_first_engine_after_search) {
searchbar.currentEngine = searchbar.engines[0];
updateStyleSheet();
}
};
// Workaround for the deprecated setIcon funtion
var oldUpdateDisplay = searchbar.updateDisplay;
searchbar.updateDisplay = function() {
oldUpdateDisplay.call(this);
updateStyleSheet();
};
// main style sheet
function updateStyleSheet() {
var sss = Components.classes["@mozilla.org/content/style-sheet-service;1"].getService(Components.interfaces.nsIStyleSheetService);
var hide_oneoff_search_engines_code = '';
var show_search_engine_names_code = '';
var show_search_engine_names_with_scrollbar_code = '';
var hide_addengines_plus_indicator_code = '';
var switch_glass_and_engine_icon_code = '';
if(hide_oneoff_search_engines)
hide_oneoff_search_engines_code=' \
#PopupSearchAutoComplete .search-panel-header, \
#PopupSearchAutoComplete .search-one-offs { \
display: none !important; \
} \
';
if(hide_addengines_plus_indicator)
hide_addengines_plus_indicator_code=' \
.searchbar-search-button[addengines=true]::after { \
visibility: hidden !important; \
} \
';
if(show_search_engine_names && !hide_oneoff_search_engines)
show_search_engine_names_code=' \
#PopupSearchAutoComplete .search-panel-one-offs .searchbar-engine-one-off-item { \
-moz-appearance:none !important; \
min-width: 0 !important; \
width: 100% !important; \
border: unset !important; \
height: 22px !important; \
background-image: unset !important; \
padding-inline-start: 3px !important; \
} \
#PopupSearchAutoComplete .search-panel-one-offs .searchbar-engine-one-off-item:not([tooltiptext]) { \
display: none !important; \
} \
#PopupSearchAutoComplete .search-panel-one-offs .searchbar-engine-one-off-item .button-box { \
display: block !important; \
padding-inline-start: 4px !important; \
margin-top: 3px !important; \
} \
#PopupSearchAutoComplete .search-panel-one-offs .searchbar-engine-one-off-item::after { \
-moz-appearance: none !important; \
display: inline !important; \
content: attr(tooltiptext) !important; \
position: relative !important; \
top: -9px !important; \
padding-inline-start: 25px !important; \
} \
#PopupSearchAutoComplete .search-panel-one-offs { \
min-height: unset !important; \
height: unset !important; \
max-height: unset !important; \
} \
#PopupSearchAutoComplete .search-setting-button { \
align-self: unset !important; \
margin-top: -22px !important; \
position: absolute !important; \
} \
';
if(show_search_engine_names_with_scrollbar && !hide_oneoff_search_engines && show_search_engine_names)
show_search_engine_names_with_scrollbar_code=' \
#PopupSearchAutoComplete .search-one-offs { \
height: '+show_search_engine_names_with_scrollbar_height+' !important; \
max-height: '+show_search_engine_names_with_scrollbar_height+' !important; \
overflow-y: scroll !important; \
overflow-x: hidden !important; \
} \
\
';
if(switch_glass_and_engine_icon)
switch_glass_and_engine_icon_code=' \
.search-go-button { \
list-style-image: url('+document.getElementById("searchbar").currentEngine.iconURI.spec+') !important; \
transform: scaleX(1) !important; \
} \
.searchbar-search-button .searchbar-search-icon { \
list-style-image: url("chrome://global/skin/icons/search-glass.svg") !important; \
-moz-context-properties: fill, fill-opacity !important; \
fill-opacity: 1.0 !important; \
fill: #3683ba !important; \
} \
.searchbar-search-button:hover .searchbar-search-icon { \
fill: #1d518c !important; \
} \
.searchbar-search-button:active .searchbar-search-icon { \
fill: #00095d !important; \
} \
\
';
var uri = Services.io.newURI("data:text/css;charset=utf-8," + encodeURIComponent(' \
\
#search-container{ min-width: 20px !important } \
#searchbuttonpopup {\
margin-inline-start: -1px; \
} \
.searchbar-search-button .searchbar-search-icon { \
list-style-image: url('+document.getElementById("searchbar").currentEngine.iconURI.spec+') !important; \
} \
.search-go-button { \
list-style-image: url("chrome://global/skin/icons/search-glass.svg") !important; \
-moz-context-properties: fill, fill-opacity !important; \
fill-opacity: 1.0 !important; \
fill: #3683ba !important; \
transform: scaleX(-1) !important; \
background: unset !important; \
margin-inline-end: 4px !important; \
} \
.search-go-button:hover { \
fill: #1d518c !important; \
} \
.search-go-button:active { \
fill: #00095d !important; \
} \
.search-go-button[hidden="true"] { \
display: block !important; \
} \
.searchbar-search-button[addengines=true] > .searchbar-search-icon-overlay, \
.searchbar-search-button:not([addengines=true]) > .searchbar-search-icon-overlay { \
list-style-image: url("chrome://global/skin/icons/arrow-down-12.svg") !important; \
-moz-context-properties: fill !important; \
margin-inline-start: -6px !important; \
margin-inline-end: 2px !important; \
width: 11px !important; \
height: 11px !important; \
} \
.searchbar-search-button[addengines=true] > .searchbar-search-icon-overlay { \
margin-top: 0px !important; \
} \
.searchbar-search-button[addengines=true]::after { \
content: " " !important; \
background: url("chrome://browser/skin/search-indicator-badge-add.svg") center no-repeat !important; \
display: block !important; \
visibility: visible !important; \
width: 11px !important; \
height: 11px !important; \
margin-inline-start: 18px !important; \
margin-top: -11px !important; \
position: absolute !important; \
} \
.searchbar-search-button[addengines=true] > .searchbar-search-icon-overlay { \
visibility: visible !important; \
} \
\
.custom-addengine-item > .menu-iconic-left::after { \
position: absolute !important; \
display: block; !important; \
content: "" !important; \
background: url("chrome://browser/skin/search-indicator-badge-add.svg") no-repeat center !important; \
box-shadow: none !important; \
margin-top: -12px !important; \
margin-inline-start: -4px !important; \
width: 11px; !important; \
height: 11px; !important; \
min-width: 11px; !important; \
min-height: 11px; !important; \
} \
'+hide_addengines_plus_indicator_code+' \
'+hide_oneoff_search_engines_code+' \
'+show_search_engine_names_code+' \
'+show_search_engine_names_with_scrollbar_code+' \
'+switch_glass_and_engine_icon_code+' \
\
'), null, null);
// remove old style sheet
if (sss.sheetRegistered(uri,sss.AGENT_SHEET)) {
sss.unregisterSheet(uri,sss.AGENT_SHEET);
}
sss.loadAndRegisterSheet(uri, sss.AGENT_SHEET);
};
} catch(e) {}
}
}
/* if search is not hidden on current window, wait for searchbar loading and then initialize 'alternative search' (with delay) */
if(!document.firstElementChild.hasAttribute("chromehidden") || !document.firstElementChild.getAttribute("chromehidden").includes("toolbar")) {
if (document.readyState === "complete") {
setTimeout(AltSearchbar.init, initialization_delay_value);
}
else {
window.addEventListener("load", AltSearchbar.init, false);
}
}
Alles anzeigen
// ==UserScript==
// @name zzzz-MultiRowTab_LiteforFx48.uc.js
// @namespace http://space.geocities.yahoo.co.jp/gl/alice0775
// @description Experimentelle CSS Version für Mehrzeilige Tableiste
// @include main
// @compatibility Firefox 95
// @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() {
var css =` @-moz-document url-prefix("chrome://browser/content/browser.xhtml") {
/* Symbolleiste Sortieren */
#titlebar { -moz-box-ordinal-group: 2; }
/* Anpassung der Symbolleiste */
:root[tabsintitlebar="true"][sizemode="maximized"] #navigator-toolbox { padding-top: 8px !important; }
#titlebar,#tabbrowser-tabs { -moz-appearance: none !important; }
/* Anpassung für Titelleistenschaltflächen */
#nav-bar:not([inFullscreen="true"]) .titlebar-button { width: 46px !important; }
#nav-bar[inFullscreen="true"] .titlebar-button { width: 36px !important; }
#toolbar-menubar:not([inactive]) ~ #nav-bar:not([inFullscreen="true"]) .titlebar-buttonbox-container { display: none !important; }
/* Mehrzeilige Tableiste */
box.scrollbox-clip[orient="horizontal"] { display: block; }
scrollbox[part][orient="horizontal"] {
display: flex;
flex-wrap: wrap;
max-height: calc(calc(8px + var(--tab-min-height)) * 5); /* Anzahl der Tabzeilen(Standard = 5 Zeilen) */
overflow-x: hidden;
overflow-y: auto; }
.tabbrowser-tab[fadein]:not([pinned]) { flex-grow: 1; }
.tabbrowser-tab { overflow: hidden; }
.tabbrowser-tab,#tabs-newtab-button { height: calc(8px + var(--tab-min-height)); }
.tabbrowser-tab > .tab-stack { width: 100%; }
#tabs-newtab-button { margin: 0 !important; }
/* Bei Überschreitung der angegebenen Zeilenanzahl, mit der Maus,
über die dann eingeblendetet Scrolleiste zur gewünschten Zeile wechseln */
scrollbox[part][orient="horizontal"] > scrollbar { -moz-window-dragging: no-drag; }
/* Ausblenden */
.tabbrowser-tab:not([fadein]) { display: none !important; }
/* --- Ziehbereich der Tab-Leiste --- */
/* Anpassung */
hbox.titlebar-spacer[type="pre-tabs"] { width: 0px !important; } /* Linker Ziehbereich: Standard 40px */
hbox.titlebar-spacer[type="post-tabs"] { width: 0px !important; } /* Rechter Ziehbereich: Standard 40px */
/* ↓ Wenn Sie die linke und rechte Seite des CSS-Codes auskommentieren und den CSS-Code aktivieren,
können Sie den Ziehbereich links einblenden, der beim Maximieren des Fensters ausgeblendet wird. */
/* :root:not([sizemode="normal"]) hbox.titlebar-spacer[type="pre-tabs"] { display: block !important; } */
/* ↓ Wenn Sie die Auskommentierung links und rechts von unten stehenden CSS-Code entfernen und den CSS-Code aktivieren,
können Sie den linken und rechten Ziehbereich einblenden, der im Vollbildmodus ausgeblendet wird. */
/* :root[inFullscreen] .titlebar-spacer { display: block !important; } */
} `;
var sss = Cc['@mozilla.org/content/style-sheet-service;1'].getService(Ci.nsIStyleSheetService);
var uri = makeURI('data:text/css;charset=UTF=8,' + encodeURIComponent(css));
sss.loadAndRegisterSheet(uri, sss.AGENT_SHEET);
if(location.href !== 'chrome://browser/content/browser.xhtml') return;
// Verschieben Sie die Menüleiste an den oberen Rand der Symbolleiste
document.getElementById("titlebar").parentNode.insertBefore(document.getElementById("toolbar-menubar"),document.getElementById("titlebar"));
// Titelleisten Schaltflächen in die Tableiste an den Rechten Rand verschieben
document.getElementById("nav-bar").appendChild(document.querySelector("#TabsToolbar .titlebar-buttonbox-container"));
// Scroll-Buttons und Spacer in der Tab-Leiste ausblenden shadowRoot
gBrowser.tabContainer.arrowScrollbox.shadowRoot.getElementById('scrollbutton-up').style.display = "none";
gBrowser.tabContainer.arrowScrollbox.shadowRoot.getElementById('scrollbutton-down').style.display = "none";
gBrowser.tabContainer.arrowScrollbox.shadowRoot.querySelector('[part="overflow-start-indicator"]').style.display = "none";
gBrowser.tabContainer.arrowScrollbox.shadowRoot.querySelector('[part="overflow-end-indicator"]').style.display = "none";
// drag & drop & DropIndicator
gBrowser.tabContainer.clearDropIndicator = function() {
let tabs = this.allTabs;
for (let i = 0, len = tabs.length; i < len; i++) {
tabs[i].removeAttribute("style");
}
}
gBrowser.tabContainer.addEventListener("dragleave", function(event) { this.clearDropIndicator(event); }, true);
gBrowser.tabContainer.on_dragover = function(event) {
this.clearDropIndicator();
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.getAttribute("overflow") == "true") {
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
);
}
}
let draggedTab = this._getDropIndex(event, false); // event.dataTransfer.mozGetDataAt(TAB_DROP_TYPE, 0);
if (
(effects == "move" || effects == "copy") &&
this == draggedTab.container
) {
ind.hidden = true;
if (!this._isGroupTabsAnimationOver()) {
// Wait for grouping tabs animation to finish
return;
}
this._finishGroupSelectedTabs(draggedTab);
if (effects == "move") {
this._animateTabMove(event);
return;
}
}
this._finishAnimateTabMove();
if (effects == "link") {
let tab = this._getDragTargetTab(event, 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;
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 = scrollRect.left - rect.left;
let maxMargin = 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, effects == "link");
let children = this.allTabs;
if (newIndex == children.length) {
// let tabRect = children[newIndex - 1].getBoundingClientRect();
children[newIndex - 1].style.setProperty("box-shadow","-1px 0 0 red inset,1px 0 0 red","important");
if (RTL_UI) {
newMargin = rect.right - tabRect.left;
} else {
newMargin = tabRect.right - rect.left;
}
} else {
// let tabRect = children[newIndex].getBoundingClientRect();
children[newIndex].style.setProperty("box-shadow","1px 0 0 red inset,-1px 0 0 red","important");
if (RTL_UI) {
newMargin = rect.right - tabRect.right;
} else {
newMargin = tabRect.left - rect.left;
}
}
}
ind.hidden = false;
newMargin += ind.clientWidth / 2;
if (RTL_UI) {
newMargin *= -1;
}
ind.style.transform = "translate(" + Math.round(newMargin) + "px)";
}
gBrowser.tabContainer.on_drop = function(event) {
this.clearDropIndicator();
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, false);
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 tabWidth = Math.round(draggedTab._dragData.tabWidth);
let translateOffset = oldTranslateX % tabWidth;
let newTranslateX = oldTranslateX - translateOffset;
if (oldTranslateX > 0 && translateOffset > tabWidth / 2) {
newTranslateX += tabWidth;
} else if (oldTranslateX < 0 && -translateOffset > tabWidth / 2) {
newTranslateX -= tabWidth;
}
let dropIndex = this._getDropIndex(event, false);
// "animDropIndex" in draggedTab._dragData &&
// draggedTab._dragData.animDropIndex;
let incrementDropIndex = true;
if (dropIndex && dropIndex > movingTabs[0]._tPos) {
dropIndex--;
incrementDropIndex = false;
}
if (oldTranslateX && oldTranslateX != newTranslateX && !gReduceMotion) {
for (let tab of movingTabs) {
tab.setAttribute("tabdrop-samewindow", "true");
tab.style.transform = "translateX(" + newTranslateX + "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) {
let newIndex = this._getDropIndex(event, false);
let newTabs = [];
for (let tab of movingTabs) {
let newTab = gBrowser.adoptTab(tab, newIndex++, tab == draggedTab);
newTabs.push(newTab);
}
// Restore tab selection
gBrowser.addRangeToMultiSelectedTabs(
newTabs[0],
newTabs[newTabs.length - 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, true);
let userContextId = this.selectedItem.getAttribute("usercontextid");
let replace = !!targetTab;
let newIndex = this._getDropIndex(event, true);
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._getDropIndex = function(event, isLink) {
var tabs = this.allTabs;
var tab = this._getDragTargetTab(event, isLink);
if (!RTL_UI) {
for (let i = tab ? tab._tPos : 0; i < tabs.length; i++) {
if (
event.screenY <
tabs[i].screenY + tabs[i].getBoundingClientRect().height
) {
if (
event.screenX <
tabs[i].screenX + tabs[i].getBoundingClientRect().width / 2
) {
return i;
}
if (
event.screenX >
tabs[i].screenX + tabs[i].getBoundingClientRect().width / 2 &&
event.screenX <
tabs[i].screenX + tabs[i].getBoundingClientRect().width
) {
return i + 1;
}
}
}
} else {
for (let i = tab ? tab._tPos : 0; i < tabs.length; i++) {
if (
event.screenY <
tabs[i].screenY + tabs[i].getBoundingClientRect().height
) {
if (
event.screenX <
tabs[i].screenX + tabs[i].getBoundingClientRect().width &&
event.screenX >
tabs[i].screenX + tabs[i].getBoundingClientRect().width / 2
) {
return i;
}
if (
event.screenX <
tabs[i].screenX + tabs[i].getBoundingClientRect().width / 2
) {
return i + 1;
}
}
}
}
return tabs.length;
}
}
Alles anzeigen
€: Keine Ahnung warum auf einmal eine einzige Zeile aus jedem Skript wurde, ich hatte es per Notpad kopiert und eingefügt.