1. Nachrichten
  2. Forum
    1. Unerledigte Themen
    2. Forenregeln
  3. Spenden
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Forum
  • Erweiterte Suche
  1. camp-firefox.de
  2. Speravir

Beiträge von Speravir

  • UserCSSLoader (2025)

    • Speravir
    • 11. Oktober 2025 um 00:31
    Zitat von Endor

    Hast Du einen Vorschlag für den Readme?

    Was Du geschrieben hast, ist in Ordnung. Was ich meinte, ist eine Ergänzung der Art:

    Zitat

    Wird CSS1.png verwendet, muss entweder sie selbst in CSS.png umbenannt werden oder der Aufruf in der CSS-Datei zu CSS1.png geändert werden.

    Ich bemerke aber gerade, dass die andere Datei css.png heißt, während in der CSS-Datei CSS.png geladen wird. In Windows ist das egal, aber nicht in den anderen Betriebssystemen. Also am besten eine der Seiten anpassen und eventuell den obigen Text entsprechend anpassen, wenn du ihn denn überhaupt so nutzen willst.

    Übrigens nebenbei: Es muss in der Readme CSS-Code heißen (mit Bindestrich).

    Und wenn Du schon eine Readme-Datei hast, gib doch noch die Herkunft der Symbole an; Vorschlag für den untersten Teil:

    Code: Readme-letzterAbsatz.md
    **Symbole:**\
    ![css.png](https://github.com/Endor8/userChrome.js/blob/master/Firefox%20143/usercssloader/icons/css.png?raw=true) (Herkunft: [Crystal Project stylesheet.png](https://commons.wikimedia.org/wiki/File:Crystal_Project_stylesheet.png), Crystal Project Icons, Link zu Wikimedia Commons)\
    ![CSS1.png](https://github.com/Endor8/userChrome.js/blob/master/Firefox%20143/usercssloader/icons/CSS1.png?raw=true) (Herkunft: [CSS text representation (short).png](https://commons.wikimedia.org/wiki/File:CSS_text_representation_(short).png), Wikimedia Commons)

    Das ist wichtig wegen der Lizenzen.

    (Zu den Backslashes statt mehrerer Leerzeichen siehe Basic writing and formatting syntax - Line Breaks in den GitHub Docs. Das weiß ich selbst auch noch nicht so lange.)

    Nachtrag: Oder ist die Vorlage für css,png doch eher File:Noia 64 apps stylesheet.png? Dann müsste man es natürlich anpassen. Was man überhaupt nicht muss, aber natürlich tun könnte, ist, noch einen Link ergänzen:

    Code: Hinweis-in-Readme.md
    Für weitere Symbole siehe beispielsweise in Wikimedia Commons in der Kategorie [Cascading Style Sheets icons](https://commons.wikimedia.org/wiki/Category:Cascading_Style_Sheets_icons).
  • UserCSSLoader (2025)

    • Speravir
    • 9. Oktober 2025 um 23:45
    Zitat von Mira_Belle

    Von daher wäre es sogar sinnvoll, den Aufruf zum Bearbeiten eben jener Datei aus dem Skript wieder zu entfernen.
    Nicht, dass da so manch einer auf dumme Ideen gebracht wird.

    Ich hab ihn drin gelassen, aber noch eine Warnung ergänzt.

  • UserCSSLoader (2025)

    • Speravir
    • 9. Oktober 2025 um 02:37
    Zitat von Mitleser

    Es ist tatsächlich ein Problem irgendwo auf Systemebene; allerdings bisher nur mit genau Zeile 95 in genau dieser Datei.

    Oh, ich hätte nach Deinem ersten Hinweis auf den Scriptcache getippt.

    Zitat von Endor

    Die vier neuen Einträge:
    "prefs.js", "user.js", "userChromeShadow.css" & "userChrome.js"

    Wie ich oben sagte, es heißt ja UserCSSLoader. Ich habe mich dafür entschieden, die drei Javascript-Dateien in der Voreinstellung nicht zu laden. Das hat aber nicht nur den Skriptnamen als Grund:

    • Die userChrome.js muss notgedrungen vorhanden sein, aber es sollte bei der Version, die wir hier vermutlich alle nutzen, nicht notwendig sein, sie zu bearbeiten. Beispielsweise bei der Variante, die man bei Aris findet, wäre das anders. Wenn ich mich recht erinnere, gibt es übrigens Skriptloader, wo die Datei in einem Unterverzeichnis liegt.
    • Die prefs.js bei laufendem Firefox zu öffnen bearbeiten und vor allem dann neu abzuspeichern, ist geradezu leichtsinnig. Wer den Eintrag aktiviert, sollte wissen, was er tut.
    • Die user.js zu bearbeiten, ist dagegen ungefährlich (man kann sich mit falschen Einträgen ins Knie schießen, aber darum geht es hier nicht), aber sie ist standardmäßig nicht vorhanden. Letzteres trifft zwar auch auf die userChromeShadow.css zu, aber dort greift der Name. :S

    Mira_Belle, Du wirst einige kleinere Änderungen feststellen. Ich habe lieber eigene Variablen für jeden Menüeintrag verwendet. Und editUserCSS stimmt ja wegen userChrome.js so nicht mehr, daher editUCFile.

    Zitat von Endor

    Nur hier:
    let customEditor = "C:\\Program Files\\Microsoft VS Code\\Code.exe";

    würde ich nur die Anführungszeichen alleine lassen.
    als so:
    let customEditor = "";

    Das habe ich so wieder zurückgesetzt, ebenso den fileManager.

    Endor, wieder als Update? Und was hältst Du davon, „mein“ Symbol als Variante hochzuladen? Siehe ZIP-Datei im Anfangsposting (ha, die ZIP ist ja größer als die PNG selbst). Dazu müsstest du natürlich eine oder beide PNG-Dateien umbenennen(*) und eventuell eine kleine Readme.md mit kurzem Hinweis anlegen, dass man nach dem Herunterladen entweder diese Variante zurück benennen oder den Namen in der CSS ändern muss.

    (*) CSS-1.png, CSS-2.png oder, weil „mein“ Symbol eigentlich aus Wikimedia stammt, CSS-WM.png oder … oder …

    JavaScript
    /* UserCSSLoader 2025-10-10
     *
     * original author: Griever -
     * https://github.com/Griever/userChromeJS/tree/master/UserCSSLoader
     *
     * Enhancements and several other changes including German translation and
     * configuration section by users aborix, Endor, bege, Mira_Belle, Speravir
     * of Camp Firefox forum - https://www.camp-firefox.de/forum/ - latest version:
     * https://www.camp-firefox.de/forum/thema/138814/?postID=1280726#post1280726
     */
    
    /****** Bedienungsanleitung ******
    
    CSS-Ordner im Chrome-Ordner erstellen, CSS-Dateien dort ablegen - speichern.
    Diejenigen, deren Dateiname mit "xul-" beginnen, diejenigen, die mit ".as.css"
    enden, sind AGENT_SHEET, alle anderen außer USER_SHEET werden gelesen. Da der
    Inhalt der Datei nicht überprüft wird, darauf achten, die Angabe von @namespace
    nicht zu vergessen!
    
    Schaltfläche oder Menü wird in Navigationsleiste eingefügt (einstellbar, siehe
    Variable "position" in unten anschließender Konfiguration).
    
    Dateiordner, Dateimanager und Texteditor können in der unten anschließenden
    Konfiguration geändert werden. Die Verwendung des in "view_source.editor.path"
    angegebenen Editors ist möglich.
    
    Linksklick auf Stil, zum Aktivieren/Deaktivieren
    Mittelklick auf Stil zum Aktivieren/Deaktivieren, ohne Menü zu schließen
    Rechtsklick auf Stil zum Öffnen im Editor
    Strg+Linksklick zum Anzeigen im Dateimanager
    
    Die Tastenkombinationen können im Menü eingeblendet werden, dazu nach 
    "acceltext" suchen und den Zeilenkommentar "//" entfernen.
    
    Ein Symbol für die Schaltfläche muss in der "userChrome.css" festgelegt werden,
    Pfad zum Bild (PNG nur als Beispiel):
    * relativ zur userChrome.css
        background-image: url("Relativer/Pfad/zum/CSS_Symbol.png");
    * eine absolute Pfadangabe zum Symbol muss mit File-Protokoll-Präfix erfolgen:
        background-image: url("file:///Absoluter/Pfad/zum/CSS_Symbol.png");
    
    Absolute Zahlenwerte müssen eventuell etwas an die eigenen Gegebenheiten
    angepasst werden (größeres Symbol, anderer Rand); der Zahlenwert für Höhe
    und Breite des Menütextes ("CSS") sollte nicht größer sein als für das
    Symbol (hier 16px).
    
    #usercssloader-menu-item {
    	background-image: url("Relativer/Pfad/zum/CSS_Symbol.png");
    	background-position: center;
    	background-repeat: no-repeat;
    	background-size: 16px;
    	border-radius: var(--toolbarbutton-border-radius);
    	margin-block: 3px;
    
    	&:hover {
    		background-color: var(--toolbarbutton-hover-background);
    	}
    
    	& #usercssloader-menu > .menu-text[value="CSS"] {
    		opacity: 0;
    		width: calc(2 * var(--toolbarbutton-inner-padding) + 16px);
    		height: calc(2 * var(--toolbarbutton-inner-padding) + 16px);
    	}
    }
    
    **** Ende der Anleitung ****/
    
    (function(){
    
    /***** Konfiguration *****/
    /* Position: als frei verschiebbare-Schaltfläche = 0, als Menü anzeigen = 1 */
    let position = 0;//1
    /* Dateimanager festlegen, Beispiele:
     *    let fileManager = "C:\\Programme\\FreeCommanderXE\\FreeCommander.exe";
     *    let fileManager = "C:\\Programme\\totalcmd\\TOTALCMD.EXE";
     * auch möglich (Achtung, nur mit fileManagerParam = "/select,"!):
     *    let fileManager = "C:\\Windows\\explorer.exe";
     * Bleibt Parameter leer, wird Standardmanager des Systems ohne Parameter
     * verwendet mit leicht eingeschränkter Funktionalität. */
    let fileManager = "";
    /* eventuelle Parameter für den Dateimanager, Beispiele:
     *    let fileManagerParam = "/T";//FreeCommander oder Totalcommander
     *    let fileManagerParam = "/select,";//Windows Explorer, mit Komma korrekt!
     */
    let fileManagerParam = "";
    /* manche Manager benötigen den Parameter nach der Pfadangabe,
       dann "fileManagerParamPost" auf true setzen */
    let fileManagerParamPost = false;
    /* eigener Texteditor mit Pfad - Standard leer, dann wird Wert aus
     * Einstellung "view_source.editor.path" verwendet mit Warnmeldung,
     * wenn auch dieser leer ist, Beispiel:
     *    let customEditor = "C:\\Windows\\System32\\notepad.exe"; */
    let customEditor = "";
    /* Unterordner für die CSS-Dateien */
    let cssFolder = "CSS";
    /* zusätzlich Chrome-Ordner im Untermenü anzeigen (true)
       oder verstecken (false) */
    let showChrome = true;
    /* Menüeintrag zum Bearbeiten der userChrome.css anzeigen (true)
       oder verstecken (false) */
    let showUserChromeCSS = true;
    /* Menüeintrag zum Bearbeiten der userContent.css anzeigen (true)
       oder verstecken (false) */
    let showUserContentCSS = true;
    /* Menüeintrag zum Bearbeiten der userChromeShadow.css anzeigen (true)
       oder verstecken (false) */
    let showUserChromeShadowCSS = true;
    /* Menüeintrag zum Bearbeiten der userChrome.js anzeigen (true)
       oder verstecken (false) */
    let showUserChromeJS = false;
    /* Menüeintrag zum Bearbeiten der pref.js anzeigen (true) oder
       verstecken (false); Achtung, diese Datei sollte nur zum Ansehen geöffnet
       werden, bei laufendem Firefox werden Änderungen wieder überschrieben! */
    let showPrefsJS = false;
    /* Menüeintrag zum Bearbeiten der user.js anzeigen (true)
       oder verstecken (false) */
    let showUserJS = false;
    /***** Ende der Konfiguration *****/
    
    // Wenn beim Start ein weiteres Fenster (zweites Fenster) vorhanden ist, beenden
    let list = Services.wm.getEnumerator("navigator:browser");
    while(list.hasMoreElements()){ if(list.getNext() != window) return; }
    
    if (window.UCL) {
    	window.UCL.destroy();
    	delete window.UCL;
    }
    
    let menutooltip = "Linksklick: an/aus, Menü schließt\nMittelklick: an/aus, Menü bleibt offen\nRechtsklick: bearbeiten";
    if (fileManager !== "") {
    		menutooltip = menutooltip + "\nStrg+Rechtsklick: im Dateimanager anzeigen";
    }
    
    window.UCL = {
    	AGENT_SHEET : Ci.nsIStyleSheetService.AGENT_SHEET,
    	USER_SHEET  : Ci.nsIStyleSheetService.USER_SHEET,
    	AUTHOR_SHEET: Ci.nsIStyleSheetService.AUTHOR_SHEET,
    	readCSS: {},
    	get disabled_list() {
    		let obj = [];
    		try {
    			obj = decodeURIComponent(this.prefs.getCharPref("disabled_list")).split("|");
    		} catch(e) {}
    		delete this.disabled_list;
    		return this.disabled_list = obj;
    	},
    	get prefs() {
    		delete this.prefs;
    		return this.prefs = Services.prefs.getBranch("UserCSSLoader.");
    	},
    	get styleSheetServices() {
    		delete this.styleSheetServices;
    		return this.styleSheetServices = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
    	},
    	get FOLDER() {
    		let aFolder;
    		try {
    			// UserCSSLoader.FOLDER verwenden
    			let folderPath = this.prefs.getCharPref("FOLDER");
    			aFolder = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
    			aFolder.initWithPath(folderPath);
    		} catch (e) {
    			aFolder = Services.dirsvc.get("UChrm", Ci.nsIFile);
    			aFolder.appendRelativePath(cssFolder);
    		}
    		if (!aFolder.exists() || !aFolder.isDirectory()) {
    			aFolder.create(Ci.nsIFile.DIRECTORY_TYPE, 0o664);
    		}
    		delete this.FOLDER;
    		return this.FOLDER = aFolder;
    	},
    	get CHRMFOLDER() {
    			let cFolder;
    			try {
    					// UserCSSLoader.CHRMFOLDER verwenden
    					let CHRMfolderPath = this.prefs.getCharPref("CHRMFOLDER");
    					cFolder = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
    					cFolder.initWithPath(CHRMfolderPath);
    			} catch (e) {
    					cFolder = Services.dirsvc.get("UChrm", Ci.nsIFile);
    			}
    			if (!cFolder.exists() || !cFolder.isDirectory()) {
    					cFolder.create(Ci.nsIFile.DIRECTORY_TYPE, 0o664);
    			}
    			delete this.CHRMFOLDER;
    			return this.CHRMFOLDER = cFolder;
    	},
    
    	init: function() {
    		const cssmenu = $C("menu", {
    			id: "usercssloader-menu",
    			label: "CSS",
    			tooltiptext: "UserCSSLoader\n\nLinksklick: Stylesheets anzeigen\nMittelklick: Styles importieren",
    			accesskey: "Y"
    		});
    		cssmenu.addEventListener("click", (event) => { if (event.button === 1) UCL.rebuild(); });
    		const menupopup = $C("menupopup", {
    			id: "usercssloader-menupopup"
    		});
    		cssmenu.appendChild(menupopup);
    
    		let menu = $C("menu", {
    			label: "Style-Loader-Menü",
    			id: "style-loader-menu",
    			accesskey: "S",
    			//acceltext: "S"
    		});
    		menupopup.appendChild(menu);
    		menupopup.appendChild($C("menuseparator"));
    
    		let mp = $C("menupopup", { id: "usercssloader-submenupopup" });
    		menu.appendChild(mp);
    		let rebuildItem = $C("menuitem", {
    			label: "Styles importieren",
    			accesskey: "I",
    			//acceltext: "I"
    		});
    		rebuildItem.addEventListener("command", () => UCL.rebuild());
    		mp.appendChild(rebuildItem);
    		mp.appendChild($C("menuseparator"));
    		//
    		let createCSS = $C("menuitem", {
    			label: "CSS-Datei erstellen",
    			accesskey: "D",
    			//acceltext: "D"
    		});
    		createCSS.addEventListener("command", () => UCL.create());
    		mp.appendChild(createCSS);
    		let openFolder = $C("menuitem", {
    			label: "CSS-Ordner öffnen",
    			accesskey: "O",
    			//acceltext: "O"
    		});
    		openFolder.addEventListener("command", () => UCL.openCSSFolder());
    		mp.appendChild(openFolder);
    		if (showChrome) {
    				let openChromeFolder = $C("menuitem", {
    					label: "Chrome-Ordner öffnen",
    					accesskey: "X",
    					//acceltext: "X"
    				});
    				openChromeFolder.addEventListener("command", () => UCL.openCHRMFolder());
    				mp.appendChild(openChromeFolder);
    		}
    		if (showUserChromeCSS || showUserContentCSS || showUserChromeShadowCSS)
    		   // wenigstens eine der Variablen muss "true" sein, …
    				mp.appendChild($C('menuseparator')); // … damit Trennlinie angezeigt wird
    		if (showUserChromeCSS) {
    				let editChromeItem = $C("menuitem", {
    					label: "userChrome.css bearbeiten"
    				});
    				editChromeItem.addEventListener("command", () => UCL.editUCFile("userChrome.css"));
    				mp.appendChild(editChromeItem);
    		}
    		if (showUserContentCSS) {
    				let editContentItem = $C("menuitem", {
    					label: "userContent.css bearbeiten"
    				});
    				editContentItem.addEventListener("command", () => UCL.editUCFile("userContent.css"));
    				mp.appendChild(editContentItem);
    		}
    		if (showUserChromeShadowCSS) {
    				let editUCShadowItem = $C("menuitem", {
    					label: "userChromeShadow.css bearbeiten"
    				});
    				editUCShadowItem.addEventListener("command", () => UCL.editUCFile("userChromeShadow.css"));
    				mp.appendChild(editUCShadowItem);
    		}
    
    		if (showUserChromeJS || showPrefsJS || showUserJS)
    		   // wenigstens eine der Variablen muss "true" sein, …
    			mp.appendChild($C('menuseparator')); // … damit Trennlinie angezeigt wird
    		if (showUserChromeJS) {
    				let editUCjsItem = $C("menuitem", {
    					label: "userChrome.js bearbeiten"
    				});
    				editUCjsItem.addEventListener("command", () => UCL.editUCFile("userChrome.js"));
    				mp.appendChild(editUCjsItem);
    		}		
    		if (showPrefsJS) {
    			let editPrefsItem = $C("menuitem", {
    				label: "prefs.js bearbeiten"
    			});
    			editPrefsItem.addEventListener("command", () => UCL.editProfileFile("prefs.js"));
    			mp.appendChild(editPrefsItem);
    		}
    		if (showUserJS) {
    			let editUserJsItem = $C("menuitem", {
    				label: "user.js bearbeiten"
    			});
    			editUserJsItem.addEventListener("command", () => UCL.editProfileFile("user.js"));
    			mp.appendChild(editUserJsItem);
    		}
    
    		CustomizableUI.createWidget({
    			id: 'usercssloader-menu-item',
    			type: 'custom',
    			defaultArea: CustomizableUI.AREA_NAVBAR,
    			onBuild: function(aDocument) {
    				let toolbaritem = aDocument.createXULElement('toolbaritem');
    				toolbaritem.id = 'usercssloader-menu-item';
    				toolbaritem.className = 'chromeclass-toolbar-additional';
    				return toolbaritem;
    			}
    		});
    		$('usercssloader-menu-item').appendChild(cssmenu);
    
    		if (position === 1) {
    				let refNode = $('helpMenu');
    				refNode.parentNode.insertBefore(cssmenu, refNode.nextSibling);
    		}
    
    		// Stile neu laden, ohne Menü zu öffnen
    		let key = $C("key", {
    			id: "usercssloader-rebuild-key",
    			key: "R",
    			modifiers: "alt",
    		});
    		key.addEventListener("command", () => UCL.rebuild());
    		$("mainKeyset").appendChild(key);
    
    		this.rebuild();
    		this.initialized = true;
    		window.addEventListener("unload", this, false);
    	},
    	uninit: function() {
    		const dis = [];
    		for (let x of Object.keys(this.readCSS)) {
    			if (!this.readCSS[x].enabled)
    				dis.push(x);
    		}
    		this.prefs.setCharPref("disabled_list", encodeURIComponent(dis.join("|")));
    		window.removeEventListener("unload", this, false);
    	},
    	destroy: function() {
    		var i = document.getElementById("usercssloader-menu");
    		if (i) i.parentNode.removeChild(i);
    		var i = document.getElementById("usercssloader-rebuild-key");
    		if (i) i.parentNode.removeChild(i);
    		this.uninit();
    	},
    	handleEvent: function(event) {
    		switch(event.type){
    			case "unload": this.uninit(); break;
    		}
    	},
    	rebuild: function() {
    		let ext = /\.css$/i;
    		let not = /\.uc\.css/i;
    		let files = this.FOLDER.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);
    
    		while (files.hasMoreElements()) {
    			let file = files.getNext().QueryInterface(Ci.nsIFile);
    			if (!ext.test(file.leafName) || not.test(file.leafName)) continue;
    			let CSS = this.loadCSS(file);
    			CSS.flag = true;
    		}
    		for (let leafName of Object.keys(this.readCSS)) {
    			const CSS = this.readCSS[leafName];
    			if (!CSS.flag) {
    				CSS.enabled = false;
    				delete this.readCSS[leafName];
    			}
    			delete CSS.flag;
    			this.rebuildMenu(leafName);
    		}
    		if (this.initialized) {
    			if (typeof(StatusPanel) !== "undefined")
    				StatusPanel._label = "Styles importiert";
    			else
    				XULBrowserWindow.statusTextField.label = "Styles importiert";
    		}
    	},
    	loadCSS: function(aFile) {
    		let CSS = this.readCSS[aFile.leafName];
    		if (!CSS) {
    			CSS = this.readCSS[aFile.leafName] = new CSSEntry(aFile);
    			if (this.disabled_list.indexOf(CSS.leafName) === -1) {
    				CSS.enabled = true;
    			}
    		} else if (CSS.enabled) {
    			CSS.enabled = true;
    		}
    		return CSS;
    	},
    	rebuildMenu: function(aLeafName) {
    		let CSS = this.readCSS[aLeafName];
    		let menuitem = document.getElementById("usercssloader-" + aLeafName);
    		if (!CSS) {
    			if (menuitem)
    				menuitem.parentNode.removeChild(menuitem);
    			return;
    		}
    
    		if (!menuitem) {
    			menuitem = $C("menuitem", {
    				label: aLeafName,
    				id: "usercssloader-" + aLeafName,
    				class: "usercssloader-item " + (CSS.SHEET == this.AGENT_SHEET? "AGENT_SHEET" : CSS.SHEET == this.AUTHOR_SHEET? "AUTHOR_SHEET": "USER_SHEET"),
    				type: "checkbox",
    				autocheck: "false",
    				tooltiptext: menutooltip
    			});
    			menuitem.addEventListener("command", () => UCL.toggle(aLeafName));
    			menuitem.addEventListener("click", (event) => UCL.itemClick(event));
    			menuitem.addEventListener("mouseup", (event) => { if (event.button === 1) event.preventDefault(); });
    			document.getElementById("usercssloader-menupopup").appendChild(menuitem);
    		}
    		menuitem.setAttribute("checked", CSS.enabled);
    	},
    	toggle: function(aLeafName) {
    		let CSS = this.readCSS[aLeafName];
    		if (!CSS || event.ctrlKey) return;
    		CSS.enabled = !CSS.enabled;
    		this.rebuildMenu(aLeafName);
    	},
    	itemClick: function(event) {
    		let label = event.currentTarget.getAttribute("label");
    		event.preventDefault();
    		event.stopPropagation();
    		if (event.button === 0) {
    				return;
    		} else if (event.button === 1) {
    				this.toggle(label);
    		} else if (event.button === 2) {
    				if (event.ctrlKey && fileManager  !== "") {
    						UCL.showFile(label);
    				} else {
    				closeMenus(event.target);
    				this.edit(this.getFileFromLeafName(label));
    				}
    		}
    	},
    	getFileFromLeafName: function(aLeafName) {
    		let f = this.FOLDER.clone();
    		f.QueryInterface(Ci.nsIFile); // use appendRelativePath
    		f.appendRelativePath(aLeafName);
    		return f;
    	},
    	showFile: function(fname) {
    				const PathSep = AppConstants.platform === "win" ? "\\" : "/";
    				let target= this.FOLDER.path + PathSep + fname;
    				let file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
    				let process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess);
    				let args = (!fileManagerParamPost) ? [fileManagerParam,target] :
    				           [target,fileManagerParam];
    				file.initWithPath(fileManager);
    				process.init(file);
    				// Verzeichnis mit anderem Dateimanager öffnen
    				process.run(false, args, args.length);
    	},
    	openCSSFolder:function(){
    		if (fileManager !== "" && fileManagerParam !== "/select,") {
    				let target = this.FOLDER.path;
    				let file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
    				let process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess);
    				let args = (!fileManagerParamPost) ? [fileManagerParam,target] :
    				           [target,fileManagerParam];
    				file.initWithPath(fileManager);
    				process.init(file);
    				// Verzeichnis mit anderem Dateimanager öffnen
    				process.run(false, args, args.length);
    		} else {
    				// Verzeichnis mit Dateimanager des Systems öffnen
    				this.FOLDER.launch();
    		}
    	},
    	openCHRMFolder:function(){
    		if (fileManager !== "" && fileManagerParam !== "/select,") {
    				let target = this.CHRMFOLDER.path;
    				let file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
    				let process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess);
    				let args = (!fileManagerParamPost) ? [fileManagerParam,target] :
    				           [target,fileManagerParam];
    				file.initWithPath(fileManager);
    				process.init(file);
    				// Verzeichnis mit anderem Dateimanager öffnen
    				process.run(false, args, args.length);
    		} else {
    				// Verzeichnis mit Dateimanager des Systems öffnen
    				this.CHRMFOLDER.launch();
    		}
    	},
    	editUCFile: function(aLeafName) {
    		let file = Services.dirsvc.get("UChrm", Ci.nsIFile);
    		file.appendRelativePath(aLeafName);
    		this.edit(file);
    	},
    	editProfileFile: function(filename) {
    		let file = Services.dirsvc.get("ProfD", Ci.nsIFile);
    		file.append(filename);
    		this.edit(file);
    	},
    	edit: function(aFile) {
    		let editor = (customEditor !== "") ? customEditor : Services.prefs.getCharPref("view_source.editor.path");
    		if (!editor) return alert('In der Konfiguration einen Texteditor festlegen ("customEditor") oder\n unter about:config im vorhandenen Schalter "view_source.editor.path"\n den vollständigen Editorpfad eintragen.');
    		try {
    			let UI = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
    			UI.charset = window.navigator.platform.toLowerCase().indexOf("win") >= 0? "Shift_JIS": "UTF-8";
    			let path = UI.ConvertFromUnicode(aFile.path);
    			let app = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
    			app.initWithPath(editor);
    			let process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
    			process.init(app);
    			process.run(false, [path], 1);
    		} catch (e) {}
    	},
    	create: function(aLeafName) {
    		if (!aLeafName) aLeafName = prompt("Name des Styles", dateFormat(new Date(), "%Y_%m%d_%H%M%S"));
    		if (aLeafName) aLeafName = aLeafName.replace(/\s+/g, " ").replace(/[\\/:*?\"<>|]/g, "");
    		if (!aLeafName || !/\S/.test(aLeafName)) return;
    		if (!/\.css$/.test(aLeafName)) aLeafName += ".css";
    		let file = this.getFileFromLeafName(aLeafName);
    		this.edit(file);
    	},
    	UCrebuild: function() {
    		let re = /^file:.*\.uc\.css(?:\?\d+)?$/i;
    		let query = "?" + new Date().getTime();
    		Array.slice(document.styleSheets).forEach(function(css){
    			if (!re.test(css.href)) return;
    			if (css.ownerNode) {
    				css.ownerNode.parentNode.removeChild(css.ownerNode);
    			}
    			let pi = document.createProcessingInstruction('xml-stylesheet','type="text/css" href="'+ css.href.replace(/\?.*/, '') + query +'"');
    			document.insertBefore(pi, document.documentElement);
    		});
    		UCL.UCcreateMenuitem();
    	},
    	UCcreateMenuitem: function() {
    		let sep = $("usercssloader-ucseparator");
    		let popup = sep.parentNode;
    		if (sep.nextSibling) {
    			let range = document.createRange();
    			range.setStartAfter(sep);
    			range.setEndAfter(popup.lastChild);
    			range.deleteContents();
    			range.detach();
    		}
    
    		let re = /^file:.*\.uc\.css(?:\?\d+)?$/i;
    		Array.slice(document.styleSheets).forEach(function(css) {
    			if (!re.test(css.href)) return;
    			let fileURL = decodeURIComponent(css.href).split("?")[0];
    			let aLeafName = fileURL.split("/").pop();
    			let m = $C("menuitem", {
    				label: aLeafName,
    				tooltiptext: fileURL,
    				id: "usercssloader-" + aLeafName,
    				type: "checkbox",
    				autocheck: "false",
    				checked: "true",
    			});
    			m.css = css;
    			m.addEventListener("command", function() {
    				if (!event.ctrlKey) {this.setAttribute("checked", !(this.css.disabled = !this.css.disabled));}
    			});
    			m.addEventListener("mouseup", function(event) {
    				if (event.button === 1) event.preventDefault();
    			});
    			m.addEventListener("click", function(event) {
    				UCL.UCItemClick(event);
    			});
    			popup.appendChild(m);
    		});
    	},
    	UCItemClick: function(event) {
    		if (event.button === 0) return;
    		event.preventDefault();
    		event.stopPropagation();
    
    		if (event.button === 1) {
    			event.target.doCommand();
    		}
    		else if (event.button === 2) {
    			closeMenus(event.target);
    			let fileURL = event.currentTarget.getAttribute("tooltiptext");
    			let file = Services.io.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler).getFileFromURLSpec(fileURL);
    			this.edit(file);
    		}
    	},
    };
    
    function CSSEntry(aFile) {
    	this.path = aFile.path;
    	this.leafName = aFile.leafName;
    	this.lastModifiedTime = 1;
    	this.SHEET = /^xul-|\.as\.css$/i.test(this.leafName) ?
    		Ci.nsIStyleSheetService.AGENT_SHEET:
    		/\.author\.css$/i.test(this.leafName)?
    			Ci.nsIStyleSheetService.AUTHOR_SHEET:
    			Ci.nsIStyleSheetService.USER_SHEET;
    }
    CSSEntry.prototype = {
    	sss: Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService),
    	_enabled: false,
    	get enabled() {
    		return this._enabled;
    	},
    	set enabled(isEnable) {
    		let aFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile)
    		aFile.initWithPath(this.path);
    
    		let isExists = aFile.exists(); // true, wenn die Datei bereits existiert
    		let lastModifiedTime = isExists ? aFile.lastModifiedTime : 0;
    		let isForced = this.lastModifiedTime != lastModifiedTime; //true, wenn es eine Änderung in der Datei gibt
    
    		let fileURL = Services.io.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler).getURLSpecFromActualFile(aFile);
    		let uri = Services.io.newURI(fileURL, null, null);
    
    		if (this.sss.sheetRegistered(uri, this.SHEET)) {
    			// Wenn diese Datei bereits gelesen wurde
    			if (!isEnable || !isExists) {
    				this.sss.unregisterSheet(uri, this.SHEET);
    			}
    			else if (isForced) {
    				// Nach Stornierung erneut einlesen
    				this.sss.unregisterSheet(uri, this.SHEET);
    				this.sss.loadAndRegisterSheet(uri, this.SHEET);
    			}
    		} else {
    			// Datei wurde nicht gelesen
    			if (isEnable && isExists) {
    				this.sss.loadAndRegisterSheet(uri, this.SHEET);
    			}
    		}
    		if (this.lastModifiedTime !== 1 && isEnable && isForced) {
    			log(this.leafName + " wurde aktualisiert");
    		}
    		this.lastModifiedTime = lastModifiedTime;
    		return this._enabled = isEnable;
    	},
    };
    
    UCL.init();
    
    function $(id) { return document.getElementById(id); }
    function $A(arr) { return Array.slice(arr); }
    function $C(name, attr) {
    	const el = document.createXULElement(name);
    	if (attr) Object.keys(attr).forEach(function(n) { el.setAttribute(n, attr[n]) });
    	return el;
    }
    function dateFormat(date, format) {
    	format = format.replace("%Y", ("000" + date.getFullYear()).substr(-4));
    	format = format.replace("%m", ("0" + (date.getMonth()+1)).substr(-2));
    	format = format.replace("%d", ("0" + date.getDate()).substr(-2));
    	format = format.replace("%H", ("0" + date.getHours()).substr(-2));
    	format = format.replace("%M", ("0" + date.getMinutes()).substr(-2));
    	format = format.replace("%S", ("0" + date.getSeconds()).substr(-2));
    	return format;
    }
    
    function log(mes) { console.log(mes); }
    })();
    Alles anzeigen
  • UserCSSLoader (2025)

    • Speravir
    • 7. Oktober 2025 um 00:30

    Ich hab mir Mira_Belles Änderungen noch nicht angesehen, finde sie aber prinzipiell gut, solange sie optional sind – es heißt ja eigentlich UserCSSLoader.

    Zitat von Mitleser

    Läuft das ( https://github.com/Endor8/userChr…cssloader.uc.js ) auch auf Linux?

    Von der Idee her sollte es. Mangels Linux kann ich es aber nicht testen.

    Zitat von Mitleser

    (Info/Vergleich: Das Script aus Beitrag 138 funktioniert.)

    Also die Version bei Endor. Wenn die Version von Mira-Belle noch nicht einmal gefunden wir, kontrolliere doch mal, ob sie überhaupt in UTF-8 kodiert ist.

  • Skript zum Anpassen der Scrollbar funktioniert nicht mehr richtig

    • Speravir
    • 1. Oktober 2025 um 00:07
    Zitat von Mira_Belle

    Das sind die Gründe, warum ich dieses CSS in einer neueren Version des Skripts entfernt habe.

    Ach so. Alles klar.

    Zitat von Boersenfeger

    Leider keine Änderung...

    Auch dir danke für die Rückmeldung.

    Zitat von Boersenfeger

    Ich habe nun nur diesen Wert geändert:

    user_pref("widget.non-native-theme.scrollbar.style", 1); /* Scrollbalken breiter */

    Und die anderen Varianten hattest du ebenso getestet, wenigstens 2–4 (5 ist Windows 11)?

    Es gibt da übrigens noch eine Einstellung, die bei Tests besser auf false gesetzt wird: layout.css.cached-scrollbar-styles.enabled. Für das Skript sollte sie keine Auswirkung haben, aber für den CSS-Teil, wie man am Namen der Einstellung erahnen kann.

  • UserCSSLoader (2025)

    • Speravir
    • 30. September 2025 um 23:48
    Zitat von bege

    Ich bin erst jetzt dazu gekommen, die neue Version zu testen.

    In den Zeilen 407 und 423 ist ein Flüchtigkeitsfehler.

    Danke fürs Durchsehen und: Upps.

    Zitat von bege

    Einfacher wäre, in der Konfiguration darauf hinzuweisen, dass der Parameter /select, eingetragen werden muss,

    Stimmt, ich hab mal einen entsprechenden Hinweis zu Beginn eingefügt.

    Siehe aktualisiertes Skript in Beitrag #128, beachte das geänderte Datum, Bege. Endor, ich hoffe, Du kannst es bei dir updaten?!

  • Skript zum Anpassen der Scrollbar funktioniert nicht mehr richtig

    • Speravir
    • 28. September 2025 um 01:40

    1. Als Update zu Beitrag #242. Als ich wegen Boersenfegers Nachfrage nachsah, ist mir komischerweise eben erst aufgefallen, dass man ja schon wenige Zeilen zuvor ebenfalls zusammenfassen kann und das nicht mehr existente horizontal muss auch in den folgenden Zeile entfernt werden, deshalb alles nochmal gemeinsam:

    CSS
    		scrollbar > slider > thumb {
    		  background-color: ${cs_thumb_color} !important;
    		  background-image: ${cs_thumb_image_horizontal} !important;
    
    		  border-radius: ${cs_thumb_roundness}px !important;
    		  box-shadow: inset 0 0 0 ${cs_thumb_border}px ${cs_thumb_border_color} !important;
    		  min-width: ${cs_thumb_minimal_size}px !important;
    
    		}
    		scrollbar[vertical] > slider > thumb {
    		  background-image: ${cs_thumb_image_vertical} !important;
    		  min-height: ${cs_thumb_minimal_size}px !important;
    		}
    		scrollbar > slider > thumb:is(:hover, active) {
    		  background-color: ${cs_thumb_hover_color} !important;
    		  background-image: ${cs_thumb_hover_image_horizontal} !important;
    		}
    		scrollbar > slider > thumb[vertical]:is(:hover, :active) {
    		  background-image: ${cs_thumb_hover_image_vertical} !important;
    		}
    		scrollbar > scrollbarbutton {
    		  background-color: ${cs_buttons_color} !important;
    		  background-image: ${cs_buttons_image_horizontal} !important;
    		  border-radius: ${cs_buttons_roundness}px !important;
    		  box-shadow: inset 0 0 0 ${cs_buttons_border}px !important;
    		  height: 17px !important;
    		  width: 17px !important;
    		}
    		scrollbar[vertical] > scrollbarbutton {
    		  background-image: ${cs_buttons_image_vertical} !important;
    		}
    		scrollbar > scrollbarbutton:hover {
    		  background-color: ${cs_buttons_hover_color} !important;
    		  background-image: ${cs_buttons_hover_image_horizontal} !important;
    		}
    		scrollbar[vertical] > scrollbarbutton:hover {
    		  background-image: ${cs_buttons_hover_image_vertical} !important;
    		}
    Alles anzeigen

    2. Breite der Leisten:

    Zitat von Boersenfeger

    möchte ich die Scrollbar um 5 px breiter haben.

    Teste, was geschieht, wenn du oben unter Punkt 1 in Zeile 117 und 148 den Wert für Höhe beziehungsweise Breite auf 22px setzt.

    Übrigens:

    Es funktioniert nicht mehr richtig seit irgendeinem Firefox-Update, meine ich, aber ich habe hier (aktualisiert natürlich) Aris’ jüngste Version custom_scrollbars.uc.js, wo es in Zeile 53–54 eine Einstellung thin_scrollbars gibt und relativ am Ende des Skripts den dazugehörenden CSS-Code (bei Aris ab Z. 323), den man dann nur wegen des entfernten horizontal anpassen muss:

    JavaScript
      if(thin_scrollbars === true)
        thin_scrollbars_code=`
            :root{
              scrollbar-width: thin !important;
            }
            scrollbar scrollbarbutton {
              height: 7px !important;
              width: 14px !important;
            }
            scrollbar[vertical] scrollbarbutton {
              height: 14px !important;
              width: 7px !important;
            }
        `;
    Alles anzeigen

    Ich hab für mich Höhe und Breite auf denselben Wert gesetzt. Bringt nur nichts für breitere Laufleisten.

  • UserCSSLoader (2025)

    • Speravir
    • 25. September 2025 um 00:45

    Endor hat das Skript in der Version aus Beitrag #128 jetzt bei GitHub hochgeladen (danke):

    userChrome.js/Firefox 143/usercssloader/usercssloader.uc.js at master · Endor8/userChrome.js
    Skripte für die Firefox-Erweiterung userChromeJS. Contribute to Endor8/userChrome.js development by creating an account on GitHub.
    github.com
  • Skript zum Anpassen der Scrollbar funktioniert nicht mehr richtig

    • Speravir
    • 24. September 2025 um 01:00
    Zitat von Mira_Belle

    Eine etwas aufgeräumtere Version für den FF 143.

    Einfach mal Danke von mir Dir und allen anderen, die eventuell noch daran beteiligt waren, ich jetzt aber auf die Schnelle nicht heraussuchen wollte.

    Ein wenig kosmetische Kritik (Info auch edvoldi).

    Es müsste orthographisch korrekt GRADIENT_HORIZONTAL heißen, das heißt ein N ist aus GRADIENT_HORINZONTAL zu entfernen. Für die Funktion der Konstante ist das zum Glück egal (wir hatten das Thema letztens erst).

    Das andere ist schwerwiegender und sollte einen Einfluss haben: Es gibt keinen Selektor horizontal mehr. Das heißt, dass in Zeile 142 zweimal das thumb[horizontal]zu thumb zu verkürzen ist und die beiden Regeln aus Zeile 138 und 142 in der Reihenfolge zu vertauschen wären. Nach dem Kürzen ergibt sich aber die bereits in Z. 135 stehende Regel, so dass man diese zwei zusammenfassen kann. Zusätzlich kann man die Regeln nochmals verkürzen, weshalb ich sie hier mal zusammen poste (die Einrückung ist durch das Kopieren übernommen worden):

    CSS
    		scrollbar > slider > thumb:is(:hover, active) {
    		  background-color: ${cs_thumb_hover_color} !important;
    		  background-image: ${cs_thumb_hover_image_horizontal} !important;
    		}
    		scrollbar > slider > thumb[vertical]:is(:hover, :active) {
    		  background-image: ${cs_thumb_hover_image_vertical} !important;
    		}

    Update: Siehe erweiterte Regeln in Beitrag #246.

    Zitat von Mira_Belle

    Corner ist normalerweise das kleine "Dreieck" in der rechten unteren Ecke!

    (Ping 2002Andreas.) Nicht Dreieck. Es ist das Quadrat, „die Ecke“, rechts unten, das/die entsteht, wenn beide Laufleisten zugleich sichtbar sind.

  • UserCSSLoader (2025)

    • Speravir
    • 24. September 2025 um 00:24
    Zitat von Mira_Belle

    Was die Einschränkungen sein sollen, mir ist nichts aufgefallen.
    Der Explorer verhält sich gleich.

    Nein, nicht völlig. Wenn man fileManager leer lässt, funktioniert das hier nicht:

    Code
    Strg+Rechtsklick: im Dateimanager anzeigen

    Das bezieht sich auf die Dateien im CSS-Ordner (der, dessen Benennung man mit cssFolder festlegen kann).

  • Firefox 143.0.1 behebt durch Trend Micro verursachten Absturz

    • Speravir
    • 20. September 2025 um 23:57

    Statt an jede einzelne Antwort ein „Gefällt-mir“-Bapperl anzuhängen einfach mal danke für die gesamte Konversation hier!

  • UserCSSLoader (2025)

    • Speravir
    • 17. September 2025 um 00:13
    Zitat von bege

    Leider funktioniert das Skript mit diesen Konfigurationen nicht:
    Windows Explorer ist mit Parameter angegeben: Chrome- und CSS-Ordner werden nicht geöffnet, sondern nur im Elternordner ausgewählt, weil diese Abfrage aus meiner Version fehlt: if (fileManagerParam !== "/select,")
    Windows Explorer ist ohne Parameter angegeben: Weder die Ordner lassen sich öffnen noch die Dateien im Explorer anzeigen. Aus der Konfigurationserklärung wird nicht deutlich, dass in deiner Version beim Explorer der Parameter angegeben werden muss.

    Hmpf. Ich hatte das natürlich explizit getestet vor der letzten Veröffentlichung. Nachdem ich deinen Text gelesen habe, ging es aber bei mir auch nicht mehr – was nicht gut ist, weil das vermuten lässt, dass eine Race Condition vorhanden ist (bei Mira_Belle scheint beispielsweise alles zu funktionieren). Ich hatte die Sonderbehandlung des Windows-Explorer vermeiden wollen, habe nun aber die Bedingung eingebaut. Der Punkt „Chrome- und CSS-Ordner werden nicht geöffnet, sondern nur im Elternordner ausgewählt“ ist jedoch weiterhin gültig. Das erfordert einen einzigen weiteren Klick, damit sollte man leben können. Es kann sein, dass das schon vorher so war und mir nur nie aufgefallen ist.

    Zitat von bege

    Kleinigkeiten:
    in den Zeilen 408 und 424 kann das Komma nach target weg, glaube ich.
    Ich vermisse im Header @version und @compatibility, damit man bei zukünftigen Änderungen gleich sieht, welche Version man hat.

    Kommata: Upps. So etwas Unscheinbares kann schon die Ursache für Probleme sein. Man sollte zwar denken, dass ein leerer (eigentlich: undefinierter) angehängter Parameter keine Rolle spielt, aber vielleicht wqr genau das die Ursache für die oben genannte Merkwürdigkeit.

    Ich hatte den langen Header absichtlich entfernt, die Versionierung stimmte sowieso nicht richtig, ich wäre da eher für eine (ISO-)Datumsangabe. Zur Kompatibilität kann ich überhaupt nichts sagen und deshalb nichts derartiges im Skript eintragen.

    Zitat von 2002Andreas

    Ich hoffe das hilft dir weiter.

    Danke, Andreas. Ich hab die entsprechenden Eigenschaften samt Werten eingefügt und diesen Text ergänzt:

    Zitat

    Absolute Zahlenwerte müssen eventuell etwas an die eigenen Gegebenheiten
    angepasst werden (größeres Symbol, anderer Rand); der Zahlenwert für Höhe
    und Breite des Menütextes ("CSS") sollte nicht größer sein als für das
    Symbol (hier 16px).

    Man könnte jetzt noch eine eigene angepasste Eigenschaft einführen, damit man nicht dreimal denselben Zahlenwert ändern muss, Es fragt sich nur, inwiefern man damit andere überfordert.

    (Update: Korrektur und Hinweis entsprechend Vorschlag von bege in Beitrag #133.)

    JavaScript
    /* UserCSSLoader 2025-09-30
     *
     * original author: Griever -
     * https://github.com/Griever/userChromeJS/tree/master/UserCSSLoader
     *
     * Enhancements and several other changes including German translation
     * and configuration section by users aborix, Endor, bege, Speravir of
     * Camp Firefox forum - https://www.camp-firefox.de/forum/ - latest version:
     * https://www.camp-firefox.de/forum/thema/138814/?postID=1279211#post1279211
     */
    
    /****** Bedienungsanleitung ******
    
    CSS-Ordner im Chrome-Ordner erstellen, CSS-Dateien dort ablegen - speichern.
    Diejenigen, deren Dateiname mit "xul-" beginnen, diejenigen, die mit ".as.css"
    enden, sind AGENT_SHEET, alle anderen außer USER_SHEET werden gelesen. Da der
    Inhalt der Datei nicht überprüft wird, darauf achten, die Angabe von @namespace
    nicht zu vergessen!
    
    Schaltfläche oder Menü wird in Navigationsleiste eingefügt (einstellbar, siehe
    Variable "position" in unten anschließender Konfiguration).
    
    Dateiordner, Dateimanager und Texteditor können in der unten anschließenden
    Konfiguration geändert werden. Die Verwendung des in "view_source.editor.path"
    angegebenen Editors ist möglich.
    
    Linksklick auf Stil, zum Aktivieren/Deaktivieren
    Mittelklick auf Stil zum Aktivieren/Deaktivieren, ohne Menü zu schließen
    Rechtsklick auf Stil zum Öffnen im Editor
    Strg+Linksklick zum Anzeigen im Dateimanager
    
    Die Tastenkombinationen können im Menü eingeblendet werden, dazu nach 
    "acceltext" suchen und den Zeilenkommentar "//" entfernen.
    
    Ein Symbol für die Schaltfläche muss in der "userChrome.css" festgelegt werden,
    Pfad zum Bild (PNG nur als Beispiel):
    * relativ zur userChrome.css
        background-image: url("Relativer/Pfad/zum/CSS_Symbol.png");
    * eine absolute Pfadangabe zum Symbol muss mit File-Protokoll-Präfix erfolgen:
        background-image: url("file:///Absoluter/Pfad/zum/CSS_Symbol.png");
    
    Absolute Zahlenwerte müssen eventuell etwas an die eigenen Gegebenheiten
    angepasst werden (größeres Symbol, anderer Rand); der Zahlenwert für Höhe
    und Breite des Menütextes ("CSS") sollte nicht größer sein als für das
    Symbol (hier 16px).
    
    #usercssloader-menu-item {
    	background-image: url("Relativer/Pfad/zum/CSS_Symbol.png");
    	background-position: center;
    	background-repeat: no-repeat;
    	background-size: 16px;
    	border-radius: var(--toolbarbutton-border-radius);
    	margin-block: 3px;
    
    	&:hover {
    		background-color: var(--toolbarbutton-hover-background);
    	}
    
    	& #usercssloader-menu > .menu-text[value="CSS"] {
    		opacity: 0;
    		width: calc(2 * var(--toolbarbutton-inner-padding) + 16px);
    		height: calc(2 * var(--toolbarbutton-inner-padding) + 16px);
    	}
    }
    
    **** Ende der Anleitung ****/
    
    (function(){
    
    /***** Konfiguration *****/
    /* Position: als frei verschiebbare-Schaltfläche = 0, als Menü anzeigen = 1 */
    let position = 0;//1
    /* Dateimanager festlegen, Beispiele:
     *    let fileManager = "C:\\Programme\\FreeCommanderXE\\FreeCommander.exe";
     *    let fileManager = "C:\\Programme\\totalcmd\\TOTALCMD.EXE";
     * auch möglich (Achtung, nur mit fileManagerParam = "/select,"!):
     *    let fileManager = "C:\\Windows\\explorer.exe";
     * Bleibt Parameter leer, wird Standardmanager des Systems ohne Parameter
     * verwendet mit leicht eingeschränkter Funktionalität. */
    let fileManager = "";
    /* eventuelle Parameter für den Dateimanager, Beispiele:
     *    let fileManagerParam = "/T";//FreeCommander oder Totalcommander
     *    let fileManagerParam = "/select,";//Windows Explorer, mit Komma korrekt!
     */
    let fileManagerParam = "";
    /* manche Manager benötigen den Parameter nach der Pfadangabe,
       dann "fileManagerParamPost" auf true setzen */
    let fileManagerParamPost = false;
    /* eigener Texteditor mit Pfad - Standard leer, dann wird Wert aus
     * Einstellung "view_source.editor.path" verwendet mit Warnmeldung,
     * wenn auch dieser leer ist, Beispiel:
     *    let customEditor = "C:\\Windows\\System32\\notepad.exe"; */
    let customEditor = "";
    /* Unterordner für die CSS-Dateien */
    let cssFolder = "CSS";
    /* Menüeintrag zum Bearbeiten der userChrome.css anzeigen (true)
       oder verstecken (false) */
    let showUserChromeCSS = true;
    /* Menüeintrag zum Bearbeiten der userContent.css anzeigen (true)
       oder verstecken (false) */
    let showUserContentCSS = true;
    /* zusätzlich Chrome-Ordner im Untermenü anzeigen (true)
       oder verstecken (false) */
    let showChrome = true;
    /***** Ende der Konfiguration *****/
    
    // Wenn beim Start ein weiteres Fenster (zweites Fenster) vorhanden ist, beenden
    let list = Services.wm.getEnumerator("navigator:browser");
    while(list.hasMoreElements()){ if(list.getNext() != window) return; }
    
    if (window.UCL) {
    	window.UCL.destroy();
    	delete window.UCL;
    }
    
    let menutooltip = "Linksklick: an/aus, Menü schließt\nMittelklick: an/aus, Menü bleibt offen\nRechtsklick: bearbeiten";
    if (fileManager !== "") {
    		menutooltip = menutooltip + "\nStrg+Rechtsklick: im Dateimanager anzeigen";
    }
    
    window.UCL = {
    	AGENT_SHEET : Ci.nsIStyleSheetService.AGENT_SHEET,
    	USER_SHEET  : Ci.nsIStyleSheetService.USER_SHEET,
    	AUTHOR_SHEET: Ci.nsIStyleSheetService.AUTHOR_SHEET,
    	readCSS: {},
    	get disabled_list() {
    		let obj = [];
    		try {
    			obj = decodeURIComponent(this.prefs.getCharPref("disabled_list")).split("|");
    		} catch(e) {}
    		delete this.disabled_list;
    		return this.disabled_list = obj;
    	},
    	get prefs() {
    		delete this.prefs;
    		return this.prefs = Services.prefs.getBranch("UserCSSLoader.");
    	},
    	get styleSheetServices() {
    		delete this.styleSheetServices;
    		return this.styleSheetServices = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
    	},
    	get FOLDER() {
    		let aFolder;
    		try {
    			// UserCSSLoader.FOLDER verwenden
    			let folderPath = this.prefs.getCharPref("FOLDER");
    			aFolder = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
    			aFolder.initWithPath(folderPath);
    		} catch (e) {
    			aFolder = Services.dirsvc.get("UChrm", Ci.nsIFile);
    			aFolder.appendRelativePath(cssFolder);
    		}
    		if (!aFolder.exists() || !aFolder.isDirectory()) {
    			aFolder.create(Ci.nsIFile.DIRECTORY_TYPE, 0o664);
    		}
    		delete this.FOLDER;
    		return this.FOLDER = aFolder;
    	},
    	get CHRMFOLDER() {
    			let cFolder;
    			try {
    					// UserCSSLoader.CHRMFOLDER verwenden
    					let CHRMfolderPath = this.prefs.getCharPref("CHRMFOLDER");
    					cFolder = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
    					cFolder.initWithPath(CHRMfolderPath);
    			} catch (e) {
    					cFolder = Services.dirsvc.get("UChrm", Ci.nsIFile);
    			}
    			if (!cFolder.exists() || !cFolder.isDirectory()) {
    					cFolder.create(Ci.nsIFile.DIRECTORY_TYPE, 0o664);
    			}
    			delete this.CHRMFOLDER;
    			return this.CHRMFOLDER = cFolder;
    	},
    
    	init: function() {
    		const cssmenu = $C("menu", {
    			id: "usercssloader-menu",
    			label: "CSS",
    			tooltiptext: "UserCSSLoader\n\nLinksklick: Stylesheets anzeigen\nMittelklick: Styles importieren",
    			accesskey: "Y"
    		});
    		cssmenu.addEventListener("click", (event) => { if (event.button === 1) UCL.rebuild(); });
    		const menupopup = $C("menupopup", {
    			id: "usercssloader-menupopup"
    		});
    		cssmenu.appendChild(menupopup);
    
    		let menu = $C("menu", {
    			label: "Style-Loader-Menü",
    			id: "style-loader-menu",
    			accesskey: "S",
    			//acceltext: "S"
    		});
    		menupopup.appendChild(menu);
    		menupopup.appendChild($C("menuseparator"));
    
    		let mp = $C("menupopup", { id: "usercssloader-submenupopup" });
    		menu.appendChild(mp);
    		let rebuildItem = $C("menuitem", {
    			label: "Styles importieren",
    			accesskey: "I",
    			//acceltext: "I"
    		});
    		rebuildItem.addEventListener("command", () => UCL.rebuild());
    		mp.appendChild(rebuildItem);
    		mp.appendChild($C("menuseparator"));
    		//
    		let createCSS = $C("menuitem", {
    			label: "CSS-Datei erstellen",
    			accesskey: "D",
    			//acceltext: "D"
    		});
    		createCSS.addEventListener("command", () => UCL.create());
    		mp.appendChild(createCSS);
    		let openFolder = $C("menuitem", {
    			label: "CSS-Ordner öffnen",
    			accesskey: "O",
    			//acceltext: "O"
    		});
    		openFolder.addEventListener("command", () => UCL.openCSSFolder());
    		mp.appendChild(openFolder);
    		if (showChrome) {
    				let openChromeFolder = $C("menuitem", {
    					label: "Chrome-Ordner öffnen",
    					accesskey: "X",
    					//acceltext: "X"
    				});
    				openChromeFolder.addEventListener("command", () => UCL.openCHRMFolder());
    				mp.appendChild(openChromeFolder);
    		}
    		if (showUserChromeCSS || showUserContentCSS)// wenigstens eine der beiden Variablen muss …
    				mp.appendChild($C('menuseparator'));// … true sein, damit Trennlinie angezeigt wird
    		if (showUserChromeCSS) {
    				let editChromeItem = $C("menuitem", {
    					label: "userChrome.css bearbeiten"
    				});
    				editChromeItem.addEventListener("command", () => UCL.editUserCSS("userChrome.css"));
    				mp.appendChild(editChromeItem);
    		}
    		if (showUserContentCSS) {
    				let editContentItem = $C("menuitem", {
    					label: "userContent.css bearbeiten"
    				});
    				editContentItem.addEventListener("command", () => UCL.editUserCSS("userContent.css"));
    				mp.appendChild(editContentItem);
    		}
    
    		CustomizableUI.createWidget({
    			id: 'usercssloader-menu-item',
    			type: 'custom',
    			defaultArea: CustomizableUI.AREA_NAVBAR,
    			onBuild: function(aDocument) {
    				let toolbaritem = aDocument.createXULElement('toolbaritem');
    				toolbaritem.id = 'usercssloader-menu-item';
    				toolbaritem.className = 'chromeclass-toolbar-additional';
    				return toolbaritem;
    			}
    		});
    		$('usercssloader-menu-item').appendChild(cssmenu);
    
    		if (position === 1) {
    				let refNode = $('helpMenu');
    				refNode.parentNode.insertBefore(cssmenu, refNode.nextSibling);
    		}
    
    		// Stile neu laden, ohne Menü zu öffnen
    		let key = $C("key", {
    			id: "usercssloader-rebuild-key",
    			key: "R",
    			modifiers: "alt",
    		});
    		key.addEventListener("command", () => UCL.rebuild());
    		$("mainKeyset").appendChild(key);
    
    		this.rebuild();
    		this.initialized = true;
    		window.addEventListener("unload", this, false);
    	},
    	uninit: function() {
    		const dis = [];
    		for (let x of Object.keys(this.readCSS)) {
    			if (!this.readCSS[x].enabled)
    				dis.push(x);
    		}
    		this.prefs.setCharPref("disabled_list", encodeURIComponent(dis.join("|")));
    		window.removeEventListener("unload", this, false);
    	},
    	destroy: function() {
    		var i = document.getElementById("usercssloader-menu");
    		if (i) i.parentNode.removeChild(i);
    		var i = document.getElementById("usercssloader-rebuild-key");
    		if (i) i.parentNode.removeChild(i);
    		this.uninit();
    	},
    	handleEvent: function(event) {
    		switch(event.type){
    			case "unload": this.uninit(); break;
    		}
    	},
    	rebuild: function() {
    		let ext = /\.css$/i;
    		let not = /\.uc\.css/i;
    		let files = this.FOLDER.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);
    
    		while (files.hasMoreElements()) {
    			let file = files.getNext().QueryInterface(Ci.nsIFile);
    			if (!ext.test(file.leafName) || not.test(file.leafName)) continue;
    			let CSS = this.loadCSS(file);
    			CSS.flag = true;
    		}
    		for (let leafName of Object.keys(this.readCSS)) {
    			const CSS = this.readCSS[leafName];
    			if (!CSS.flag) {
    				CSS.enabled = false;
    				delete this.readCSS[leafName];
    			}
    			delete CSS.flag;
    			this.rebuildMenu(leafName);
    		}
    		if (this.initialized) {
    			if (typeof(StatusPanel) !== "undefined")
    				StatusPanel._label = "Styles importiert";
    			else
    				XULBrowserWindow.statusTextField.label = "Styles importiert";
    		}
    	},
    	loadCSS: function(aFile) {
    		let CSS = this.readCSS[aFile.leafName];
    		if (!CSS) {
    			CSS = this.readCSS[aFile.leafName] = new CSSEntry(aFile);
    			if (this.disabled_list.indexOf(CSS.leafName) === -1) {
    				CSS.enabled = true;
    			}
    		} else if (CSS.enabled) {
    			CSS.enabled = true;
    		}
    		return CSS;
    	},
    	rebuildMenu: function(aLeafName) {
    		let CSS = this.readCSS[aLeafName];
    		let menuitem = document.getElementById("usercssloader-" + aLeafName);
    		if (!CSS) {
    			if (menuitem)
    				menuitem.parentNode.removeChild(menuitem);
    			return;
    		}
    
    		if (!menuitem) {
    			menuitem = $C("menuitem", {
    				label: aLeafName,
    				id: "usercssloader-" + aLeafName,
    				class: "usercssloader-item " + (CSS.SHEET == this.AGENT_SHEET? "AGENT_SHEET" : CSS.SHEET == this.AUTHOR_SHEET? "AUTHOR_SHEET": "USER_SHEET"),
    				type: "checkbox",
    				autocheck: "false",
    				tooltiptext: menutooltip
    			});
    			menuitem.addEventListener("command", () => UCL.toggle(aLeafName));
    			menuitem.addEventListener("click", (event) => UCL.itemClick(event));
    			menuitem.addEventListener("mouseup", (event) => { if (event.button === 1) event.preventDefault(); });
    			document.getElementById("usercssloader-menupopup").appendChild(menuitem);
    		}
    		menuitem.setAttribute("checked", CSS.enabled);
    	},
    	toggle: function(aLeafName) {
    		let CSS = this.readCSS[aLeafName];
    		if (!CSS || event.ctrlKey) return;
    		CSS.enabled = !CSS.enabled;
    		this.rebuildMenu(aLeafName);
    	},
    	itemClick: function(event) {
    		let label = event.currentTarget.getAttribute("label");
    		event.preventDefault();
    		event.stopPropagation();
    		if (event.button === 0) {
    				return;
    		} else if (event.button === 1) {
    				this.toggle(label);
    		} else if (event.button === 2) {
    				if (event.ctrlKey && fileManager  !== "") {
    						UCL.showFile(label);
    				} else {
    				closeMenus(event.target);
    				this.edit(this.getFileFromLeafName(label));
    				}
    		}
    	},
    	getFileFromLeafName: function(aLeafName) {
    		let f = this.FOLDER.clone();
    		f.QueryInterface(Ci.nsIFile); // use appendRelativePath
    		f.appendRelativePath(aLeafName);
    		return f;
    	},
    	showFile: function(fname) {
    				const PathSep = AppConstants.platform === "win" ? "\\" : "/";
    				let target= this.FOLDER.path + PathSep + fname;
    				let file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
    				let process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess);
    				let args = (!fileManagerParamPost) ? [fileManagerParam,target] :
    				           [target,fileManagerParam];
    				file.initWithPath(fileManager);
    				process.init(file);
    				// Verzeichnis mit anderem Dateimanager öffnen
    				process.run(false, args, args.length);
    	},
    	openCSSFolder:function(){
    		if (fileManager !== "" && fileManagerParam !== "/select,") {
    				let target = this.FOLDER.path;
    				let file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
    				let process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess);
    				let args = (!fileManagerParamPost) ? [fileManagerParam,target] :
    				           [target,fileManagerParam];
    				file.initWithPath(fileManager);
    				process.init(file);
    				// Verzeichnis mit anderem Dateimanager öffnen
    				process.run(false, args, args.length);
    		} else {
    				// Verzeichnis mit Dateimanager des Systems öffnen
    				this.FOLDER.launch();
    		}
    	},
    	openCHRMFolder:function(){
    		if (fileManager !== "" && fileManagerParam !== "/select,") {
    				let target = this.CHRMFOLDER.path;
    				let file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
    				let process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess);
    				let args = (!fileManagerParamPost) ? [fileManagerParam,target] :
    				           [target,fileManagerParam];
    				file.initWithPath(fileManager);
    				process.init(file);
    				// Verzeichnis mit anderem Dateimanager öffnen
    				process.run(false, args, args.length);
    		} else {
    				// Verzeichnis mit Dateimanager des Systems öffnen
    				this.CHRMFOLDER.launch();
    		}
    	},
    	editUserCSS: function(aLeafName) {
    		let file = Services.dirsvc.get("UChrm", Ci.nsIFile);
    		file.appendRelativePath(aLeafName);
    		this.edit(file);
    	},
    	edit: function(aFile) {
    		let editor = (customEditor !== "") ? customEditor : Services.prefs.getCharPref("view_source.editor.path");
    		if (!editor) return alert('In der Konfiguration einen Texteditor festlegen ("customEditor") oder\n unter about:config im vorhandenen Schalter "view_source.editor.path"\n den vollständigen Editorpfad eintragen.');
    		try {
    			let UI = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
    			UI.charset = window.navigator.platform.toLowerCase().indexOf("win") >= 0? "Shift_JIS": "UTF-8";
    			let path = UI.ConvertFromUnicode(aFile.path);
    			let app = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
    			app.initWithPath(editor);
    			let process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
    			process.init(app);
    			process.run(false, [path], 1);
    		} catch (e) {}
    	},
    	create: function(aLeafName) {
    		if (!aLeafName) aLeafName = prompt("Name des Styles", dateFormat(new Date(), "%Y_%m%d_%H%M%S"));
    		if (aLeafName) aLeafName = aLeafName.replace(/\s+/g, " ").replace(/[\\/:*?\"<>|]/g, "");
    		if (!aLeafName || !/\S/.test(aLeafName)) return;
    		if (!/\.css$/.test(aLeafName)) aLeafName += ".css";
    		let file = this.getFileFromLeafName(aLeafName);
    		this.edit(file);
    	},
    	UCrebuild: function() {
    		let re = /^file:.*\.uc\.css(?:\?\d+)?$/i;
    		let query = "?" + new Date().getTime();
    		Array.slice(document.styleSheets).forEach(function(css){
    			if (!re.test(css.href)) return;
    			if (css.ownerNode) {
    				css.ownerNode.parentNode.removeChild(css.ownerNode);
    			}
    			let pi = document.createProcessingInstruction('xml-stylesheet','type="text/css" href="'+ css.href.replace(/\?.*/, '') + query +'"');
    			document.insertBefore(pi, document.documentElement);
    		});
    		UCL.UCcreateMenuitem();
    	},
    	UCcreateMenuitem: function() {
    		let sep = $("usercssloader-ucseparator");
    		let popup = sep.parentNode;
    		if (sep.nextSibling) {
    			let range = document.createRange();
    			range.setStartAfter(sep);
    			range.setEndAfter(popup.lastChild);
    			range.deleteContents();
    			range.detach();
    		}
    
    		let re = /^file:.*\.uc\.css(?:\?\d+)?$/i;
    		Array.slice(document.styleSheets).forEach(function(css) {
    			if (!re.test(css.href)) return;
    			let fileURL = decodeURIComponent(css.href).split("?")[0];
    			let aLeafName = fileURL.split("/").pop();
    			let m = $C("menuitem", {
    				label: aLeafName,
    				tooltiptext: fileURL,
    				id: "usercssloader-" + aLeafName,
    				type: "checkbox",
    				autocheck: "false",
    				checked: "true",
    			});
    			m.css = css;
    			m.addEventListener("command", function() {
    				if (!event.ctrlKey) {this.setAttribute("checked", !(this.css.disabled = !this.css.disabled));}
    			});
    			m.addEventListener("mouseup", function(event) {
    				if (event.button === 1) event.preventDefault();
    			});
    			m.addEventListener("click", function(event) {
    				UCL.UCItemClick(event);
    			});
    			popup.appendChild(m);
    		});
    	},
    	UCItemClick: function(event) {
    		if (event.button === 0) return;
    		event.preventDefault();
    		event.stopPropagation();
    
    		if (event.button === 1) {
    			event.target.doCommand();
    		}
    		else if (event.button === 2) {
    			closeMenus(event.target);
    			let fileURL = event.currentTarget.getAttribute("tooltiptext");
    			let file = Services.io.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler).getFileFromURLSpec(fileURL);
    			this.edit(file);
    		}
    	},
    };
    
    function CSSEntry(aFile) {
    	this.path = aFile.path;
    	this.leafName = aFile.leafName;
    	this.lastModifiedTime = 1;
    	this.SHEET = /^xul-|\.as\.css$/i.test(this.leafName) ?
    		Ci.nsIStyleSheetService.AGENT_SHEET:
    		/\.author\.css$/i.test(this.leafName)?
    			Ci.nsIStyleSheetService.AUTHOR_SHEET:
    			Ci.nsIStyleSheetService.USER_SHEET;
    }
    CSSEntry.prototype = {
    	sss: Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService),
    	_enabled: false,
    	get enabled() {
    		return this._enabled;
    	},
    	set enabled(isEnable) {
    		let aFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile)
    		aFile.initWithPath(this.path);
    
    		let isExists = aFile.exists(); // true, wenn die Datei bereits existiert
    		let lastModifiedTime = isExists ? aFile.lastModifiedTime : 0;
    		let isForced = this.lastModifiedTime != lastModifiedTime; //true, wenn es eine Änderung in der Datei gibt
    
    		let fileURL = Services.io.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler).getURLSpecFromActualFile(aFile);
    		let uri = Services.io.newURI(fileURL, null, null);
    
    		if (this.sss.sheetRegistered(uri, this.SHEET)) {
    			// Wenn diese Datei bereits gelesen wurde
    			if (!isEnable || !isExists) {
    				this.sss.unregisterSheet(uri, this.SHEET);
    			}
    			else if (isForced) {
    				// Nach Stornierung erneut einlesen
    				this.sss.unregisterSheet(uri, this.SHEET);
    				this.sss.loadAndRegisterSheet(uri, this.SHEET);
    			}
    		} else {
    			// Datei wurde nicht gelesen
    			if (isEnable && isExists) {
    				this.sss.loadAndRegisterSheet(uri, this.SHEET);
    			}
    		}
    		if (this.lastModifiedTime !== 1 && isEnable && isForced) {
    			log(this.leafName + " wurde aktualisiert");
    		}
    		this.lastModifiedTime = lastModifiedTime;
    		return this._enabled = isEnable;
    	},
    };
    
    UCL.init();
    
    function $(id) { return document.getElementById(id); }
    function $A(arr) { return Array.slice(arr); }
    function $C(name, attr) {
    	const el = document.createXULElement(name);
    	if (attr) Object.keys(attr).forEach(function(n) { el.setAttribute(n, attr[n]) });
    	return el;
    }
    function dateFormat(date, format) {
    	format = format.replace("%Y", ("000" + date.getFullYear()).substr(-4));
    	format = format.replace("%m", ("0" + (date.getMonth()+1)).substr(-2));
    	format = format.replace("%d", ("0" + date.getDate()).substr(-2));
    	format = format.replace("%H", ("0" + date.getHours()).substr(-2));
    	format = format.replace("%M", ("0" + date.getMinutes()).substr(-2));
    	format = format.replace("%S", ("0" + date.getSeconds()).substr(-2));
    	return format;
    }
    
    function log(mes) { console.log(mes); }
    })();
    Alles anzeigen
  • UserCSSLoader (2025)

    • Speravir
    • 14. September 2025 um 01:02
    Zitat von Boersenfeger

    Allerdings ist da der Abstand zum linken und rechten Icon größer als bei den anderen in meiner Statuszeile. Vielleicht kann man ja noch da etwas ändern!?

    Ausgehend von Deinem zuvor geposteten Stil würde ich als Erstes das hier versuchen:

    Code
    #usercssloader-menu-item #usercssloader-menu > .menu-text[value="CSS"] {
    	opacity: 0;
    	width: calc(2 * var(--toolbarbutton-inner-padding) + 20px);
    	height: calc(2 * var(--toolbarbutton-inner-padding) + 20px);
    }

    Dort ist jeweils der Wert von 24px zu 20px geändert.

    Zitat von 2002Andreas

    Was mir aber gar nicht gefällt, bei hover passt der Hintergrund nicht:

    […]

    CSS
    margin-top: 5px !important;
    margin-bottom: 5px !important;

    die beiden unteren Werte sind neu eingefügt.

    Bei der Höhe meiner Leiste ist mir das überhaupt nicht aufgefallen.

    Kannst du bitte das mal austesten:

    CSS
    #usercssloader-menu-item {
    	height: var(--button-min-height);
    }

    Und, wenn das zu groß ist, als nächstes var(--button-min-height-small)? Ich hab noch nicht herausgefunden, wo die Unterscheidung stattfindet, wann welche Variable aktiviert wird.

    Zitat von 2002Andreas

    Und hier der Radius-Wert

    Hmm, stiimmt. Ist mir auch nicht aufgefallen. Aber warum nur bei Hover? Und es gibt eine Variable dafür, also gleich mal mittesten:

    CSS
    #usercssloader-menu-item {
    	border-radius: var(--toolbarbutton-border-radius);
    }

    Dann würde ich das alles noch in die Anleitung einfügen.

  • UserCSSLoader (2025)

    • Speravir
    • 13. September 2025 um 01:02
    Zitat von Boersenfeger

    in Zeile 404 if (fileManager !== "") {

    […]

    So sieht diese Zeile bei mir in der vorherigen Version aus if (fileManager.length !== 0) {

    Ist dies eine bewusste Änderung oder ein Kopierfehler oder ähnliches?

    Sören hat das Entscheidende schon gesagt. Der Hintergrund ist, dass ich dachte, den Code dahingehend zu vereinheitlichen und die gewählte Variante etwas kürzer und für mich auch etwas besser verständlich ist (und als ich diese eingeführt habe, war mir gar nicht bewusst, dass die andere bereits verwendet wurde).

    Zur Nachfrage, Börsi, hattest Du meine Hinweise zur Kürzung Deines CSS-Stils in Beitrag #63 bemerkt und waren diese nachvollziehbar? Oder bist du sogar auf die kürzere Version, wie jetzt im Skript beschrieben, umgestiegen?

  • UserCSSLoader (2025)

    • Speravir
    • 12. September 2025 um 01:44

    Leute, Leute, kaum ist man mal ein paar Tage nicht anwesend, kommt man hier nicht mehr mit.

    Unten folgt das hoffentlich letzte Update, bevor Endor es bei sich hochladen kann.

    Ich habe erstens

    JavaScript
    const PathSep = AppConstants.platform === "win" ? "\\" : "/";
    				let target= this.FOLDER.path + PathSep + fname;

    wieder eingefügt. Meine Aussage

    Zitat von Speravir

    Dann müsste ich aber auch

    ChromeUtils.importESModule("resource://gre/modules/AppConstants.sys.mjs");

    wieder einführen

    stimmt übrigens nicht, wie Bege uns mit seiner letzten Skriptversion zeigte und ich dann in der Konsole ausprobierte. Ich meine, es war einmal anders, aber egal.

    Zweitens habe ich das hier geändert:

    Zitat von bege

    Wobei die Änderung von openFolder zu openFile nicht ganz passt. Die CSS-Dateien werden nicht geöffnet, sondern nur im Dateimanager im Order angezeigt. Geöffnet wird also tatsächlich nur der Ordner.

    Heißt jetzt showFile.

    Sonst habe ich am Code nichts geändert und damit auch das nicht entfernt, was ich als Backup-Funktion bezeichnet habe. In dem Zusammenhang: Wenn ich explizit den Windows-Explorer (beziehungsweise File-Explorer, wie es in Win11 heißt) samt Parameter auswähle, funktioniert es hier mit der jüngsten Version.

    Alles andere sind Änderungen am kommentierten Teil zu Beginn des Skripts:

    Ich hab den alten Header entfernt, dafür eine kürzere Angabe zur Urheberschaft eingefügt (bewusst in Englisch). Und dann gibt es Änderungen an Bedienungsanleitung und Konfigurationserläuterungen. Ob der erste Absatz der Bedienungsanleitung noch auf dem aktuellen Stand ist, dessen bin ich mir unsicher.

    JavaScript
    /* UserCSSLoader
     * original author: Griever -
     * https://github.com/Griever/userChromeJS/tree/master/UserCSSLoader
     *
     * Enhancements and several other changes including German translation
     * and configuration section by users aborix, Endor, bege, Speravir of
     * Camp Firefox forum - https://www.camp-firefox.de/forum/ - latest version:
     * https://www.camp-firefox.de/forum/thema/138814/?postID=1278991#post1278991
     */
    
    /****** Bedienungsanleitung ******
    
    CSS-Ordner im Chrome-Ordner erstellen, CSS-Dateien dort ablegen - speichern.
    Diejenigen, deren Dateiname mit "xul-" beginnen, diejenigen, die mit ".as.css"
    enden, sind AGENT_SHEET, alle anderen außer USER_SHEET werden gelesen. Da der
    Inhalt der Datei nicht überprüft wird, darauf achten, die Angabe von @namespace
    nicht zu vergessen!
    
    Schaltfläche oder Menü wird in Navigationsleiste eingefügt (einstellbar, siehe
    Variable "position" in unten anschließender Konfiguration).
    
    Dateiordner, Dateimanager und Texteditor können in der unten anschließenden
    Konfiguration geändert werden. Die Verwendung des in "view_source.editor.path"
    angegebenen Editors ist möglich.
    
    Linksklick auf Stil, zum Aktivieren/Deaktivieren
    Mittelklick auf Stil zum Aktivieren/Deaktivieren, ohne Menü zu schließen
    Rechtsklick auf Stil zum Öffnen im Editor
    Strg+Linksklick zum Anzeigen im Dateimanager
    
    Die Tastenkombinationen können im Menü eingeblendet werden, dazu nach 
    "acceltext" suchen und den Zeilenkommentar "//" entfernen.
    
    Ein Symbol für die Schaltfläche muss in der "userChrome.css" festgelegt werden,
    Pfad zum Bild (PNG nur als Beispiel):
    * relativ zur userChrome.css
        background-image: url("Relativer/Pfad/zum/CSS_Symbol.png");
    * eine absolute Pfadangabe zum Symbol muss mit File-Protokoll-Präfix erfolgen:
        background-image: url("file:///Absoluter/Pfad/zum/CSS_Symbol.png");
    
    #usercssloader-menu-item {
    	background-image: url("Relativer/Pfad/zum/CSS_Symbol.png");
    	background-position: center;
    	background-repeat: no-repeat;
    	background-size: 16px;
    
    	&:hover {
    		background-color: var(--toolbarbutton-hover-background);
    	}
    
    	& #usercssloader-menu > .menu-text[value="CSS"] {
    		opacity: 0;
    		width: calc(2 * var(--toolbarbutton-inner-padding) + 16px);
    		height: calc(2 * var(--toolbarbutton-inner-padding) + 16px);
    	}
    }
    
    **** Ende der Anleitung ****/
    
    (function(){
    
    /***** Konfiguration *****/
    /* Position: als frei verschiebbare-Schaltfläche = 0, als Menü anzeigen = 1 */
    let position = 0;//1
    /* Dateimanager festlegen, Beispiele:
     *    let fileManager = "C:\\Programme\\FreeCommanderXE\\FreeCommander.exe";
     *    let fileManager = "C:\\Programme\\totalcmd\\TOTALCMD.EXE";
     * auch möglich:
     *    let fileManager = "C:\\Windows\\explorer.exe";
     * Bleibt Parameter leer, wird Standardmanager des Systems ohne Parameter
     * verwendet mit leicht eingeschränkter Funktionalität. */
    let fileManager = "";
    /* eventuelle Parameter für den Dateimanager, Beispiele:
     *    let fileManagerParam = "/T";//FreeCommander oder Totalcommander
     *    let fileManagerParam = "/select,";//Windows Explorer, mit Komma korrekt!
     */
    let fileManagerParam = "";
    /* manche Manager benötigen den Parameter nach der Pfadangabe,
       dann "fileManagerParamPost" auf true setzen */
    let fileManagerParamPost = false;
    /* eigener Texteditor mit Pfad - Standard leer, dann wird Wert aus
     * Einstellung "view_source.editor.path" verwendet mit Warnmeldung,
     * wenn auch dieser leer ist, Beispiel:
     *    let customEditor = "C:\\Windows\\System32\\notepad.exe"; */
    let customEditor = "";
    /* Unterordner für die CSS-Dateien */
    let cssFolder = "CSS";
    /* Menüeintrag zum Bearbeiten der userChrome.css anzeigen (true)
       oder verstecken (false) */
    let showUserChromeCSS = true;
    /* Menüeintrag zum Bearbeiten der userContent.css anzeigen (true)
       oder verstecken (false) */
    let showUserContentCSS = true;
    /* zusätzlich Chrome-Ordner im Untermenü anzeigen (true)
       oder verstecken (false) */
    let showChrome = true;
    /***** Ende der Konfiguration *****/
    
    // Wenn beim Start ein weiteres Fenster (zweites Fenster) vorhanden ist, beenden
    let list = Services.wm.getEnumerator("navigator:browser");
    while(list.hasMoreElements()){ if(list.getNext() != window) return; }
    
    if (window.UCL) {
    	window.UCL.destroy();
    	delete window.UCL;
    }
    
    let menutooltip = "Linksklick: an/aus, Menü schließt\nMittelklick: an/aus, Menü bleibt offen\nRechtsklick: bearbeiten";
    if (fileManager !== "") {
    		menutooltip = menutooltip + "\nStrg+Rechtsklick: im Dateimanager anzeigen";
    }
    
    window.UCL = {
    	AGENT_SHEET : Ci.nsIStyleSheetService.AGENT_SHEET,
    	USER_SHEET  : Ci.nsIStyleSheetService.USER_SHEET,
    	AUTHOR_SHEET: Ci.nsIStyleSheetService.AUTHOR_SHEET,
    	readCSS: {},
    	get disabled_list() {
    		let obj = [];
    		try {
    			obj = decodeURIComponent(this.prefs.getCharPref("disabled_list")).split("|");
    		} catch(e) {}
    		delete this.disabled_list;
    		return this.disabled_list = obj;
    	},
    	get prefs() {
    		delete this.prefs;
    		return this.prefs = Services.prefs.getBranch("UserCSSLoader.");
    	},
    	get styleSheetServices() {
    		delete this.styleSheetServices;
    		return this.styleSheetServices = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
    	},
    	get FOLDER() {
    		let aFolder;
    		try {
    			// UserCSSLoader.FOLDER verwenden
    			let folderPath = this.prefs.getCharPref("FOLDER");
    			aFolder = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
    			aFolder.initWithPath(folderPath);
    		} catch (e) {
    			aFolder = Services.dirsvc.get("UChrm", Ci.nsIFile);
    			aFolder.appendRelativePath(cssFolder);
    		}
    		if (!aFolder.exists() || !aFolder.isDirectory()) {
    			aFolder.create(Ci.nsIFile.DIRECTORY_TYPE, 0o664);
    		}
    		delete this.FOLDER;
    		return this.FOLDER = aFolder;
    	},
    	get CHRMFOLDER() {
    			let cFolder;
    			try {
    					// UserCSSLoader.CHRMFOLDER verwenden
    					let CHRMfolderPath = this.prefs.getCharPref("CHRMFOLDER");
    					cFolder = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
    					cFolder.initWithPath(CHRMfolderPath);
    			} catch (e) {
    					cFolder = Services.dirsvc.get("UChrm", Ci.nsIFile);
    			}
    			if (!cFolder.exists() || !cFolder.isDirectory()) {
    					cFolder.create(Ci.nsIFile.DIRECTORY_TYPE, 0o664);
    			}
    			delete this.CHRMFOLDER;
    			return this.CHRMFOLDER = cFolder;
    	},
    
    	init: function() {
    		const cssmenu = $C("menu", {
    			id: "usercssloader-menu",
    			label: "CSS",
    			tooltiptext: "UserCSSLoader\n\nLinksklick: Stylesheets anzeigen\nMittelklick: Styles importieren",
    			accesskey: "Y"
    		});
    		cssmenu.addEventListener("click", (event) => { if (event.button === 1) UCL.rebuild(); });
    		const menupopup = $C("menupopup", {
    			id: "usercssloader-menupopup"
    		});
    		cssmenu.appendChild(menupopup);
    
    		let menu = $C("menu", {
    			label: "Style-Loader-Menü",
    			id: "style-loader-menu",
    			accesskey: "S",
    			//acceltext: "S"
    		});
    		menupopup.appendChild(menu);
    		menupopup.appendChild($C("menuseparator"));
    
    		let mp = $C("menupopup", { id: "usercssloader-submenupopup" });
    		menu.appendChild(mp);
    		let rebuildItem = $C("menuitem", {
    			label: "Styles importieren",
    			accesskey: "I",
    			//acceltext: "I"
    		});
    		rebuildItem.addEventListener("command", () => UCL.rebuild());
    		mp.appendChild(rebuildItem);
    		mp.appendChild($C("menuseparator"));
    		//
    		let createCSS = $C("menuitem", {
    			label: "CSS-Datei erstellen",
    			accesskey: "D",
    			//acceltext: "D"
    		});
    		createCSS.addEventListener("command", () => UCL.create());
    		mp.appendChild(createCSS);
    		let openFolder = $C("menuitem", {
    			label: "CSS-Ordner öffnen",
    			accesskey: "O",
    			//acceltext: "O"
    		});
    		openFolder.addEventListener("command", () => UCL.openCSSFolder());
    		mp.appendChild(openFolder);
    		if (showChrome) {
    				let openChromeFolder = $C("menuitem", {
    					label: "Chrome-Ordner öffnen",
    					accesskey: "X",
    					//acceltext: "X"
    				});
    				openChromeFolder.addEventListener("command", () => UCL.openCHRMFolder());
    				mp.appendChild(openChromeFolder);
    		}
    		if (showUserChromeCSS || showUserContentCSS)// wenigstens eine der beiden Variablen muss …
    				mp.appendChild($C('menuseparator'));// … true sein, damit Trennlinie angezeigt wird
    		if (showUserChromeCSS) {
    				let editChromeItem = $C("menuitem", {
    					label: "userChrome.css bearbeiten"
    				});
    				editChromeItem.addEventListener("command", () => UCL.editUserCSS("userChrome.css"));
    				mp.appendChild(editChromeItem);
    		}
    		if (showUserContentCSS) {
    				let editContentItem = $C("menuitem", {
    					label: "userContent.css bearbeiten"
    				});
    				editContentItem.addEventListener("command", () => UCL.editUserCSS("userContent.css"));
    				mp.appendChild(editContentItem);
    		}
    
    		CustomizableUI.createWidget({
    			id: 'usercssloader-menu-item',
    			type: 'custom',
    			defaultArea: CustomizableUI.AREA_NAVBAR,
    			onBuild: function(aDocument) {
    				let toolbaritem = aDocument.createXULElement('toolbaritem');
    				toolbaritem.id = 'usercssloader-menu-item';
    				toolbaritem.className = 'chromeclass-toolbar-additional';
    				return toolbaritem;
    			}
    		});
    		$('usercssloader-menu-item').appendChild(cssmenu);
    
    		if (position === 1) {
    				let refNode = $('helpMenu');
    				refNode.parentNode.insertBefore(cssmenu, refNode.nextSibling);
    		}
    
    		// Stile neu laden, ohne Menü zu öffnen
    		let key = $C("key", {
    			id: "usercssloader-rebuild-key",
    			key: "R",
    			modifiers: "alt",
    		});
    		key.addEventListener("command", () => UCL.rebuild());
    		$("mainKeyset").appendChild(key);
    
    		this.rebuild();
    		this.initialized = true;
    		window.addEventListener("unload", this, false);
    	},
    	uninit: function() {
    		const dis = [];
    		for (let x of Object.keys(this.readCSS)) {
    			if (!this.readCSS[x].enabled)
    				dis.push(x);
    		}
    		this.prefs.setCharPref("disabled_list", encodeURIComponent(dis.join("|")));
    		window.removeEventListener("unload", this, false);
    	},
    	destroy: function() {
    		var i = document.getElementById("usercssloader-menu");
    		if (i) i.parentNode.removeChild(i);
    		var i = document.getElementById("usercssloader-rebuild-key");
    		if (i) i.parentNode.removeChild(i);
    		this.uninit();
    	},
    	handleEvent: function(event) {
    		switch(event.type){
    			case "unload": this.uninit(); break;
    		}
    	},
    	rebuild: function() {
    		let ext = /\.css$/i;
    		let not = /\.uc\.css/i;
    		let files = this.FOLDER.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);
    
    		while (files.hasMoreElements()) {
    			let file = files.getNext().QueryInterface(Ci.nsIFile);
    			if (!ext.test(file.leafName) || not.test(file.leafName)) continue;
    			let CSS = this.loadCSS(file);
    			CSS.flag = true;
    		}
    		for (let leafName of Object.keys(this.readCSS)) {
    			const CSS = this.readCSS[leafName];
    			if (!CSS.flag) {
    				CSS.enabled = false;
    				delete this.readCSS[leafName];
    			}
    			delete CSS.flag;
    			this.rebuildMenu(leafName);
    		}
    		if (this.initialized) {
    			if (typeof(StatusPanel) !== "undefined")
    				StatusPanel._label = "Styles importiert";
    			else
    				XULBrowserWindow.statusTextField.label = "Styles importiert";
    		}
    	},
    	loadCSS: function(aFile) {
    		let CSS = this.readCSS[aFile.leafName];
    		if (!CSS) {
    			CSS = this.readCSS[aFile.leafName] = new CSSEntry(aFile);
    			if (this.disabled_list.indexOf(CSS.leafName) === -1) {
    				CSS.enabled = true;
    			}
    		} else if (CSS.enabled) {
    			CSS.enabled = true;
    		}
    		return CSS;
    	},
    	rebuildMenu: function(aLeafName) {
    		let CSS = this.readCSS[aLeafName];
    		let menuitem = document.getElementById("usercssloader-" + aLeafName);
    		if (!CSS) {
    			if (menuitem)
    				menuitem.parentNode.removeChild(menuitem);
    			return;
    		}
    
    		if (!menuitem) {
    			menuitem = $C("menuitem", {
    				label: aLeafName,
    				id: "usercssloader-" + aLeafName,
    				class: "usercssloader-item " + (CSS.SHEET == this.AGENT_SHEET? "AGENT_SHEET" : CSS.SHEET == this.AUTHOR_SHEET? "AUTHOR_SHEET": "USER_SHEET"),
    				type: "checkbox",
    				autocheck: "false",
    				tooltiptext: menutooltip
    			});
    			menuitem.addEventListener("command", () => UCL.toggle(aLeafName));
    			menuitem.addEventListener("click", (event) => UCL.itemClick(event));
    			menuitem.addEventListener("mouseup", (event) => { if (event.button === 1) event.preventDefault(); });
    			document.getElementById("usercssloader-menupopup").appendChild(menuitem);
    		}
    		menuitem.setAttribute("checked", CSS.enabled);
    	},
    	toggle: function(aLeafName) {
    		let CSS = this.readCSS[aLeafName];
    		if (!CSS || event.ctrlKey) return;
    		CSS.enabled = !CSS.enabled;
    		this.rebuildMenu(aLeafName);
    	},
    	itemClick: function(event) {
    		let label = event.currentTarget.getAttribute("label");
    		event.preventDefault();
    		event.stopPropagation();
    		if (event.button === 0) {
    				return;
    		} else if (event.button === 1) {
    				this.toggle(label);
    		} else if (event.button === 2) {
    				if (event.ctrlKey) {
    						UCL.showFile(label);
    				} else {
    				closeMenus(event.target);
    				this.edit(this.getFileFromLeafName(label));
    				}
    		}
    	},
    	getFileFromLeafName: function(aLeafName) {
    		let f = this.FOLDER.clone();
    		f.QueryInterface(Ci.nsIFile); // use appendRelativePath
    		f.appendRelativePath(aLeafName);
    		return f;
    	},
    	showFile: function(fname) {
    		if (fileManager !== "") {
    				const PathSep = AppConstants.platform === "win" ? "\\" : "/";
    				let target= this.FOLDER.path + PathSep + fname;
    				let file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
    				let process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess);
    				let args = (!fileManagerParamPost) ? [fileManagerParam,target] :
    				           [target,fileManagerParam];
    				file.initWithPath(fileManager);
    				process.init(file);
    				// Verzeichnis mit anderem Dateimanager öffnen
    				process.run(false, args, args.length);
    		} else {
    				// Verzeichnis mit Dateimanager des Systems öffnen
    				this.FOLDER.launch();
    		}
    	},
    	openCSSFolder:function(){
    		if (fileManager !== "") {
    				let target = this.FOLDER.path;
    				let file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
    				let process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess);
    				let args = (!fileManagerParamPost) ? [fileManagerParam,target,] :
    				           [target,fileManagerParam];
    				file.initWithPath(fileManager);
    				process.init(file);
    				// Verzeichnis mit anderem Dateimanager öffnen
    				process.run(false, args, args.length);
    		} else {
    				// Verzeichnis mit Dateimanager des Systems öffnen
    				this.FOLDER.launch();
    		}
    	},
    	openCHRMFolder:function(){
    		if (fileManager !== "") {
    				let target = this.CHRMFOLDER.path;
    				let file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
    				let process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess);
    				let args = (!fileManagerParamPost) ? [fileManagerParam,target,] :
    				           [target,fileManagerParam];
    				file.initWithPath(fileManager);
    				process.init(file);
    				// Verzeichnis mit anderem Dateimanager öffnen
    				process.run(false, args, args.length);
    		} else {
    				// Verzeichnis mit Dateimanager des Systems öffnen
    				this.CHRMFOLDER.launch();
    		}
    	},
    	editUserCSS: function(aLeafName) {
    		let file = Services.dirsvc.get("UChrm", Ci.nsIFile);
    		file.appendRelativePath(aLeafName);
    		this.edit(file);
    	},
    	edit: function(aFile) {
    		let editor = (customEditor !== "") ? customEditor : Services.prefs.getCharPref("view_source.editor.path");
    		if (!editor) return alert('In der Konfiguration einen Texteditor festlegen ("customEditor") oder\n unter about:config im vorhandenen Schalter "view_source.editor.path"\n den vollständigen Editorpfad eintragen.');
    		try {
    			let UI = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
    			UI.charset = window.navigator.platform.toLowerCase().indexOf("win") >= 0? "Shift_JIS": "UTF-8";
    			let path = UI.ConvertFromUnicode(aFile.path);
    			let app = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
    			app.initWithPath(editor);
    			let process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
    			process.init(app);
    			process.run(false, [path], 1);
    		} catch (e) {}
    	},
    	create: function(aLeafName) {
    		if (!aLeafName) aLeafName = prompt("Name des Styles", dateFormat(new Date(), "%Y_%m%d_%H%M%S"));
    		if (aLeafName) aLeafName = aLeafName.replace(/\s+/g, " ").replace(/[\\/:*?\"<>|]/g, "");
    		if (!aLeafName || !/\S/.test(aLeafName)) return;
    		if (!/\.css$/.test(aLeafName)) aLeafName += ".css";
    		let file = this.getFileFromLeafName(aLeafName);
    		this.edit(file);
    	},
    	UCrebuild: function() {
    		let re = /^file:.*\.uc\.css(?:\?\d+)?$/i;
    		let query = "?" + new Date().getTime();
    		Array.slice(document.styleSheets).forEach(function(css){
    			if (!re.test(css.href)) return;
    			if (css.ownerNode) {
    				css.ownerNode.parentNode.removeChild(css.ownerNode);
    			}
    			let pi = document.createProcessingInstruction('xml-stylesheet','type="text/css" href="'+ css.href.replace(/\?.*/, '') + query +'"');
    			document.insertBefore(pi, document.documentElement);
    		});
    		UCL.UCcreateMenuitem();
    	},
    	UCcreateMenuitem: function() {
    		let sep = $("usercssloader-ucseparator");
    		let popup = sep.parentNode;
    		if (sep.nextSibling) {
    			let range = document.createRange();
    			range.setStartAfter(sep);
    			range.setEndAfter(popup.lastChild);
    			range.deleteContents();
    			range.detach();
    		}
    
    		let re = /^file:.*\.uc\.css(?:\?\d+)?$/i;
    		Array.slice(document.styleSheets).forEach(function(css) {
    			if (!re.test(css.href)) return;
    			let fileURL = decodeURIComponent(css.href).split("?")[0];
    			let aLeafName = fileURL.split("/").pop();
    			let m = $C("menuitem", {
    				label: aLeafName,
    				tooltiptext: fileURL,
    				id: "usercssloader-" + aLeafName,
    				type: "checkbox",
    				autocheck: "false",
    				checked: "true",
    			});
    			m.css = css;
    			m.addEventListener("command", function() {
    				if (!event.ctrlKey) {this.setAttribute("checked", !(this.css.disabled = !this.css.disabled));}
    			});
    			m.addEventListener("mouseup", function(event) {
    				if (event.button === 1) event.preventDefault();
    			});
    			m.addEventListener("click", function(event) {
    				UCL.UCItemClick(event);
    			});
    			popup.appendChild(m);
    		});
    	},
    	UCItemClick: function(event) {
    		if (event.button === 0) return;
    		event.preventDefault();
    		event.stopPropagation();
    
    		if (event.button === 1) {
    			event.target.doCommand();
    		}
    		else if (event.button === 2) {
    			closeMenus(event.target);
    			let fileURL = event.currentTarget.getAttribute("tooltiptext");
    			let file = Services.io.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler).getFileFromURLSpec(fileURL);
    			this.edit(file);
    		}
    	},
    };
    
    function CSSEntry(aFile) {
    	this.path = aFile.path;
    	this.leafName = aFile.leafName;
    	this.lastModifiedTime = 1;
    	this.SHEET = /^xul-|\.as\.css$/i.test(this.leafName) ?
    		Ci.nsIStyleSheetService.AGENT_SHEET:
    		/\.author\.css$/i.test(this.leafName)?
    			Ci.nsIStyleSheetService.AUTHOR_SHEET:
    			Ci.nsIStyleSheetService.USER_SHEET;
    }
    CSSEntry.prototype = {
    	sss: Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService),
    	_enabled: false,
    	get enabled() {
    		return this._enabled;
    	},
    	set enabled(isEnable) {
    		let aFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile)
    		aFile.initWithPath(this.path);
    
    		let isExists = aFile.exists(); // true, wenn die Datei bereits existiert
    		let lastModifiedTime = isExists ? aFile.lastModifiedTime : 0;
    		let isForced = this.lastModifiedTime != lastModifiedTime; //true, wenn es eine Änderung in der Datei gibt
    
    		let fileURL = Services.io.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler).getURLSpecFromActualFile(aFile);
    		let uri = Services.io.newURI(fileURL, null, null);
    
    		if (this.sss.sheetRegistered(uri, this.SHEET)) {
    			// Wenn diese Datei bereits gelesen wurde
    			if (!isEnable || !isExists) {
    				this.sss.unregisterSheet(uri, this.SHEET);
    			}
    			else if (isForced) {
    				// Nach Stornierung erneut einlesen
    				this.sss.unregisterSheet(uri, this.SHEET);
    				this.sss.loadAndRegisterSheet(uri, this.SHEET);
    			}
    		} else {
    			// Datei wurde nicht gelesen
    			if (isEnable && isExists) {
    				this.sss.loadAndRegisterSheet(uri, this.SHEET);
    			}
    		}
    		if (this.lastModifiedTime !== 1 && isEnable && isForced) {
    			log(this.leafName + " wurde aktualisiert");
    		}
    		this.lastModifiedTime = lastModifiedTime;
    		return this._enabled = isEnable;
    	},
    };
    
    UCL.init();
    
    function $(id) { return document.getElementById(id); }
    function $A(arr) { return Array.slice(arr); }
    function $C(name, attr) {
    	const el = document.createXULElement(name);
    	if (attr) Object.keys(attr).forEach(function(n) { el.setAttribute(n, attr[n]) });
    	return el;
    }
    function dateFormat(date, format) {
    	format = format.replace("%Y", ("000" + date.getFullYear()).substr(-4));
    	format = format.replace("%m", ("0" + (date.getMonth()+1)).substr(-2));
    	format = format.replace("%d", ("0" + date.getDate()).substr(-2));
    	format = format.replace("%H", ("0" + date.getHours()).substr(-2));
    	format = format.replace("%M", ("0" + date.getMinutes()).substr(-2));
    	format = format.replace("%S", ("0" + date.getSeconds()).substr(-2));
    	return format;
    }
    
    function log(mes) { console.log(mes); }
    })();
    Alles anzeigen
  • Schaltfläche um Lesezeichen Leiste ein/auszublenden ?

    • Speravir
    • 12. September 2025 um 01:01
    Zitat von grisu2099

    Geh mal oben im Menü Einstellungen auf Optionen. Dort dann auf den Punkt Neues Dokument. Da kannst du rechts die Codierung einstellen auf UTF-8. Danach sollte sich nichts mehr verstellen... :/

    Genau den Punkt meinte ich, Enterhaken.

    Zitat von Enterhaken

    Genau so ist es bei mir auch eingestellt:

    Bei mir auch mit einer Ausnahme: Ich hab „UTF-8 auch beim Öffnen von ANSI-Dokumenten“ deaktiviert und muss dann eben mit den Konsequenzen leben. Zuletzt ist das Problem hier aber nicht mehr vorgekommen.

  • Schaltfläche um Lesezeichen Leiste ein/auszublenden ?

    • Speravir
    • 7. September 2025 um 02:15
    Zitat von Enterhaken

    Wenn ich die Skripte mit Notepad++ erstelle, springt die Kodierung nur dann automatisch von UTF-8 um wenn in den Code-Schnipseln Umlaute verbaut sind.

    Das ist mir auch schon diverse Male passiert, weshalb ich bei dir sofort daran dachte, nur waren andere schneller mit der Lösung. Was hast du eigentlich für eine Einstellung für neue Dokumente in den Optionen von N++?

  • Custom toolbars buttons have no icons

    • Speravir
    • 7. September 2025 um 02:07

    lenny2, Mira_Belle: Es muss sich um about_button.uc.js oder about_button_generic.uc.js handeln, aber über Anpassungen muss uns tatsächlich der OP Bescheid geben.

    juzzlukin, please, post your actual script, so we can see your (necessary) edits. Do other scripts work?

  • Meine Version des App-Menüs (JavaScript)

    • Speravir
    • 7. September 2025 um 01:53
    Zitat von Mira_Belle

    Hast Du Dir das schon mal angeschaut?

    Ja, aber ich bin auch kein Experte. Das läuft eher wie bei den meisten hier: Blindes Huhn und hochprozentiger Schnaps. ;)

    Sehe ich das richtig, dass Deine Version eine Abwandlung von einem Skript ist, dass 2002Andreas hier irgendwo mal gepostet hat, als er Probleme damit hatte?

  • UserCSSLoader (2025)

    • Speravir
    • 7. September 2025 um 01:49
    Zitat von bege

    Dazu muss jetzt immer ein Dateimanager angegeben werden, z.B. eben auch der Windows Explorer.

    Jetzt scheinen sich unsere Postings überschnitten zu haben. Ernaut danke und ich schau mir das natürlich an, aber ich bleibe dabei: Diesen letzten Ausweg würde ich nicht entfernen, eher darauf hinweisen, dass man auch den Windows Explorer explizit angeben kann.

Unterstütze uns!

Jährlich (2025)

105,8 %

105,8% (687,41 von 650 EUR)

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