für den Fall daß ein Zähler auf 0 steht - will ich unbedingt
Man könnte die "Nuller" auch einfach ausblenden...
für den Fall daß ein Zähler auf 0 steht - will ich unbedingt
Man könnte die "Nuller" auch einfach ausblenden...
ZB ist opacity: 0.5 deutlicher langsamer als etwa color: hsl(0, 0%, 50%, 0.5) !important; und fill: hsl(0, 0%, 50%, 0.5) !important;.
Dass der Unterschied für dich wahrnehmbar ist, finde ich ein wenig überraschend in Anbetracht dessen, um wie wenige Elemente es eigentlich geht. Aber grundsätzlich ist es nicht überaschend, dass opacity langsamer ist, weil sich das auf sämtliche Eigenschaften auswirkt und das andere eben nur auf color und fill. Außerdem verändert opacity nicht nur die Deckkraft für das Element selbst, sondern auch für sämtliche Kindelemente. Das ist also mit wesentlich mehr Arbeit für den Browser verbunden.
Man könnte die "Nuller" auch einfach ausblenden...
Mach ich doch auch in den Codebeispielen, für den ersten Ordner Zähler - aber wenn ein Ordner keine Lesezeichen drin hat, aber Ordner - dann will ich den Ziffern Zähler nur verblasst haben!
Etwas anal, ich weiss, aber einfach kann jeder.
Den aktuellen Code habe ich übrigens auch angepasst, um wahlweise einen oder beide 0 Zähler mit display: none ausblenden zu können, wie du es bei dir gemacht hast, ohne weitere Änderungen, also flexibler als vorher.
So zumindest der Plan, bin schon ganz verunsichert nach meinen ganzen Pannen.
Dass der Unterschied für dich wahrnehmbar ist, finde ich ein wenig überraschend in Anbetracht dessen, um wie wenige Elemente es eigentlich geht. Aber grundsätzlich ist es nicht überaschend, dass opacity langsamer ist, weil sich das auf sämtliche Eigenschaften auswirkt und das andere eben nur auf color und fill. Außerdem verändert opacity nicht nur die Deckkraft für das Element selbst, sondern auch für sämtliche Kindelemente. Das ist also mit wesentlich mehr Arbeit für den Browser verbunden.
Bin auch überrascht, aber es passiert deutlich merkbar nur bei vielen Einträgen mit opacity in einem einzelnen Popup.
In diesem Fall ist das mein - wenig realistischer - Test Setup im Testprofil, der teils Dutzende Lesezeichenordner mit keinen Ordnern und/oder keinen Lesezeichen drinnen hat; also eine Menge Pseudoelemente mit opacity < 1.
Deine Erklärung macht auch Sinn; ich kenne es aus mehreren (Render) Anwendungen, daß Transparenz teils massive Leistungseinbrüche mit sich bringen kann, wenn sie nicht sehr gezielt/lokalisiert eingesetzt wird.
Mh, was sind die Vor- bzw. Nachteile, wenn man das meiste davon direkt in JavaScript umsetzt?
Ich frag' nur aus Neugierde!
Mh, was sind die Vor- bzw. Nachteile, wenn man das meiste davon direkt in JavaScript umsetzt?
Was mich angeht, manche Sachen kann ich einfach nicht...
Was mich angeht, manche Sachen kann ich einfach nicht...
Ok, ich tu mir mit CSS ziemlich schwer, was so "Funktionen angeht.
Da bist Du der Fuchs.
Aber es ist, war eine generelle Frage!
Ein grosser Unterschied wäre noch die Möglichkeit, separate CSS Dateien live editieren und speichern zu können in den Browser Werkzeugen, und auch sofort ein Ergebnis zu sehen.
Damit kann man über mehrere verbundene CSS Dateien parallel arbeiten, idealerweise mit einer zentralen Kontroll CSS plus darin importierten CSS Dateien für grössere Varianten, und dabei alle Styling Elemente aufeinander abstimmen ohne Restarts etc..
Ausserdem fällt damit ein Menge zusätzlicher Code weg im JS, das ganze Dateipfad Gedöns und die Einbindung von CSS allgemein, was bei Fx Code Veränderungen das eventuelle Troubleshooting weiter kompliziert.
Horstmann Stimmt, das sind durchaus Punkte, die für ein ausgelagertes CSS sprechen.
Für CSS im Skript spricht "für" mich, es ist variabler.
Mann hat alles unter "Dach und Fach", und wenn man geschickt die Variablen setzt,
hat man so etwas wie ein Konfigurationsbereich, wie ich schon mit dem Hinweis auf das Scrollbar-Skript beschreiben wollte.
Auch hat man mit JavaScript Möglichkeiten, die einem nur in CSS so nicht so einfach, oder auch gar nicht, zur Verfügung stehen.
Für einen Benutzer ist ein JavaScript, so denke ich, in der Anwendung einfacher, er muss nicht mehrere Dateien in verschiedene
Verzeichnisse ablegen.
Die Konfiguration des Skriptes, wenn geschickt gemacht, sollte auch für einen Laien einfach sein, weil er ja dann,
nichts am eigentlichen Code verändern muss und brauch.
Nachteil, es werden Monster, wenn man alles Mögliche abdecken will.
Kann man ja hier in diesem Thread mit "meinem" Skript nachvollziehen.
Hatte das ursprüngliche Skript ca. 150 Zeilen,
hat die letzte funktionierende Version schon ca. 200 Zeilen.
Ich finde Javascript einfach spannend und in Kombination mit CSS steht einem der Firefox offen.
Ob nun Funktionen und Layout getrennt oder, wie ich es lieber mag, Funktionen und Layout kombiniert in einer Datei,
ist wohl eine Frage der persönlichen Vorlieben. Denke ich.
Was sagt DIhr dazu Sören Hentzschel und BrokenHeart ?
Interessiert mich, bitte einen kleinen Kommentar.
Was sagt DIhr dazu Sören Hentzschel und BrokenHeart ?
Interessiert mich, bitte einen kleinen Kommentar.
Es kommt immer darauf an, was man möchte.
Ich bin grundsätzlich dagegen, Dinge zu vermischen, die nicht zusammen gehören. Weder CSS noch JavaScript gehört in HTML-Dateien und CSS gehört auch nicht in JavaScript-Dateien. Denn das verhindert eine effektive CSP, es erschwert Linting und man bekommt noch nicht einmal Syntax-Highlighting für die „fremde“ Sprache. Für die Wartbarkeit und damit letztlich auch Code-Qualität ist das schlecht.
Wenn einem das egal und dafür wichtiger ist, möglichst alles mit einer einzelnen Datei teilen zu können, sind das halt andere Voraussetzungen.
Aber als kleiner Inspirations-Ansatz, weil eine Konfiguration angesprochen worden ist: Das eine sind CSS-Variablen. Damit kann man schon viel anpassbar machen. Und wenn man größere Abhängigkeiten benötigt, könnte man im Script eigene Optionen in about:config setzen. Diese kann man dann im CSS wiederum auslesen. Auf diese Weise kann man if/else-Kontrukte auch im CSS simulieren.
Es kommt immer darauf an, was man möchte.
So schaut's aus.
Dein Einwand kann ich durchaus verstehen, wenn man große Projekt pflegt,
wie den Onlineauftritt eines Unternehmens würde es auf jeden Fall sehr schnell unübersichtlich und kompliziert werden.
Wir reden hier aber nur von kleinen Anpassungen des Firefox.
Und man muss auch bedenken, dass weniger visierte Anwender solche Anpassungen vornehmen möchten.
Einige sind ja schon fast überfordert, die richtigen Vorbereitungen zu treffen, damit der Firefox überhaupt anpassbar wird.
Nun bin ich gespannt, was BrokenHeart zu dem Thema meint.
Eventuell trenne ich in Zukunft ja doch CSS und JavaScript, aber ich weiß es noch nicht.
Nun bin ich gespannt, was BrokenHeart zu dem Thema meint.
Habe eigentlich keine dezidierte Meinung dazu, sehe das so ähnlich wie du. Bei der hier üblichen Größe spielt es wohl keine große Rolle, ob man sein CSS auslagert oder direkt im Skript verwurstet. Aber übertreiben sollte man es wirklich nicht mit dem eingebundenen CSS - so wie ich es bei den MultiRowTabs gemacht hatte .
Bei größeren (professionellen) Projekten hat Sören sicher mit seinen Hinweisen recht.
Mich interessiert die Thematik aber nicht sonderlich, da ich die Beschäftigung mit den "Formalismen" von JavaScript/CSS nicht so wichtig finde. Für mich steht das Verstehen des Firefox-Quellcodes im Vordergrund: z.B. die Aufrufe über die idl-Schnittstelle und die Funktionalität aus den importierten Modulen. Was nützt es mir mit sauberem Code "in Schönheit zu sterben", wenn ich nichts über die Firefox-spezifischen Möglichkeiten von CSS/Javascript weiß und das auch anwenden kann?
OT: Viel wichtiger finde ich, dass endlich mal jemand (zumindest für Windows) ein (PowerShell-)Skript schreibt, welches das Herunterladen und Entpacken der zum Ausführen von User-Skripten notwendigen Dateien übernimmt. Ich kenne mich leider nicht mit dem Scripting aus und eine ausführbare Anwendung in C++ zu schreiben halte ich für übertrieben. Außerdem hat man nachher eine .exe Datei, die auch noch mit Administrator-Rechten ausgeführt werden muss. Auch wenn man Quellen und make-File mitliefert, kann ich jeden verstehen, der so was nicht nutzen möchte. Ein Skript wäre da schon geschmeidiger.
Ich bin mir sicher, wenn so ein Skript existiert, würden auch mehr Menschen die User-Skripte nutzen.
Mira_Belle Du beherrscht das doch, wenn ich mich nicht täusche. Na, wie wär's ...
Du beherrscht das doch, wenn ich mich nicht täusche. Na, wie wär's ...
Würde ich ja gerne, aber so wirklich fit bin ich da auch nicht!
UND wäre auf jeden Fall auf Hilfe angewiesen.
Und dann wäre ja noch das Problem mit dem Testen!!
In einer VM sollte das kein Problem sein, aber bisher habe ich auf meinem System
es einfach noch nicht hinbekommen, so ein Ding zu starten. Ums verrecken nicht!
Da steh' ich mir wohl selbst im Weg, warum auch immer.
Nachtrag!
Ich überrasche mich immer mal wieder selber!
ABER ich scheitere am Profilpfad.
Runterladen, ok. Entpacken, ok.
Kopieren der "config.js" ins Programmverzeichnis, auch ok,
Anlegen des Ordners "userChromeJS", auch kein Ding.
Kopieren der Dateien, die da rein sollen, abgehakt.
Und dann kommt das Profilverzeichnis
Ende. Da verließen sie sie! Ich bin in einer Schaffenskrise.
"$env:APPDATA "Mozilla\Firefox\Profiles" bis hier her komme ich, und dann "xxx..default"!?
Ich muss ja in diesen Ordner um darin den "chrome"-Ordner erstellen zu können.
Jemand eine Idee?
Ein grosser Unterschied wäre noch die Möglichkeit, separate CSS Dateien live editieren und speichern zu können in den Browser Werkzeugen, und auch sofort ein Ergebnis zu sehen.
Geht wohl fast hiermit:
// cssLive.uc.js
(function() {
if (location.href !== 'chrome://browser/content/browser.xhtml') return;
//if (location !=AppConstants.BROWSER_CHROME_URL) {
// return;
/*** OPTIONEN START *******************************************************/
var cssLiveOptions = {
/* Falls sich die Testdatei in einem Unterverzeichnis von "chrome"
befindet, bitte hier zwischen Anführungszeichen eintragen, ansonsten
nur die Anführungszeichen */
subdir: 'css',
/* Name der Testdatei */
file: 'Test.css'
};
/*** OPTIONEN ENDE ********************************************************/
var buttonPath = '';
var testFile = Services.dirsvc.get('UChrm', Ci.nsIFile);
if( cssLiveOptions.subdir != '' ) {
testFile.append( cssLiveOptions.subdir );
buttonPath += cssLiveOptions.subdir + "/";
}
testFile.append( cssLiveOptions.file );
buttonPath += cssLiveOptions.file;
var buttonTxt_1 = buttonPath + " aufrufen";
var buttonTxt_2 = buttonPath + " ausführen";
var errorTxt = "Die Datei \n" + testFile.path + "\n existiert nicht.";
ChromeUtils.importESModule("resource:///modules/CustomizableUI.sys.mjs");
try {
CustomizableUI.createWidget({
id: "fp-get-css-file",
defaultArea: CustomizableUI.AREA_NAVBAR,
removable: true,
label: buttonTxt_1,
tooltiptext: buttonTxt_1,
onClick: function() {
if( testFile.exists() ) {
testFile.launch();
} else {
alert( errorTxt );
}
},
onCreated: function(aNode) {
aNode.style.listStyleImage = 'url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADJklEQVR4Xi3Pb0yVdRjG8e/ze57ncDrAOWwRhDQ7xYAMlAgIBW2txaio5TvMzZa68oWtzRdKbXbIpWyOzcWLWqXkFjUtsIksW72wuTVx+EJHCxhkSCNoKLYDwuH8e66eNV98dr24t/u+LwsAoKsucqg4tFS4kiTtge4PFAkRksADGdsyua4JXJ7ITH0yQw+ABTB3sHGipGNjJX8MgzGw6oEBQi5kPYinQBYEbDDAX5PEulJXPhqn2bQE2Fayfa2S8THOfu/wzTkDzmOQV8nAkOHMoIFgmS9K3w/i5DmP1fwqdrbRFIR6euqJ6btc2Y4jsGWM0emOWrU2FAtQRTSiid7n9EJtkQCVlebrUle9lnuLVA3v09/G8diLCFxp+DVprF2a2KHqsrACtqVbQy9L8T2qq4goaKOpz5uka22Kn1yn2gBHOPMSx9o3obJokbS8R/p3txTfK918Q+2tjwrQYPcWaW6Xdj5fKkB9B2uks+v1VICYSWXQjia4eWuB8z2/0//pGMMD04yP3qFzfzXBoE3sszGmR27Tubuc3KDDsf4ZsME2iO4GjuqXQh1orxDwv1OxBsX2VQlQcWGObnzdog/3bhCg0uIHNPLFVqnf/8DlA2ctDSTgxNFnOHFgE7jAg7kQcjnS8TRgQcCiprGQzncrIZ0i/u0so7lLODlgsh6QSMNCAix8BhJJNH6b5NwyFNhwLwWuB/NxEoemudi9wMT8Cq4LBrDwgLUULK/BPR9+jC4ytPUC17/8DR6CpYEplt+eJTX7OH9HbEL5NvKwjGvj4AHprC8DSZ+/zHJgI+uI+xdvbL9E+JRLJr+Sr5LXKd8foqY8QjqN7fxzlzhaAy8LGYHnQTxJ3hNhFlptCi4XsP7PEoaD4mr4KlveeZjNG4qYvDbKyipJolCXOI70U630Y6uvRfrZzyuvSKOvavK9Kp2OFqv3zagWLzb7s21aubBZ519HFjzrg8NP8utbu2hWMIyyHpYBYwyOa2Hn2cwuJAiHAthp+e087s4n6e5LjwzeodECAKiAffk5PJLOkJKFACzLZ8B27jfMYgUM7mKSuzPwMcB/6Jh/V5xUni0AAAAASUVORK5CYII=)';
return aNode;
}
});
} catch (e) {
Components.utils.reportError(e);
};
try {
CustomizableUI.createWidget({
id: "fp-register-css-file",
defaultArea: CustomizableUI.AREA_NAVBAR,
removable: true,
label: buttonTxt_2,
tooltiptext: buttonTxt_2,
onClick: function() {
if( testFile.exists() ) {
var CI = Components.interfaces;
var CC = Components.classes;
let sss = CC["@mozilla.org/content/style-sheet-service;1"].getService( CI.nsIStyleSheetService );
let ios = CC["@mozilla.org/network/io-service;1"].getService( CI.nsIIOService );
let fileURL = Services.io.getProtocolHandler( 'file' ).QueryInterface( Ci.nsIFileProtocolHandler ).getURLSpecFromFile( testFile );
let uri = ios.newURI( fileURL , null , null );
sss.loadAndRegisterSheet( uri , sss.AGENT_SHEET );
} else {
alert( errorTxt );
}
},
onCreated: function(aNode) {
aNode.style.listStyleImage = 'url(data:image/gif;base64,R0lGODlhEAAQAPcAAAQCVISChMTCtOTizNTSxERCRAQCZJSW1MzGzNTW1Ozq7CwqdKyqlMzKxERCjMTCxNzavLy6vMzKzPz67HRypCQiJJyahAQCdOTe1CQinLy65Pz2/PT23NTSzNzW3Ly6tExGnMTGxMS+xMzK1JSWpAQCXMTGvOzmzAQCbMTC1Nza1DQ2dKyqnNTOxExOfOTezLy+vMzOzPz+7Hx+rDQyNKSehAQCfCwqlPz+/NzWzMzGxAD/AOQA2C8A6iQAEgAAAACAAAAAAAAAAAAAAAACAAAAAAAAAAAAAADMAkPpACYSAAAAAKAVCC+LACQ/AAB3AADQhADq7QASEgAAAACwTkPqACYSAAAAAOgACAcAACgACgAAAACwnADqjAASPwAAd/8CBP8AAP8AAAAAAABwAADqAAASAAAAADB6QwSBAAA/OgB3AIQSXAGSAAE/UAF3ABDUcugdABITbwB3AHQAZ40AADQAcnYAAMwIYfsCABIAbQAAAPo4X5m1jDknN3cAdlQASLoA7z8AnAAB1f4sAP/pAP8SAP8AABIAB3UAAD8AAHcAAEWEAHXtAD8SAHcAAABOAAAAEABQKAAAAACwAENDACYmAAAAAAD+AEP/ACb/AAD/AHA4AGbqAD8SAHcAADQAAAAAAAAAAMAAAAQANOoBiBIAuQAAo29l/ogm/zQ0/3Z2/wA4XwDqjCQSNwAAdgBPJQAgAAA0AAB2APhcJULqACYSAAAAAAAAoAABuwAAUAAAAGVl/yYm/zQ0/3Z2/wAAAAEAAAAAAAAAAKAYZB0A6xMAEncAAADnRgAlgyQ0TAB2AAAARAAA6wAAEgAAAKRgdwPrUCQSTwAAAEgieAEm6yQ0EgB2AA/U5wBsJQBPNAAAdh7gHQB37QBPEgAAAHQA2QEB/yQA/wAAfy1c+ADq7AASEgAAAEgAAAEBACQAAAAAAABD5wAmJQA0NAB2dg4BAAAAAAAAAAAAAAAAPAAA7wAAnAAB1Ui4GAHtFCQSKAAAAFP6AQCZLQA5SAB3ACH5BAAAAAAALAAAAAAQABAABwi3AAsEGEiwYEEaARQk8MCQ4UIPCxNsEJhABIwIGE08wAhDxAMFFB/gGCkjhkgcEwh8DEkBQIkSAkzMcPlhZYAEDwjguLCCgw4cIGrgBBnAwwMRAzKggNBCgwsVIWxWzDkCBQkcNxhIeCCV6wMZBlDgKIEhqgiiUx+8OIBiAYsOXoka5dogBQoHJhDEpejxQYgTNizk8NrVK4EcH6JyPRuyb9/FXIluUEC5smXKOArQKMC5s2fPFQICADs=)';
return aNode;
}
});
} catch (e) {
Components.utils.reportError(e);
}
})();
Alles anzeigen
Geht wohl fast hiermit:
Danke für den Tip.
Mit Spannung erwartet, hier meine aktuelle Version, damit ich das Ding endlich aufhöre weiter zu bearbeiten.
Hoffe es macht Sinn; Kommentare und Aufbau für Bedienbarkeit zu gestalten ist immer eine Herausforderung.
Es ist noch Einiges an Variablen enthalten; wer diese oder einige Varianten nicht braucht, kann wo nötig feste Werte eintragen bzw. Letztere löschen.
Wir hätten hier Icons von Firefox, ersetzbar mit eigenen Icons (zB die im Anhang), eine entfernbare Trennlinie, und eine Option die Reihenfolge von Icon und Zahlenwert umzukehren, plus einige mögliche kosmetische Anpassungen.
Das ganze sollte sich ohne viel Drama automatisch für die diversen Varianten anpassen lassen über die Basiseinstellungen.
Test und Kritik wie immer herzlich willkommen.
//bmcount.uc.js, RC_2
//Zeigt Anzahl der Lesezeichenordner und Links an in Lesezeichenpopups
//basiert auf Script von BrokenHeart =>
//https://www.camp-firefox.de/forum/thema/136572-nur-die-anzeige-der-ordner-lesezeichenanzahl-in-einer-anderen-farbe-darstellen/?postID=1269879#post1269879
//Release Candidate 2 =>
//https://www.camp-firefox.de/forum/thema/136572-nur-die-anzeige-der-ordner-lesezeichenanzahl-in-einer-anderen-farbe-darstellen/?postID=1272262#post1272262
// Eigenes Icon erwartet in Profilordner/chrome/icons , icons Ordner falls noetig erstellen
// Eigenes Icon, Name unten in ==> let icon1/2 = yourIcon...
//Basis Anpassungen =>
//Zaehler (Counter) Design Optionen mit / ohne Klammern waehlen ganz unten => #A, #B, #D (aus/ein), #C Feinabstimmung
(function() {
if (!window.gBrowser)
return;
setTimeout(function() {
setFunction();
},50);
//Custom icons ==> in profilename/chrome/icons folder
let ProfilePath = PathUtils.toFileURI(PathUtils.join(PathUtils.profileDir, 'chrome', 'icons'));
let icon1 = "YourFolderIcon.svg" // Custom Folder Icon
let icon2 = "YourLinkIcon.svg" // Custom Link Icon
function setFunction() {
const css =`
/*** Basiseinstellungen ***/
#bmContent {
/** Gesamt **/
display: flex !important;
margin-inline: auto -8px !important; /* Gesamt rechtsbuendig, Abstand rechts zu Pfeil > */
height: var(--bm_icon_size); /* Layout passt sich Icon Groesse an */
padding-left: 8px; /* min. Abstand links Gesamt für enge Popups */
/*font-size: 12px !important;*/
/** Icons Varianten / ungewuenschte Varianten auskommentieren!!! **/
/* Use Firefox Icons => */
--bm_icon_image_1: url("chrome://global/skin/icons/folder.svg");
--bm_icon_image_2: url("chrome://browser/skin/bookmark-hollow.svg");
/* Eigene Icons, falls Icons existieren im icons Ordner => */
/* --bm_icon_image_1: url("${ProfilePath}/${icon1}");
--bm_icon_image_2: url("${ProfilePath}/${icon2}");
*/
/** #A: Feste Breite der beiden Counter, abhaengig von Anzahl Ziffern
=> Wert erhoehen NUR bis Icons untereinander auf gleicher Hoehe sind,
ungewuenschte Variante auskommentieren!!! **/
/* 2 Ziffern plus Klammern, Systemfont Mac, Zähler Design Optionen => ganz unten */
/* --bm_width_one: 2.1em;
--bm_width_two: 2.1em;
*/
/* 2 Ziffern ohne Klammern, Systemfont Mac, Zähler Design Optionen => ganz unten */
--bm_width_one: 1.3em;
--bm_width_two: 1.3em;
/** #B: Reihenfolge Varianten Icons / Ziffern / ungewuenschte Variante auskommentieren!!! **/
/* #1 Icons links / Ziffern rechts */
--bm_padding_inline: calc(var(--bm_icon_size) + var(--bm_space)) 0;
--bm_bg_position: center left;
/* #2 Ziffern links / Icons rechts / --bm_divider_2 gerade Zahl = Abstand mittig zusaetzlich fuer Trennlinie */
/* --bm_padding_inline: 0 calc(var(--bm_icon_size) + var(--bm_space));
--bm_bg_position: center right;
--bm_divider_2: -1px;
*/
/** #C: Abstaende / Groessen Counter Basis **/
/* Abstand mittig zwischen Counter #1 <=> Counter #2, gerade Zahl falls Trennlinie benutzt */
--bm_margin_mid: 16px;
/* Groesse Icons = 16px Firefox Standard */
--bm_icon_size: 16px;
/* Abstand zwischen Icon und Ziffer */
--bm_space: 3px;
}
/** #D: Trennlinie optional, auskommentieren falls unerwuenscht => evtl. #C neu anpassen **/
/* image / slice = max icon width? / height adjust 0px = 100%, width / outset = Abstand links */
#bmContent::after {
border-image: linear-gradient(currentColor, currentColor)
0 0 0 1 /
2px var(--bm_divider) /
0 0 0 calc(var(--bm_margin_mid)/2 + var(--bm_divider) + 2*var(--bm_divider_2, 0px));
--bm_divider: 1px;
}
/*** Basiseinstellungen Ende ***/
/** Counters **/
/* Counter #1 Ordner */
#bmContent::before {
content: attr(data-value1);
display: flex;
min-width: fit-content;
width: var(--bm_width_one);
padding-inline: var(--bm_padding_inline);
align-items: center;
justify-content: end;
margin-right: var(--bm_divider_2, 0px);
background-image: var(--bm_icon_image_1);
background-position: var(--bm_bg_position);
background-repeat: no-repeat;
background-size: var(--bm_icon_size);
/* Farben Text / svg Icons aendern => */
/*color: hsl(155, 90%, 50%, 1) !important;*/
/*fill: hsl(255, 70%, 50%, 1) !important;*/
}
/* Counter #2 Links */
#bmContent::after {
content: attr(data-value2);
display: flex;
min-width: fit-content;
width: var(--bm_width_two);
padding-inline: var(--bm_padding_inline);
align-items: center;
justify-content: end;
margin-left: calc(var(--bm_margin_mid) + var(--bm_divider, 0px));
background-image: var(--bm_icon_image_2);
background-position: var(--bm_bg_position);
background-repeat: no-repeat;
background-size: var(--bm_icon_size);
/* Farben Text / svg Icons aendern => */
/*color: hsl(155, 90%, 50%, 1) !important;*/
/*fill: hsl(255, 70%, 50%, 1) !important;*/
}
/** Optionale Extras **/
/* Anpassungen bei Zahl = 0 */
/* Verstecken / Verblassen #1 */
#bmContent:is(
[data-value1="[0]"],
[data-value1="0"],
[data-value1="(0)"])::before {
/*opacity: 0.2;*/
display: none;
}
/* Verstecken / Verblassen #2 */
#bmContent:is(
[data-value2="[0]"],
[data-value2="0"],
[data-value2="(0)"])::after {
opacity: 0.5;
}
/* Verstecken Trennlinie bei #1 = 0 und versteckt */
#bmContent:is(
[data-value1="[0]"],
[data-value1="0"],
[data-value1="(0)"])::after {
border-image: none;
}
/** Helfer zum Testen der Abstände **/
/*
#bmContent {
outline: 1px solid blue;
outline-offset: 4px;
}
#bmContent::before, #bmContent::after {
outline: 1px solid orange;
}
*/
/*
#bmContent::after {
background-image: var(--bm_icon_image_1),linear-gradient(lightgreen, lightgreen) !important;
background-color: pink;
}
#bmContent::before {
background-image: var(--bm_icon_image_2),linear-gradient(lightblue, lightblue) !important;
background-color: khaki;
}
*/
`;
const sss = Cc['@mozilla.org/content/style-sheet-service;1'].getService(Ci.nsIStyleSheetService);
const uri = Services.io.newURI('data:text/css,' + encodeURIComponent(css));
sss.loadAndRegisterSheet(uri, sss.AGENT_SHEET);
let bmbMenu = document.getElementById('bookmarks-menu-button');
let bookMenu = document.getElementById('bookmarksMenu');
let persToolBar = document.getElementById('PersonalToolbar');
if(bmbMenu)
bmbMenu.addEventListener('popupshowing', onPopupShowing );
if(bookMenu)-
bookMenu.addEventListener('popupshowing', onPopupShowing );
if(persToolBar)
persToolBar.addEventListener('popupshowing', onPopupShowing );
}
function onPopupShowing(aEvent) {
let popup = aEvent.originalTarget;
for (let item of popup.children) {
if (item.localName != 'menu' || item.id?.startsWith('history'))
continue;
setTimeout(() => {
let itemPopup = item.menupopup;
itemPopup.hidden = true;
itemPopup.collapsed = true;
itemPopup.openPopup();
itemPopup.hidePopup();
let menuitemCount = 0;
let menuCount = 0;
for (let subitem of itemPopup.children) {
if (subitem.classList.contains('bookmark-item') && !subitem.disabled && !subitem.hidden) {
if (subitem.localName == 'menuitem') {
menuitemCount++;
} else if (subitem.localName == 'menu') {
menuCount++;
}
}
}
itemPopup.hidden = false;
itemPopup.collapsed = false;
// Eigenes Element für Zaehler
let bmCounta = item.childNodes[1];
bmCounta.innerHTML = "";
let bmVario = document.createElement("bmElement");
bmVario.id = "bmContent";
bmCounta.appendChild(bmVario);
//Zaehler Design Optionen => mit, ohne, eckige, runde Klammern
let strCountOut1 = "" + menuCount + ""; // ohne Klammern
//let strCountOut1 = "(" + menuCount + ")"; // runde Klammern
//let strCountOut1 = "[" + menuCount + "]"; // eckige Klammern
bmVario.setAttribute('data-value1', strCountOut1);
let strCountOut2 = "" + menuitemCount + ""; // ohne Klammern
//let strCountOut2 = "(" + menuitemCount + ")"; // runde Klammern
//let strCountOut2 = "[" + menuitemCount + "]"; // eckige Klammern
bmVario.setAttribute('data-value2', strCountOut2);
// Extra class und Attribut parent; experimentell
//if (bmContent.parentElement) {
//bmContent.parentElement.classList.add('pfeil');
//bmContent.parentElement.setAttribute('data-value3', strCountOut1 + strCountOut2);
//}
}, 100);
}
}
})();
Alles anzeigen
Nur, wenn Du möchtest!!
Du könntest oben Variablen definieren, die die Einstellung für das Klammergedöhns vereinfachen,
und niemand müsste im Code groß was verändern.
Einfach eine "0" für ohne, eine "1" für runde oder eine "2" für eckige Klammern.
Und das mit der Trennlinie ließe sich auch so lösen.
"0" keine, "1" eine Trennlinie, ginge auch mit true & false.
Aber ist nur so eine Idee und muss ja auch nicht sein.
Finde Dein Skript gut.
Du könntest oben Variablen definieren, die die Einstellung für das Klammergedöhns vereinfachen,
und niemand müsste im Code groß was verändern.
Einfach eine "0" für ohne, eine "1" für runde oder eine "2" für eckige Klammern.
Danke Mira.
Das mit den Klammern als JS Option würde evtl. Sinn machen, da müsste ich mich aber nochmal einlesen wie das geht (viele deiner früheren Postings zu JS Variablen kenne ich auch).
Ich wollte nur ein Mittelding finden zw. Variablen und manuell, so daß das CSS möglichst übersichtlich bleibt, und Styles weitmöglichst im CSS Block sitzen, für User die sich darüber ihr eigenes Ding basteln wollen.
Vorschlag.
// Variable zur Auswahl der Klammern
let out = 0; // 0 für "ohne Klammern", 1 für "runde Klammern", 2 für "eckige Klammern"
und ganz unten dann:
//Zaehler Design Optionen => mit, ohne, eckige, runde Klammern
let strCountOut1, strCountOut2;
if (out === 0) {
strCountOut1 = "" + menuCount + "";
strCountOut2 = "" + menuitemCount + "";
} else if (out === 1) {
strCountOut1 = "(" + menuCount + ")";
strCountOut2 = "(" + menuitemCount + ")";
} else if (out === 2) {
strCountOut1 = "[" + menuCount + "]";
strCountOut2 = "[" + menuitemCount + "]";
}
bmVario.setAttribute('data-value1', strCountOut1);
bmVario.setAttribute('data-value2', strCountOut2);
Alles anzeigen
Vorschlag.
Coool! Dankeschön.
PS: Ab Fx 139 sollte das alte Script nicht mehr funktionieren, und evtl. kommen dann Anfragen und weitere Kommentare; bis dahin lasse ich meine letzte Version wie sie ist - danach kommt dein Code mit rein.
PS: Ab Fx 139 sollte das alte Script nicht mehr funktionieren, und evtl. kommen dann Anfragen und weitere Kommentare; ...
Nach Belieben veränder, zerpflücken und anpassen, funktioniert in der Nightly.
// BookmarkCount.uc.js
/* ******************************************************************************************************************* */
/* Author BrokenHeart => https://www.camp-firefox.de/forum/thema/136572/?postID=1229536#post1229536 **** */
/* Correction from BrokenHeart => https://www.camp-firefox.de/forum/thema/136572/?postID=1229696#post1229696 **** */
/* Extension from Sören Henschel => https://www.camp-firefox.de/forum/thema/136572/?postID=1229555#post1229555 **** */
/* Customized by Mira inspired by grisu2099 ********************************************************************** */
/* Source => https://www.camp-firefox.de/forum/thema/136572/?postID=1229875#post1229883 **** */
/* Customized by Mira inspired by Horstmann ********************************************************************** */
/* Source => https://www.camp-firefox.de/forum/thema/136572/?postID=1229993#post1229993 **** */
/* Adjustments for 139 and customized by Mira inspired by Horstmann ********************************************** */
/* Source => https://www.camp-firefox.de/forum/thema/136572/?postID=1270254#post1270254 **** */
/* ******************************************************************************************************************* */
/* Version 1.01 => https://www.camp-firefox.de/forum/thema/136572/?postID=1230128#post1230128 **** */
/* Version 1.02 => https://www.camp-firefox.de/forum/thema/136572/?postID=1230334#post1230334 **** */
/* Version 1.03a => https://www.camp-firefox.de/forum/thema/136572/?postID=1270258#post1270258 **** */
/* ******************************************************************************************************************* */
/* Custom Counter in the Bookmarks for folders and links ************************************************************* */
/* ******************************************************************************************************************* */
(function() {
if (!window.gBrowser)
return;
setTimeout(function() {
setFunction();
},50);
//Custom icons in profile/chrome/icons folder
let ProfilePath = PathUtils.toFileURI(PathUtils.join(PathUtils.profileDir, 'chrome', 'icons'));
let icon1 = "folder-fat.svg"; // Custom Folder Icon
let icon2 = "bookmark-hollow.svg"; // Custom Link Icon
let icon3 = "arrow-right.svg"; // Custom Arrow Icon
// Custom settings
let bm_font_size = 12;
let cs_font_weight = 700;
let bm_icon_size = 16;
// NEU: Schriftfarbe getrennt definieren
//let cs_font_color_1 = "#FFA500"; // Farbe für Folder-Zähler (links)
//let cs_font_color_2 = "#00FFFF"; // Farbe für Link-Zähler (rechts)
let cs_font_color_1 = "#FFD700"; // Farbe für Folder-Zähler (links)
let cs_font_color_2 = "#FFD700"; // Farbe für Link-Zähler (rechts)
// NEU: Symbolfarber getrennt definieren
//let cs_icon_color_1 = "#5fe575"; // Farbe für "Ordner", 1.Symbol
//let cs_icon_color_2 = "#fbf328"; // Farbe für "Link", 2.Symbol
//let cs_icon_color_3 = "#bbf700"; // Farbe für den Pfeil
let cs_icon_color_1 = "#C0C0C0"; // Farbe für "Ordner", 1.Symbol
let cs_icon_color_2 = "#C0C0C0"; // Farbe für "Link", 2.Symbol
let cs_icon_color_3 = "#C0C0C0"; // Farbe für den Pfeil
// Calculated settings
let cs_font_size = `${bm_font_size}px`;
let cs_icon_size = `${bm_icon_size}px`;
let cs_width_one = `calc(${bm_icon_size}px + 1.4em)`;
let cs_width_uno = `calc(${bm_icon_size}px)`;
let cs_width_two = `calc(${bm_icon_size}px + 1.4em)`;
let cs_width_due = `calc(${bm_icon_size}px)`;
//let useStyle1 = true; // <- HIER Weiche setzen: true = Variante 1, false = Variante 2
let useStyle = 1; // <- HIER Weiche setzen: 0 = Symbole hinter den Zählern, 1 = Symbole vor den Zählern
// Symbole vor den Zählern
let css_one = `
/* Counter #1 Folder */
#bmContent::before {
content: attr(data-value1) !important;
width: ${cs_width_one} !important;
align-items: center !important;
display: flex !important;
justify-content: end !important;
/*margin-inline: 16px 4px; */ /* min. Abstand links für enge Popups, rechts zum 2ten Counter */
margin-left: 16px !important; /* Abstand links minimum für schmale Popus CHANGE */
margin-right: -1px !important; /* Abstand Icon "Ordner" bis zum "Zähler" */
background-image: url("${ProfilePath}/${icon1}")!important;
background-position: center right calc(${cs_width_one} - ${cs_icon_size}) !important;
background-repeat: no-repeat !important;
background-size: ${cs_icon_size} ${cs_icon_size} !important;
color: ${cs_font_color_1} !important; /* Farbe der 1. Zahl */
fill: ${cs_icon_color_1} !important; /* Farbe des 1. Symbols */
}
/* Counter #2 Links */
#bmContent::after {
content: attr(data-value2) !important;
width: ${cs_width_two} !important;
align-items: center !important;
display: flex !important;
justify-content: end !important;
/*margin-inline: -2px;*/
margin-left: 4px !important; /* Abstand "Zähler 1" zum Icon2 */
margin-right: -1px !important; /* Abstand Icon "Links" bis zum "Zähler" */
background-image: url("${ProfilePath}/${icon2}") !important;
background-position: center right calc(${cs_width_two} - ${cs_icon_size}) !important;
background-repeat: no-repeat !important;
background-size: ${cs_icon_size} ${cs_icon_size} !important;
color: ${cs_font_color_2} !important; /* Farbe der 2. Zahl */
fill: ${cs_icon_color_2} !important; /* Farbe des 2. Symbols */
}
`;
// Symbole hinter den Zählern
let css_two = `
/* Counter #1 Folder */
#bmContent::before {
content: attr(data-value1) !important;
width: ${cs_width_one} !important;
align-items: center !important;
display: flex !important;
justify-content: end !important;
background-image: url("${ProfilePath}/${icon1}")!important;
background-position: center right calc(${cs_width_uno} - ${cs_icon_size}) !important;
background-repeat: no-repeat !important;
background-size: ${cs_icon_size} ${cs_icon_size} !important;
color: ${cs_font_color_1} !important; /* Farbe der 1. Zahl */
fill: ${cs_icon_color_1} !important; /* Farbe des 1. Symbols */
padding: 2px 20px 0px 10px !important; /* top | right | bottom | left */
/*margin-inline: 0px -10px; */
margin-left: 16px !important; /* Abstand links minimum für schmale Popus CHANGE */
margin-right: 12px !important; /* Abstand Icon "Ordner" bis zum "Zähler" */
}
#bmContent::after {
content: attr(data-value2) !important;
width: ${cs_width_two} !important;
align-items: center !important;
display: flex !important;
justify-content: end !important;
/*justify-content: flex-end; */
background-image: url("${ProfilePath}/${icon2}")!important;
background-position: center right calc(${cs_width_due} - ${cs_icon_size}) !important;
background-repeat: no-repeat !important;
background-size: ${cs_icon_size} ${cs_icon_size} !important;
color: ${cs_font_color_2} !important; /* Farbe der 2. Zahl */
fill: ${cs_icon_color_2} !important; /* Farbe des 2. Symbols */
padding: 2px 22px 0 0 !important; /* top | right | bottom | left */
margin-left: -14px !important; /* Abstand "Zähler 1" zum Icon2 */
margin-right: -1px !important; /* Abstand Icon "Links" bis zum "Zähler" */
}
`;
function setFunction() {
const css =`
/* Counter rechtsbuendig */
#bmContent {
display: flex !important;
margin-inline: auto 0 !important;
font-family: Consolas, "Lucida Console", "Courier New", monospace !important;
font-size: ${cs_font_size} !important;
font-weight: ${cs_font_weight} !important;
height: ${cs_icon_size} !important;
}
/* Dynamisch gewählter before-Block */
${useStyle ? css_one : css_two}
/* Pfeil */
menupopup > menu::after {
content: "" !important;
background-image: url("${ProfilePath}/${icon3}")!important;
height: ${cs_icon_size} !important;
height: ${cs_icon_size} !important;
fill: ${cs_icon_color_3} !important;
}
`;
const sss = Cc['@mozilla.org/content/style-sheet-service;1'].getService(Ci.nsIStyleSheetService);
const uri = Services.io.newURI('data:text/css,' + encodeURIComponent(css));
sss.loadAndRegisterSheet(uri, sss.AGENT_SHEET);
let bmbMenu = document.getElementById('bookmarks-menu-button');
let bookMenu = document.getElementById('bookmarksMenu');
let persToolBar = document.getElementById('PersonalToolbar');
if(bmbMenu)
bmbMenu.addEventListener('popupshowing', onPopupShowing );
if(bookMenu)
bookMenu.addEventListener('popupshowing', onPopupShowing );
if(persToolBar)
persToolBar.addEventListener('popupshowing', onPopupShowing );
}
function onPopupShowing(aEvent) {
let popup = aEvent.originalTarget;
for (let item of popup.children) {
if (item.localName != 'menu' || item.id?.startsWith('history'))
continue;
setTimeout(() => {
let itemPopup = item.menupopup;
itemPopup.hidden = true;
itemPopup.collapsed = true;
itemPopup.openPopup();
itemPopup.hidePopup();
let menuitemCount = 0;
let menuCount = 0;
for (let subitem of itemPopup.children) {
if (subitem.classList.contains('bookmark-item') && !subitem.disabled && !subitem.hidden) {
if (subitem.localName == 'menuitem') {
menuitemCount++;
} else if (subitem.localName == 'menu') {
menuCount++;
}
}
}
itemPopup.hidden = false;
itemPopup.collapsed = false;
// Neues Element für Zaehler
let bmCounta = item.childNodes[1];
if (!bmCounta) return; // Falls undefiniert
bmCounta.innerHTML = ""
let bmContent = document.createElement("bmContent");
bmContent.id = "bmContent";
bmCounta.appendChild(bmContent);
//let strCountOut1 = " " + menuCount + " "; // Has no brackets
//let strCountOut1 = "(" + menuCount + ")"; // Has round brackets
//let strCountOut1 = "[" + menuCount + "]"; // Has square brackets
let strCountOut1 = String(menuCount).padEnd(2, " ");
bmContent.setAttribute('data-value1', strCountOut1);
//let strCountOut2 = " " + menuitemCount + " "; // Has no brackets
//let strCountOut2 = "(" + menuitemCount + ")"; // Has round brackets
//let strCountOut2 = "[" + menuitemCount + "]"; // Has square brackets
// let strCountOut2 = String(menuitemCount).padEnd(2, " ");
// bmContent.setAttribute('data-value2', strCountOut2);
let strCountOut2 = (useStyle === 0)
? String(menuitemCount).padStart(4, "/ ")
: String(menuitemCount).padEnd(2, " ");
bmContent.setAttribute('data-value2', strCountOut2);
}, 100);
}
}
})();
Alles anzeigen