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
    • 22. August 2025 um 01:00
    Zitat von Endor

    Habe eine funktionierende Version vom usercssloader.uc.js auf Basis einer
    Version aus den asiatischen Tiefen gemacht.

    Oh … :whistling:

    Ich hab die Änderungen aus der vorigen Version (UserCSSLoader.uc.js bei Endor) wieder eingebaut inklusive des Konfigurationsteils und einigen Fehlerkorrekturen (an einer Stelle fehlte sicher eine Semikolon, in einer anderen kann man es weglassen, glaube ich, es ist aber besser, es zu setzen; plus Rechtschreib-/Tippfehler, zum Teil von mir selber aus der Vorgängerversion).

    Zitat von Endor

    Im Moment fehlt noch der Eintrag zum öffnen des Chromeordners
    und die Möglichkeit zur Verwendung eines alternativen Dateimanagers.
    Also anstelle vom Explorer zbs. den Totalcomander.

    Bei mir funktioniert es. (Bis auf das:) Wenn ich mich aber recht erinnere, ging schon beim letzten Mal die Sache mit den Dateimanagerparametern nicht, vielleicht will sich BrokenHeart das mal ansehen? Ich nutze daher eine Windows-Verknüpfung (.LNK-Datei), in Linux und MacOS würde man wohl eine Shell-Datei einsetzen. Eine Tastenkombi musste auch wieder eingefügt, dabei aber geändert werden, bei einer anderen war mir nicht aufgefallen, dass meine Änderung schon vergeben war, Details bei Anfrage und vielleicht fällt anderen eine weitere Kollision auf.

    Den CSS-Tester und alle dazugehörigen Codeteile habe ich wieder herausgeworfen: Erstens ist das in der Skript-Vorlage sowieso standardmäßig deaktiviert und zweitens erhielt ich nach Aktivierung nur leere Fenster ohne Inhalt, was aber, sofern ich die Fehlerkonsole nicht missverstehe, an meinen Schutzeinstellungen im Firefox liegen könnte.

    JavaScript: UserCSSLoader_2025-08
    // ==UserScript==
    // @name           UserCSSLoader
    // @description    CSS-Codes - Styles laden und verwalten
    // @namespace      http://d.hatena.ne.jp/Griever/
    // @author         Griever
    // @include        main
    // @license        MIT License
    // @compatibility  Firefox 141+
    // @charset        UTF-8
    // @version        0.0.4r4
    // @note           0.0.4r4 prevent close menu when middleclick
    // @note           Aktualisierungen von BrokenHeart (mit 0.0.4r4 obsolet) und Speravir - www.camp-firefox.de
    // @note           0.0.4r3 Fx92: getURLSpecFromFile() -> getURLSpecFromActualFile()
    // @note           0.0.4r2 AUTHOR_SHEET-Unterstützung hinzugefügt, wichtig: Dateiendung muss .author.css sein!
    // @note           Version 0.0.4.g ermöglicht "Styles importieren" per Mittelklick und Verwendung
    // @note           eines anderen Dateimanagers (siehe in Konfiguration), ergänzt um einen
    // @note           Parameter für den Dateimanager (vFMParameter in der Konfiguration) von aborix
    // @note           Frei verschiebbare Schaltfläche eingebaut von aborix
    // @note           0.0.4 Remove E4X
    // @note           CSS-Entry-Klasse erstellt
    // @note           Style-Test-Funktion überarbeitet
    // @note           Wenn die Datei gelöscht wurde, CSS beim Neu-Erstellen und Löschen des Menüs abbrechen
    // @note           uc einlesen .uc.css temporäre Korrespondenz zum erneuten Lesen
    // ==/UserScript==
    
    /****** 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 wird in Navigationsleiste eingefügt (konfigurierbar, siehe Variable "position")
    
    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 bzw. einfügen.
    
    Verwenden des in "view_source.editor.path" angegebenen Editors.
    
    Dateiordner kann in Konfiguration geändert werden.
    
    **** Anleitung Ende ****/
    
    (function(){
    
    /***** Konfiguration *****/
    // Position: als frei verschiebbare-Schaltfläche = 0, als Menü anzeigen = 1
    let position = 0;//1
    // alternativer Dateimanager, Bsp.:
    // let filemanager = "C:\\Programme\\totalcmd\\TOTALCMD.EXE";
    let filemanager = "";
    // eventuelle Parameter für den alternativen Dateimanager, sonst filemanagerParam = "";
    //let filemanagerParam = "/O /T";//Totalcommander
    let filemanagerParam = "";
    // Unterordner für die CSS-Dateien:
    let cssFolder = "CSS";
    // Menüeintrag zum Bearbeiten der userChrome.css verstecken (true) oder anzeigen (false)
    let hideUserChromeCSS = false;
    // Menüeintrag zum Bearbeiten der userContent.css verstecken (true) oder anzeigen (false)
    let hideUserContentCSS = false;
    // zusätzlich Chrome-Ordner im Untermenü anzeigen: 1 = ja, 0 = nein
    let showChrome = 1;
    /***** Ende Konfiguration *****/
    
    ChromeUtils.importESModule("resource://gre/modules/AppConstants.sys.mjs");
    
    let { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
    const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
    
    // 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;
    }
    
    window.UCL = {
    		vFileManager: filemanager,
    		vFMParameter: filemanagerParam,
    		USE_UC: "UC" in window,
    		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, 0664);
    		}
    		delete this.FOLDER;
    		return this.FOLDER = aFolder;
    	},
    	get CHRMFOLDER() {
    			let bFolder;
    			try {
    					// UserCSSLoader.CHRMFOLDER verwenden
    					let CHRMfolderPath = this.prefs.getCharPref("CHRMFOLDER");
    					bFolder = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
    					bFolder.initWithPath(CHRMfolderPath);
    			} catch (e) {
    					bFolder = Services.dirsvc.get("UChrm", Ci.nsIFile);
    			}
    			if (!bFolder.exists() || !bFolder.isDirectory()) {
    					bFolder.create(Ci.nsIFile.DIRECTORY_TYPE, 0664);
    			}
    			delete this.CHRMFOLDER;
    			return this.CHRMFOLDER = bFolder;
    	},
    
    	getFocusedWindow: function() {
    		let win = document.commandDispatcher.focusedWindow;
    		if (!win || win == window) win = content;
    		return win;
    	},
    
    	init: function() {
    		const cssmenu = $C("menu", {
    			id: "usercssloader-menu",
    			label: "CSS",
    			tooltiptext: "UserCSSLoader\n\nLinksklick: Stylesheets anzeigen\nMittelklick: Styles importieren",
    			accesskey: "Y"
    		});
    		cssmenu.addEventListener("mouseup", (event) => { if (event.button === 1) event.preventDefault(); });
    		cssmenu.addEventListener("command", () => 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: "M",
    			//acceltext: "Alt + M"
    		});
    		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: "Alt + I"
    		});
    		rebuildItem.addEventListener("command", () => UCL.rebuild());
    		mp.appendChild(rebuildItem);
    		mp.appendChild($C("menuseparator"));
    		let createCSS = $C("menuitem", {
    			label: "CSS-Datei erstellen",
    			accesskey: "E",
    			//acceltext: "Alt + E"
    		});
    		createCSS.addEventListener("command", () => UCL.create());
    		mp.appendChild(createCSS);
    		let openFolder = $C("menuitem", {
    			label: "CSS-Ordner öffnen",
    			accesskey: "O",
    			//acceltext: "Alt + O"
    		});
    		openFolder.addEventListener("command", () => UCL.openFolder());
    		mp.appendChild(openFolder);
    		if (showChrome === 1) {
    				let openChromeFolder = $C("menuitem", {
    					label: "Chrome-Ordner öffnen",
    					accesskey: "X",
    					//acceltext: "Alt + X"
    				});
    				openChromeFolder.addEventListener("command", () => UCL.openCHRMFolder());
    				mp.appendChild(openChromeFolder);
    		}
    		mp.appendChild($C('menuseparator'));
    		let editChromeItem = $C("menuitem", {
    			label: "userChrome.css bearbeiten",
    			hidden: hideUserChromeCSS,
    		});
    		editChromeItem.addEventListener("command", () => UCL.editUserCSS("userChrome.css"));
    		mp.appendChild(editChromeItem);
    		let editContentItem = $C("menuitem", {
    			label: "userContent.css bearbeiten",
    			hidden: hideUserContentCSS,
    		});
    		editContentItem.addEventListener("command", () => UCL.editUserCSS("userContent.css"));
    		mp.appendChild(editContentItem);
    
    		menu = $C("menu", {
    			label: ".uc.css",
    			accesskey: "U",
    			//acceltext: "Alt + U",
    			hidden: !UCL.USE_UC
    		});
    		menupopup.appendChild(menu);
    		mp = $C("menupopup", { id: "usercssloader-ucmenupopup" });
    		menu.appendChild(mp);
    		let UCrebuild = $C("menuitem", {
    			label: "Importieren(.uc.js)",
    		});
    		UCrebuild.addEventListener("command", () => UCL.UCrebuild());
    		mp.appendChild(UCrebuild);
    		mp.appendChild($C("menuseparator", { id: "usercssloader-ucseparator" }));
    
    		CustomizableUI.createWidget({
    			id: 'usercssloader-menu-item',
    			type: 'custom',
    			defaultArea: CustomizableUI.AREA_NAVBAR,
    			onBuild: function(aDocument) {
    				let toolbaritem = aDocument.createElementNS('http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul', '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);
    		}
    
    		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;
    		if (UCL.USE_UC) {
    			setTimeout(function() {
    				UCL.UCcreateMenuitem();
    			}, 1000);
    		}
    		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 : "Linksklick: an/aus, Menü schließt\nMittelklick: an/aus, Menü bleibt offen\nRechtsklick: bearbeiten\nStrg+Rechtsklick: im Dateimanager anzeigen"
    			});
    			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.openFolder(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;
    	},
    	openFolder: function(label) {
    		const PathSep = AppConstants.platform === "win" ? "\\" : "/";
    		let target= this.FOLDER.path + PathSep + label;
    		if (this.vFileManager.length !== 0) {
    				let file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
    				let process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess);
    				let args = [this.vFMParameter,target];
    				file.initWithPath(this.vFileManager);
    				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 (this.vFileManager.length !== 0) {
    					let file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
    					let process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess);
    					let args = [this.vFMParameter,this.CHRMFOLDER.path];
    					file.initWithPath(this.vFileManager);
    					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 = Services.prefs.getCharPref("view_source.editor.path");
    		if (!editor) return alert('Unter about:config den vorhandenen Schalter\n "view_source.editor.path" mit dem Editorpfad ergänzen');
    		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.createElementNS(XULNS, 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

    BrokenHeart , die Bemerkung, dass Deine Änderung obsolet sei, bezieht sich auf diese von Januar dieses Jahres, wo Du die benötigten Eventlistener über eine Funktion eingebaut hast. Das ist in der aktuellen Version nicht mehr notwendig.

    Zitat von Boersenfeger

    In Zeile 376 steht let sep = $("usercssloader-ucsepalator");

    Ist das korrekt oder muss es ucseparator heißen?

    Ja, das ist ein Tippfehler, der mir ebenso auffiel und den ich auch geändert habe. Es betrifft hier aber eine ID und die könnte irgendeinen auch völlig kryptischen Namen erhalten, solange sie eindeutig ist, was hier der Fall ist (diese ID mit Tippfehler wird bereits weiter vorn erzeugt/zugeordnet, in Z. 179).

  • ScrollTopAndBottom.uc.js und Open with.uc.js zeigen keine Icons mehr an im Nightly

    • Speravir
    • 7. August 2025 um 01:35

    Probiert doch die hier oben von milupo (#41) und Endor in einer aktualisierten Version (siehe am 5.2.2025, 14:32) gepostete Variante ( Endor, ich glaube, Du hast die nicht bei GitHub hochgeladen). Ich vermute, dass ich diese früher benutzt habe, weil sie bei Endor oder schon Mithrandir/Ardiman verfügbar war.

    Ich nutze aber seit Jahren das entsprechende Addon Open With (dessen Entwicklung leider eingestellt wurde, wie man im GitHub-Repository lesen kann/muss). Dort kann man die Parameter einfach zusätzlich einfügen, es benötigt allerdings zusätzlich eine Python-Installation und einmalig etwas Mehraufwand.

  • Allgemeine Diskussion über Firefox

    • Speravir
    • 7. August 2025 um 00:54
    Zitat von Sören Hentzschel

    Wenn Firefox auf Windows keinen dedizierten Shortcut dafür hat, gibt es immer noch die Möglichkeit, die Menüleiste über die Tastatur zu bedienen, was auch bei standardmäßig ausgeblendeter Menüleiste funktioniert.

    Ja, stimmt natürlich.

    Zitat von Sören Hentzschel

    Bei nur gelegentlicher Nutzung bietet sich die Einblendung über die Alt-Taste ein

    Ja, genau das tue ich. Das wollte ich mit „Ich benötige die Menüleiste auch nicht ständig“ andeuten.

    Zitat von Sören Hentzschel

    Welche Funktion, die du tatsächlich nutzt, findest du denn nur in der Menüleiste?

    Selten, aber gelegentlich dann doch: Im Menü Ansicht die Punkte Webseiten-Stil und Textkodierung reparieren.

  • Allgemeine Diskussion über Firefox

    • Speravir
    • 6. August 2025 um 01:38

    Und zusätzlich:

    Zitat von Sören Hentzschel

    Einstellungen und neues privates Fenster […]. Beides öffne ich aber ohnehin ausschließlich mit der Tastatur.

    Für die Einstellungen gibt es in Windows keine Tastenkombination. Jedenfalls wird keine im Menü angezeigt und auch auf der SUMO-Seite Tastenkombinationen in Firefox zur schnellen Durchführung häufiger Befehle finde ich nichts (dort ist natürlich Windows11 ausgewählt). Zu SUMO bin ich jetzt übrigens über das Hilfemenü gelangt. :)

    Ich benötige die Menüleiste auch nicht ständig, aber manche Sachen finde ich dort einfacher oder anscheinend nur dort. Für einiges gibt es noch Buttons, beispielsweise die Einstellungen.

  • ScrollTopAndBottom.uc.js und Open with.uc.js zeigen keine Icons mehr an im Nightly

    • Speravir
    • 6. August 2025 um 01:16
    Zitat von lenny2

    Weil das Skript nicht auf .lnk reagiert.

    Schade. Ich hab so geantwortet, weil eine von mir früher benutzte Variante des Skriptes so funktionierte.

  • ScrollTopAndBottom.uc.js und Open with.uc.js zeigen keine Icons mehr an im Nightly

    • Speravir
    • 5. August 2025 um 01:57
    Zitat von lenny2

    Wie kann ich in OpenWith den Pfad zum Browser mit Befehlszeilentasten angeben?

    In Windows: Erzeuge eine Verknüpfung (.lnk-Datei), in der der du die Befehlszeilenoptionen im Ziel zusätzlich einträgst, und verlinke im Skript diese Verknüpfung. In Linux und MacOS müsste es dann mit Shell-Dateien funktioneren.

  • Code für min, max, close funktioniert nach Update nicht mehr richtig

    • Speravir
    • 27. Juli 2025 um 01:16
    Zitat von Horstmann

    Es gibt auch noch […] light-dark

    Stimmt, daran habe ich nicht gedacht. Ist ja auch noch relativ neu. Hilft mir selbst allerdings nicht.

  • Code für min, max, close funktioniert nach Update nicht mehr richtig

    • Speravir
    • 26. Juli 2025 um 01:04

    OK, Andreas.

    Zum Thema: Alles, was Horstmann schreibt, kann ich unterschreiben.

    Zu meinem obigen Nachtrag: Es ist so, dass ich den geposteten Code so ähnlich für mich schon gebastelt hatte (ich hab nur :root[lwtheme-image] statt #main-window), dann wegen der Frage verschiedene Themes aktiviert habe und der Code dann plötzlich nicht funktionierte, und zwar wie erwartet bei den System-Themes (wegen des lwtheme-image), aber auch bei diesem: Dark Cyan Blur. obwohl dort das entsprechende Attribut auf true gesetzt ist. Ich hab den Stilcode jetzt auf das aktuelle Theme eingeschränkt, das geht zum Glück, weil es im Style-Attribut eingetragen ist. Bei manchen sehr hellen Themes sind weiße Schalter sowieso schlecht bis gar nicht zu erkennen. Dann muss ich den Teil in Testprofilen eben anpassen, wenn nötig (Nachtrag: durch die Beschränkung muss ich das aber gar nicht, wie ich inzwischen sehe; das von mir benutzte standardmäig Theme ist offensichtlich eher eine Ausnahme).

  • Code für min, max, close funktioniert nach Update nicht mehr richtig

    • Speravir
    • 25. Juli 2025 um 00:31
    Zitat von Firefox_94.0.1

    Doch seit dem neuesten Update funktionieren nur noch die :hover background Einstellungen. Die Symbole selbst bleiben schwarz, obwohl sie als weiß definiert wurden.

    Füge auch dort ein !important hinzu. Übrigens kannst du den Code verkürzen, denn alle 3 Schalter besitzen die Klasse titlebar-button. Ich selbst hab noch aus der höheren Ebene titlebar-buttonbox davor gesetzt, um die Spezifität zu erhöhen, benötige aber trotzdem jetzt die Verstärkung. Alles in allem:

    CSS
    /* 3 Buttons oben rechts Farbe ändern*/
     /***** links *****/
    #main-window .titlebar-buttonbox .titlebar-button {
        color: #fff !important;
     }

    Sollte irdendwann mal weitere Titlebar-Buttons dazukommen, dann müsste man unter Umständen wieder auf die einzelnen Klassenbezeichner zugreifen.

    Zitat von 2002Andreas

    Wie du sieht, hier sind sie weiß.

    Du benutzt doch ein dunkles Thema, wenn ich nicht irre, dann sind die Knöpfe schon vom Betriebssystem aus weiß. Das ist ja das Neue in Windows, dass sie jetzt nativ übernommen werden (zum Glück aber auch per CSS überregelt werden können).

    Edit: Ich merke gerade, dass das wohl nur teilweise zutrifft. Ich habe bei mir selbst auf die beschriebene Weise die Farbe der Knöpfe beeinflussen können. Das scheint aber nicht für jedes Theme zu funktionieren (ich hab hier einige installiert, die ich gelegentlich für Testprofile nutze.)

  • dav_LinkifiesLocationBar.uc.js = Fehlerhafte Url Anzeige

    • Speravir
    • 20. Juli 2025 um 00:58
    Zitat von Mira_Belle

    Mh, 'ne ganz schön harte Nuss.
    Selbst mit KI komme ich z.Z. nicht weiter.

    Bisher wohl die falschen Fragen gestellt.
    Bleibe aber weiter am Ball, das Ding interessiert mich!

    Muss herausfinden, wie genau die URL zerpflückt und zerlegt wird.

    Ohne es vollständig verstanden zu haben: Sieh dir die Funktion pintaLocation_() an, in Version 1.1 (vergleiche oben bei Endor) Zeile 312 bis 385. Übrigens sind Teile des Skripts (Bezeichnungen) und Kommentare in Spanisch.

  • Perplexity aus der Suchmaschinen-Liste verschwunden

    • Speravir
    • 13. Juli 2025 um 02:35
    Zitat von 2002Andreas
    Zitat von neuneuer

    wieder in der Liste der Suchmaschinen aufgeführt wird?

    Den Eintrag unten: Hinzufügen hast du nicht?

    Ich glaube, dafür muss die Einstellung browser.urlbar.update2.engineAliasRefresh auf true gesetzt werden beziehungsweise überhaupt erstmal in der Konfig angelegt werden.

  • v140.0rc1 Konflikt mit dem Skript addonbar_vertical.uc.js von Aris-t2

    • Speravir
    • 18. Juni 2025 um 02:11
    Zitat von Horstmann
    Zitat von Speravir

    Ich hab diesen Code (2 Zeilen) jedenfalls schon länger deaktiviert.

    Nur 2 Zeilen? :/

    Aah, da habe ich Quatsch erzählt. Die zwei auskommentierten Zeilen befinden sich etwas weiter oben, Z. 342f.

  • v140.0rc1 Konflikt mit dem Skript addonbar_vertical.uc.js von Aris-t2

    • Speravir
    • 17. Juni 2025 um 21:04
    Zitat von Horstmann

    ab Zeile 358 den Code für fix for downloads button on add-on bar rauszunehmen

    Der übrigens schon länger, nicht erst in der Nightly-Version, eine Fehlermeldung erzeugt, wenn man diesen Downloadsbutton nicht benutzt, beispielsweise weil man einen anderen Knopf eingebaut hat. Ich hab diesen Code (2 Zeilen) jedenfalls schon länger deaktiviert. (Edit: Irrtum, siehe meine Antwort im übernächsten Posting #9.)

    Zitat von Horstmann

    oder dort eine neue Issue eröffnen

    („dort“: Aris-t2/CustomJSforFx)

    Oder noch niederschwelliger in der von Aris angebotenen Diskussion, aktuell [JavaScript][Firefox] General JavaScript talk and custom userChrome.js scripts (v2).

    Zitat von Endor

    Ich hoffe aber ArisCTR liest hier mit.
    E-Mail Benachrichtigung sollte er ja auf jeden Fall nun ja
    bekommen.

    Ich bin mir da nicht so sicher. Ich habe Aris öfter auf hiesige Beiträge und Diskussionen hingewiesen und er schien bis dahin nichts davon bemerkt zu haben … Und eben habe ich dasselbe für diese Diskussion gemacht.

  • Mozilla integriert KI-Suchmaschine Perplexity in Firefox

    • Speravir
    • 16. Juni 2025 um 23:49
    Zitat von BrokenHeart

    Bei Google werden bei den KI-basierten Suchergebnissen genauso Links auf die gefundenen Quellen ausgegeben.

    Touché, das habe ich bisher nicht benutzt. Ich habe aber zum Glück auch nicht geschrieben, dass alle anderen das nicht täten.

  • Mozilla integriert KI-Suchmaschine Perplexity in Firefox

    • Speravir
    • 15. Juni 2025 um 00:58

    Gute Entscheidung. Anders als bei anderen KI-basierten Modellen werden übrigens die ausgewerteten Quellen angegeben.

  • Finde die CSS-Datei zur individuellen Firefox Einstellung nicht

    • Speravir
    • 12. Juni 2025 um 01:44
    Zitat von Skogtroll

    in welchem eine userchrome.css sein soll

    Nur, um sicherzugehen: Die Datei muss userChrome.css heißen – mit großem C im Innern. Und sie muss in UTF-8 kodiert sein. Solange alles nur in Englisch ist, wird einem das nicht auffallen, aber sofort, wenn man beispielsweise deutsche Umlaute einfügt.

  • Tab mit Audioinhalt: Ist diese Darstellung normal oder ein nicht mehr richtig funktionierendes Script?

    • Speravir
    • 7. Juni 2025 um 21:21

    Eine nette Ergänzung zu #117 (Einfärbung der Audio-Icons, beachte Zeilenzahlen):

    CSS
    .tab-audio-button[soundplaying-scheduledremoval]:not([muted]) {
    	--button-icon-fill: #0060df !important;/* var(--blue-60) */
    }

    Das färbt das Symbol blau, wenn man einen Medieninhalt mit Audioteil pausiert, aber auch, wenn er fertig abgespielt ist.

    Damit man das überhaupt bemerkt, muss man den Standard der Symboleinblendung deutlich verlängern: In about:config die Einstellung browser.tabs.delayHidingAudioPlayingIconMS finden und den Standardwert 3000 (= 3000ms) deutlich erhöhen. Beispielsweise steht 86400000 für 1 Tag (24h à 60min à 60s), was für die meisten effektiv bedeuten sollte, dass das Symbol gar nicht ausgeblendet wird (und diese Flackerei, wie sie etwa Zitronella störte, auch nicht mehr auftreten dürfte).

    Ich hab mir das Symbol auch noch geändert, aber, wie oben mehrfach bemerkt, muss die entsprechende Regel in die UserChromeShadow-Stildatei eingetragen werden:

    CSS
    /* Anzeige des Pausenmodus in Tabs mit Medieninhalten */
    .tab-audio-button {
        #TabsToolbar #tabbrowser-tabs[orient="horizontal"] &:not([pinned]):not([crashed]),
        :root:not([sidebar-expand-on-hover]) #tabbrowser-tabs[orient="vertical"][expanded] &:not([pinned]):not([crashed]) {
            &[soundplaying-scheduledremoval]:not([muted])::part(button) {
                background-image: url("chrome://global/skin/media/pause-fill.svg") !important;
            }
        }
    }

    Das ist eine abgewandelte Kopie des originalen Codes, ich hatte nur damit Erfolg. Das zeigt das Pausensymbol auch bei bis zum Ende abgespielten Medientabs, aber das sit mir lieber als das Symbol für einen aktiven Medientab.

    Es gibt übrigens im Firefox noch schlankere Pausensymbole an anderer Stelle (bzw. wie es scheint das optisch selbe Symbol an zwei Stellen), bei Interesse könnte ich eine Adresse angeben.

    Apropos Zitronella: Zu deinem Beitrag #145 siehe auch Antwort von krystian3w in Audio is expanding/collapsing/resizing tab, want to act like before FireFox 136 (Issue #755 · Aris-t2/CustomCSSforFx).

  • Seit FF139 geht das script nicht mehr: allow_search_oneoff_with_empty_text.uc.js

    • Speravir
    • 7. Juni 2025 um 01:49
    Zitat von jizz

    the issue should be with your loader not supporting the @sandobx annotation.

    Ah, sadly I had to notice this myself with other scripts by Alice.

  • Seit FF139 geht das script nicht mehr: allow_search_oneoff_with_empty_text.uc.js

    • Speravir
    • 4. Juni 2025 um 23:42
    Zitat von 2002Andreas
    Zitat von Speravir

    was kann das Skript, was darüber hinaus geht?

    Mit Linksklick der Maus öffnet sich die Suchseite.

    Danke. Ich sag ja, das Skript ist nicht mehr nötig … 8o

  • Mozilla veröffentlicht Firefox 138 mit neuer Profilverwaltung

    • Speravir
    • 3. Juni 2025 um 00:28
    Zitat von .DeJaVu

    Es war durchaus eine ernste Frage.

    Ah, OK.

Unterstütze uns!

Jährlich (2025)

101,9 %

101,9% (662,48 von 650 EUR)

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