Dharkness
Ergänze das CSS um:
Das sollte es gewesen sein.
Dharkness
Ergänze das CSS um:
Das sollte es gewesen sein.
Wer mag, kann auch einige Menüeinträge ausblenden!
Ich brauche z.B. jene nicht und habe DAS dann doch per CSS im Skript umgesetzt.
Einfach in Zeile 120 eingefügt.
let sss = Components.classes["@mozilla.org/content/style-sheet-service;1"].getService(Components.interfaces.nsIStyleSheetService);
let uri = Services.io.newURI("data:text/css;charset=utf-8," + encodeURIComponent(`
/*--------------------------------------------------------------------------*/
/*------------------- Einige Menüeinträge ausgeblendet ---------------------*/
/*--------------------------------------------------------------------------*/
#submenu-CSSShadow,
#submenu-cssweb,
menuitem.uProfMenu_edit[label="Bild Url"],
menuitem.uProfMenu_edit[label="config Einträge.css"],
menuitem.uProfMenu_folder[label="CSSShadow-Ordner"],
menuitem.uProfMenu_folder[label="CSSWeb-Ordner"] {
display: none !important;
}
`), null, null);
sss.loadAndRegisterSheet(uri, sss.AUTHOR_SHEET);
Alles anzeigen
Natürlich funktioniert das auch per externem CSS, siehe oben!!
Gibt ja Anwender die strickt JS und CSS getrennt haben wollen. ![]()
Was ne Sisyphusarbeit.
Es ist vollbracht.
Die Altlast mit "warpmenuto: 'helpMenu'" habe ich entsorgt und ersetzt durch die Auswahl,
ob ein Button oder ein Menü erstellt werden soll.
Das komplette Gefrickel mit dem CSS habe ich entfernt!
Dafür aber natürlich für den Button JS-Code eingefügt.
Es kann also recht einfach ein eigenes Symbol konfiguriert werden![]()
Und wie immer kann das SVG auch durch ein PNG ersetzt werden.
Wer doch lieber das "alte" Symbol für den Button behalten möchte,
ersetzt halt ganz einfach button.style.listStyleImage = 'url("' + iconUrl + '")'; durch
button.style.listStyleImage = 'url(data:image/png;base64, .... 5CYII=)';
Mh, ich lass das mal komplett auskommentiert im Code.
Fehlt noch etwas?
Achja, für das Symbol, wenn man denn keinen Button, sondern lieber ein Untermenü unter Extras haben möchte,
habe ich externes CSS!
@-moz-document url(chrome://browser/content/browser.xhtml) {
/* ------------------------------ */
/* ------ Extra-Config-Menü ----- */
/* ------------------------------ */
/* Das Symbol (Platzhalter) ausblenden */
#ExtraConfigMenu.menu-iconic img.menu-icon {
display: none !important;
}
/* Symbol vor dem JavaScript-Loader-Menü */
#ExtraConfigMenu {
background-image: url("../icons/edit.svg") !important;
background-repeat: no-repeat !important;
padding-left: 36px !important;
background-position: 12px center !important;
background-size: 16px 16px !important;
-moz-context-properties: fill;
fill: #e0e0e0 !important;
}
}
Alles anzeigen
So, und hier das komplett überarbeitete Skript
und auf vielfachen Wunsch einer einzelnen Person natürlich mit Erläuterungen.
Wäre schön, wenn das noch einmal jemand prüfen könnte,
denn bei aller Sorgfalt kann sich doch mal ein Fehler einschleichen.
/*
// ==UserScript==
// @name extras_config_menu.uc.js
// @compatibility Firefox 153*.*
// @include main
// @version 1.0.20260825
// @edit @aborix 7/21 CSS Dateien als Untermenü eingefügt
// @edit @2002Andreas 8/21 Shadow CSS Dateien als Untermenü + Ordner eingefügt
// @edit @BrokenHeart 1/25 Anpass. wg. Änderung der Sicherheitsrichtlinien bei 'inlineEvents'
// @edit @Mira 8/26 Anpassung für security.allow_unsafe_dangerous_privileged_evil_eval = false
// @edit @Mira 8/26 Anpassung für Userscripte im Unterordner "chrome/scripts", Expliziter Ausschluss von "userChromeShadow.uc.js"
// @edit @Mira 8/26 Anpassung für "Skriptliste in Zwischenablage"
// @edit @Mira 8/26 1. Altlast "warpmenuto: 'helpMenu'" ersetzt durch die Auswahl, ob ein Button oder ein Menü erstellt werden soll.
// @edit @Mira 8/26 2. Das komplette CSS entsorgt! Code für Button ergänzt.
// ==/UserScript==
*/
var uProfMenu = {
// ■■ START UserConfiguration ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
// In der folgenden Zeile (20) den Pfad zum Texteditor eintragen (unter Ubuntu 10.04 z.B.: '/usr/bin/gedit'). Bei Fehleintrag wird view_source.editor.path ausgelesen:
//TextOpenExe: 'C:\\Program Files (x86)\\Notepad++\\notepad++.exe',
TextOpenExe: 'C:\\Program Files\\Microsoft VS Code\\Code.exe',
// Falls gewuenscht, in Zeile 24 einen Dateimanager eintragen (komplett leer lassen fuer Dateimanager des Systems) Beispiele:
// vFileManager: 'E:\\Total Commander\\Totalcmd.exe',
// vFileManager: 'C:\\Program Files (x86)\\FreeCommander\\FreeCommander.exe'
vFileManager: '',
// In der folgenden Zeile festlegen, ob ein verschiebbarer Button erstellt wird:
showAsButton: 1, // 1: ja / Button wird erstellt, 0: nein / Menue unter "Extras"0: nein / Menue unter "Extras"
// Unter Linux sollte/kann versucht werden, die userChromeJS-Skripte zu sortieren, unter Windows ist das evtl. nicht noetig (die Sortierung wird Gross- und Kleinschreibung *nicht* beruecksichtigen - dazu wird die sort()-Funktion entsprechend mit einer Vergleichsfunktion aufgerufen)
sortScripts: 0, // 1 zum Erzwingen der Sortierung
// Einbindung GM-Skripte-Ordner (0: nein, 1: Greasemonkey [Profil-Verzeichnis], 2: UserScriptLoader [Chrome-Verzeichnis], 3: Scriptish [Profil-Verzeichnis]):
gmOrdner: 0,
// Einbindung CSS-Ordner (0: nein, 1: UserCSSLoader-Ordner im Chrome-Verzeichnis):
cssOrdner: 1,
// In Zeile 37 gueltige about:Adressen eintragen, die ebenfalls aufgerufen werden sollen.
// - Zum Ausblenden: abouts: [],
// - Damit die about:-Seiten nicht als Untermenue, sondern direkt als Menuepunkte aufgefuehrt werden, muss das erste Element '0' sein:
// abouts: ['0','about:about','about:addons','about:cache','about:config','about:support'],
abouts: ['about:about','about:addons','about:cache','about:config','about:crashes',
'about:downloads','about:home','about:logins','about:memory','about:support',
'about:preferences','about:performance','about:profiles'
],
// Die normalen Firefox-Einstellungen auch zur Verfuegung stellen (0: nein, 1: ja):
showNormalPrefs: 1,
// Stellt "Skriptliste in Zwischenablage" zur Verfuegung (1: ja, 2: mit getrennter Nummerierung, 3: mit gemeinsamer Nummerierung) oder nicht (0):
enableScriptsToClip: 2,
// Um den Eintrag "Neustart" zu erzwingen (falls z.B. das andere Skript zu spaet eingebunden und nicht erkannt wird), auf 1 setzen:
enableRestart: 1,
// Symbol (Icon) nur fuer Button:
icon: 'edit.svg', // [Name.Dateiendung] des Symbols
iconColour: '#ff0000', // Farbe fuer das SVG-Icon setzen (leer fuer Originalfarbe)
iconPath: '/chrome/icons/', // Pfad zum Ordner der das Icon beinhaltet
// ■■ END UserConfiguration ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
// --- INIT (ANGEPASST) ---
init: function() {
// Profil-URI und Icon-URL einmalig bereitstellen
var curProfDir = PathUtils.toFileURI(PathUtils.join(PathUtils.profileDir));
var iconUrl = curProfDir + this.iconPath + this.icon;
var iconColour = this.iconColour;
if (this.showAsButton) {
// als verschiebbaren Button anlegen
if (window.__SSi == "window0") {
CustomizableUI.createWidget({
id: "ExtraConfigMenu-button",
defaultArea: CustomizableUI.AREA_NAVBAR,
label: "Extra Config Menü",
tooltiptext: "Extra Config Menü\nRechtsklick öffnet about:config",
onCreated: function(button) {
// Optik direkt am Button-Element setzen
button.style.MozContextProperties = 'fill, stroke, fill-opacity';
button.style.listStyleImage = 'url("' + iconUrl + '")';
// button.style.listStyleImage = 'url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACnElEQVR4Xm2RzYtbZRSHn/fr3pvJzTB3qiNM2k2pMBUGhEHaqsUqdeFGQalCobgREaFu/B/cqCtxVSjoQhBEQRBmIfWDKgNGJUPt0Nhah9JJ4iSd5E6+bu5972tAO4SS5/DjXZ1znsMrNiq1eikMQqYYJCmjxNH5+zdW777L0J5KKl9VPmnf+ut9KWkwhbheuzNcOVYOmGKc5iRO0r1ykeXCx0h7kt4fC3z5wfqbQnAJwQHa5S7jAZSRuJ0mkf81cheobhBXZa+ri1uptQjHAZoZCEC1PiPgDuwxCfwerBU7b73zXn//3usCcdt4HkZ7SGZg431U51NUCgwlO3cV/bVXhR/6p9ut+nP9QYeNn7/n8qUPZxvQ/Q6VVWHk4ZqWRvlJjpx9hcGfW2wO95N2q8m3618A2WwDt/0RplSAXsBed57eyossHl5GYdHacG3zGpADM06wjQ1UUIN+CLHPvfAxojPnKLiE+bDE1R9+5GatAmgPeGCAteQ7l5GBhGSyuROyd/gFouUyWkqEErR2mwXAAA8BRS0AgMQBjSra30ZkEeDzz9Dn4ZcvMO51SMcJcTdGChmA0ABA6cAgzyG3I8jLEBylV4fWoaeIc0V7t0Uv7pFbC+CA+28mp/8+SwXKnMVmz1O9HpE+eobMZdjcoY1GIHD/NwIdoH1fBaNguzlg88pVyoUi4vTbFI8eJxsNAIfSkrliESllH/L0v0jktNNomFGv1TFrL3Fo9QSMR3jaEEXzLC09gjaKp595No0WjyCEB4zRclICUMDxtRMce/wJ1MIi2SglXShhfI/cOjxPoZRmbq4gXzt/gVrtBrdvbiG+Wf+p/mvll1BpiVAGhCDPxuAUDotz4HKHlIJON6bRbL4hhPjcMx5mkn8BBLEUrsVZbq0AAAAASUVORK5CYII=)';
if (iconColour) {
button.style.color = iconColour;
}
}
});
}
var menu = document.getElementById("ExtraConfigMenu-button");
// KORREKTUR:
if (!menu) {
return;
}
menu.setAttribute("type", "menu");
// Dropmarker ausblenden (ersetzt ehemaliges CSS-Stylesheet)
menu.querySelectorAll("dropmarker, .toolbarbutton-menu-dropmarker").forEach(function(d) {
d.style.display = "none";
});
menu.addEventListener('click', function(event) {
if (event.button == 2 && !this.open) {
openTrustedLinkIn("about:config", "tab");
event.preventDefault();
}
}, true);
} else {
var zielmenu = document.getElementById('menu_ToolsPopup');
// da showAsButton nicht gesetzt ist, als Untermenue von Extras anlegen
if (zielmenu == null) {
userChrome.log("extras_config_menu.uc.js findet Zielmenue nicht, evtl. weil ein anderes Fenster als das Hauptfenster geoeffnet wurde.");
return;
}
var menu = zielmenu.appendChild(this.createME("menu", "Extra Config Men\u00FC", null, 0, "ExtraConfigMenu"));
menu.setAttribute("class", "menu-iconic");
// Ersetze ondblclick durch addEventListener
menu.addEventListener('dblclick', function() {
openTrustedLinkIn('about:config', 'tab');
}, true);
}
// ab hier ist alles gleich, egal ob Button oder Menue
// Menü-Popup erstellen
var menupopup = menu.appendChild(this.createME("menupopup", null, null, 0, "ExtraConfigMenu-popup"));
// Event-Listener für popupshowing (unchanged, aber sicher)
menu.addEventListener('popupshowing', function(event) {
uProfMenu.getScripts(0);
uProfMenu.getCss(3);
uProfMenu.getCss(4);
uProfMenu.getCss(5);
}, true);
// --- UNTERMENÜS (unchanged) ---
var submenu = menupopup.appendChild(this.createME("menu", "Meine Scripte", null, 0, "submenu-ucjs"));
// Anlegen von Untermenues fuer userChromeJS-Skripte und CSS-Dateien (befuellen spaeter)
var submenupopup = submenu.appendChild(this.createME("menupopup", null, null, 0, "submenu-ucjs-items"));
var submenu = menupopup.appendChild(this.createME("menu", "css", null, 0, "submenu-css"));
var submenupopup = submenu.appendChild(this.createME("menupopup", null, null, 0, "submenu-css-items"));
var submenu = menupopup.appendChild(this.createME("menu", "CSSShadow", null, 0, "submenu-CSSShadow"));
var submenupopup = submenu.appendChild(this.createME("menupopup", null, null, 0, "submenu-CSSShadow-items"));
var submenu = menupopup.appendChild(this.createME("menu", "cssweb", null, 0, "submenu-cssweb"));
var submenupopup = submenu.appendChild(this.createME("menupopup", null, null, 0, "submenu-cssweb-items"));
// Ende Anlegen von Untermenues
// Skriptliste in Zwischenablage (ANGEPASST: sCommand als Funktion)
if (this.enableScriptsToClip) {
menupopup.appendChild(this.createME(
"menuitem",
"Skriptliste in Zwischenablage",
function() { uProfMenu.getScripts(1); },
"uProfMenu_clipboard",
0
));
}
menupopup.appendChild(document.createXULElement('menuseparator'));
// --- KONFIGDATEIEN (ANGEPASST: sCommand als Funktion) ---
// Einbindung von Konfigdateien
menupopup.appendChild(this.createME(
"menuitem", "Bild Url",
function() { uProfMenu.edit(0, 'Bild Url.css'); },
"uProfMenu_edit", 0
));
menupopup.appendChild(this.createME(
"menuitem", "config Einträge.css",
function() { uProfMenu.edit(0, 'config Einträge.css'); },
"uProfMenu_edit", 0
));
menupopup.appendChild(this.createME(
"menuitem", "userChrome.css",
function() { uProfMenu.edit(0, 'userChrome.css'); },
"uProfMenu_edit", 0
));
menupopup.appendChild(this.createME(
"menuitem", "userChromeShadow.css",
function() { uProfMenu.edit(0, 'userChromeShadow.css'); },
"uProfMenu_edit", 0
));
menupopup.appendChild(this.createME(
"menuitem", "userContent.css",
function() { uProfMenu.edit(0, 'userContent.css'); },
"uProfMenu_edit", 0
));
menupopup.appendChild(this.createME(
"menuitem", "userChrome.js",
function() { uProfMenu.edit(0, 'userChrome.js'); },
"uProfMenu_edit", 0
));
menupopup.appendChild(this.createME(
"menuitem", "prefs.js",
function() { uProfMenu.edit(1, 'prefs.js'); },
"uProfMenu_edit", 0
));
menupopup.appendChild(this.createME(
"menuitem", "user.js",
function() { uProfMenu.edit(1, 'user.js'); },
"uProfMenu_edit", 0
));
// Ende Einbindung von Konfigdateien
// --- ORDNER (ANGEPASST: sCommand als Funktion) ---
menupopup.appendChild(document.createXULElement('menuseparator'));
// Einbindung von Ordnern
switch (this.gmOrdner) {
case 1:
menupopup.appendChild(this.createME(
"menuitem", "GM-skripty",
function() { uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('ProfD') + uProfMenu.getDirSep() + 'gm_scripts'); },
"uProfMenu_folder", 0
));
break;
case 2:
menupopup.appendChild(this.createME(
"menuitem", "USL-skripty",
function() { uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm') + uProfMenu.getDirSep() + 'UserScriptLoader'); },
"uProfMenu_folder", 0
));
break;
case 3:
menupopup.appendChild(this.createME(
"menuitem", "Skripty Scriptish",
function() { uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('ProfD') + uProfMenu.getDirSep() + 'scriptish_scripts'); },
"uProfMenu_folder", 0
));
break;
}
menupopup.appendChild(this.createME(
"menuitem", "CSS-Ordner",
function() { uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm') + uProfMenu.getDirSep() + 'css'); },
"uProfMenu_folder", 0
));
menupopup.appendChild(this.createME(
"menuitem", "CSSShadow-Ordner",
function() { uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm') + uProfMenu.getDirSep() + 'CSSShadow'); },
"uProfMenu_folder", 0
));
menupopup.appendChild(this.createME(
"menuitem", "CSSWeb-Ordner",
function() { uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm') + uProfMenu.getDirSep() + 'CSSWeb'); },
"uProfMenu_folder", 0
));
menupopup.appendChild(this.createME(
"menuitem", "Chromeordner",
function() { uProfMenu.prefDirOpen('UChrm'); },
"uProfMenu_folder", 0
));
menupopup.appendChild(this.createME(
"menuitem", "Profilordner",
function() { uProfMenu.prefDirOpen('ProfD'); },
"uProfMenu_folder", 0
));
menupopup.appendChild(this.createME(
"menuitem", "Icons-Ordner",
function() { uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm') + uProfMenu.getDirSep() + 'Icons'); },
"uProfMenu_folder", 0
));
menupopup.appendChild(this.createME(
"menuitem", "Installationsordner",
function() { uProfMenu.prefDirOpen('CurProcD'); },
"uProfMenu_folder", 0
));
menupopup.appendChild(this.createME(
"menuitem", "Addonordner",
function() { uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('ProfD') + uProfMenu.getDirSep() + 'extensions'); },
"uProfMenu_folder", 0
));
menupopup.appendChild(this.createME(
"menuitem", "Startup-Cacheordner",
function() { uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('ProfLD') + uProfMenu.getDirSep() + 'startupCache'); },
"uProfMenu_folder", 0
));
// Ende Einbindung von Ordnern
// --- ABOUT-SEITEN (ANGEPASST: Closure-Problem gelöst) ---
// Einbindung von abouts
if (this.abouts.length > 0) {
menupopup.appendChild(document.createXULElement('menuseparator'));
// falls der erste Eintrag des Arrays = '0' ist, dann kein Untermenue anlegen, sondern direkt als Menuepunkte einbinden
if (this.abouts[0] == '0') {
for (var i = 1; i < this.abouts.length; i++) {
(function(index) {
var about = uProfMenu.abouts[index];
menupopup.appendChild(uProfMenu.createME(
"menuitem", about,
function() { openTrustedLinkIn(about, 'tab'); },
"uProfMenu_about", 0
));
})(i);
}
} else {
// der erste Eintrag des arrays ist ungleich '0', deshalb als Untermenue einrichten
var submenu = menupopup.appendChild(this.createME("menu", "uc.js", null, 0, "submenu-about"));
var submenupopup = submenu.appendChild(this.createME("menupopup", null, null, 0, "submenu-about-items"));
this.fillMenu("submenu-about", "submenu-about-items", "about:", this.abouts, "uProfMenu_about", 1);
}
}
// Ende Einbindung von abouts
// Separator, falls dieser nicht schon durch abouts generiert wurde und weitere Menuepunkte folgen werden
// --- EINSTELLUNGEN & NEUSTART (ANGEPASST) ---
if (this.abouts.length == 0 && (this.showNormalPrefs || typeof(ToolRstartMod) != "undefined")) {
menupopup.appendChild(document.createXULElement('menuseparator'));
}
// Falls gewuenscht (s. Konfigurationsabschnitt), Zugriff auf die normalen Einstellungen
if (this.showNormalPrefs) {
menupopup.appendChild(this.createME(
"menuitem", "Einstellungen",
function() { try { openOptionsDialog(); } catch(e) { openPreferences(); } },
"uProfMenu_prefs", 0
));
}
// Falls addRestartButton installiert ist, Neustart zur Verfuegung stellen (addRestartButton 1.0.20120105mod erforderlich)
if (this.enableRestart) {
menupopup.appendChild(this.createME(
"menuitem", "Neustart",
function() {
Services.appinfo.invalidateCachesOnRestart();
Services.startup.quit(Ci.nsIAppStartup.eRestart | Ci.nsIAppStartup.eAttemptQuit, 0);
},
0, 0
));
}
},
// --- HILFSFUNKTIONEN (unchanged) ---
// Betriebssystem nach https://developer.mozilla.org/en/Code_snippets/Miscellaneous ermitteln
getDirSep: function() {
var osString = Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULRuntime).OS;
var dirsep = "/";
switch(osString) {
case "WINNT": dirsep = "\\"; break;
case "Linux": dirsep = "/"; break;
case "Darwin": dirsep = "/"; break;
}
return dirsep;
},
// --- EDIT (changed by Mira) ---
edit: function(OpenMode, Filename) {
var Path = "";
var dSep = this.getDirSep(); // die Trennzeichen zwischen Ordnern abhaengig vom Betriebssystem machen
// --- Pfad-Handling für chrome/scripts/ ---
if (Filename.includes("/") || Filename.includes("\\")) {
Path = this.getPrefDirectoryPath("ProfD") + dSep + Filename;
} else {
// Original-Logik
switch (OpenMode) {
//Current is Chrome Directory
case 0: Path = this.getPrefDirectoryPath("UChrm") + dSep + Filename; break;
//Current is Profile Directory
case 1: Path = this.getPrefDirectoryPath("ProfD") + dSep + Filename; break;
//Current is Root
case 2: Path = Filename; break;
//Current is CSS folder
case 3: Path = this.getPrefDirectoryPath("UChrm") + dSep + "CSS" + dSep + Filename; break;
//Current is CSSWeb folder
case 4: Path = this.getPrefDirectoryPath("UChrm") + dSep + "CSSWeb" + dSep + Filename; break;
//Current is CSSShadow folder
case 5: Path = this.getPrefDirectoryPath("UChrm") + dSep + "CSSShadow" + dSep + Filename; break;
}
}
this.launch(this.TextOpenExe, Path);
},
dirOpen: function(Path) {
if (this.vFileManager.length != 0) {
var file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
var process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess);
var args = [Path];
file.initWithPath(this.vFileManager);
process.init(file);
// Verzeichnis mit anderem Dateimanager oeffnen
process.run(false, args, args.length);
} else {
// Verzeichnis mit Dateimanager des Systems oeffnen
var dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
dir.initWithPath(Path);
dir.launch();
}
},
prefDirOpen: function(prefDir) {
var Path = this.getPrefDirectoryPath(prefDir);
this.dirOpen(Path);
},
getPrefDirectoryPath: function(str) {
// get profile directory
var file = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties)
.get(str, Components.interfaces.nsIFile);
if (str == 'CurProcD') file = file.parent;
return file.path;
},
launch: function(RanPath, OpenPath) {
var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsIFile);
var proc = Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess);
var args = [OpenPath];
file.initWithPath(RanPath);
// falls der im Konfigurationsabschnitt definierte Editor nicht gefunden wird, auf Einstellung in about:config ausweichen:
if (!file.exists()) {
var pref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
RanPath = pref.getCharPref("view_source.editor.path");
file.initWithPath(RanPath);
}
proc.init(file);
proc.run(false, args, args.length);
},
stringComparison: function(a, b) {
a = a.toLowerCase().replace(/ä/g,"a").replace(/ö/g,"o").replace(/ü/g,"u").replace(/ß/g,"s");
b = b.toLowerCase().replace(/ä/g,"a").replace(/ö/g,"o").replace(/ü/g,"u").replace(/ß/g,"s");
return (a == b) ? 0 : (a > b) ? 1 : -1;
},
// --- GETSCRIPTS (changed by Mira) ---
getScripts: function(iType) {
// Array nimmt Namen der gefundenen Skripte auf
let ucJsScripts = [];
// Suchmuster, also die Dateierweiterungen uc.js
let extjs = /\.uc\.js$/i;
// --- 1. Standard-UChrm-Ordner durchsuchen (ohne userChromeShadow.uc.js) ---
let uchrmFolder = Services.dirsvc.get("UChrm", Ci.nsIFile);
if (uchrmFolder.exists()) {
// files mit Eintraegen im Chrome-Ordner befuellen
let files = uchrmFolder.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);
// Ordner bzw. files durchlaufen und kontrollieren, ob gesuchte Dateien dabei sind
while (files.hasMoreElements()) {
let file = files.getNext().QueryInterface(Ci.nsIFile);
// uc.js gefunden -> im Array ablegen
if (extjs.test(file.leafName) && file.leafName !== "userChromeShadow.uc.js") {
ucJsScripts.push(file.leafName);
}
}
}
// --- 2. chrome/scripts-Ordner durchsuchen (falls vorhanden) ---
let chromeScriptsFolder = Services.dirsvc.get("ProfD", Ci.nsIFile);
chromeScriptsFolder.append("chrome");
chromeScriptsFolder.append("scripts");
if (chromeScriptsFolder.exists()) {
// files mit Eintraegen im Scripts-Ordner befuellen
let files = chromeScriptsFolder.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);
// Ordner bzw. files durchlaufen und kontrollieren, ob gesuchte Dateien dabei sind
while (files.hasMoreElements()) {
let file = files.getNext().QueryInterface(Ci.nsIFile);
// uc.js gefunden -> im Array ablegen
if (extjs.test(file.leafName)) {
ucJsScripts.push("chrome/scripts/" + file.leafName); // Pfad-Präfix für spätere Verarbeitung
}
}
}
if (this.sortScripts) ucJsScripts.sort(this.stringComparison);
// Aufruf der naechsten Methoden um die beiden Untermenues oder die Zwischenablage zu befuellen
if (iType == 0) {
this.fillMenu("submenu-ucjs", "submenu-ucjs-items", "Meine Scripte", ucJsScripts, "uProfMenu_ucjs", 0);
} else {
// Für Zwischenablage: Nur Dateinamen (ohne Pfad) verwenden
var simpleNames = ucJsScripts.map(f => f.split(/[\\/]/).pop());
var result = this.fillClipboardValue(simpleNames, []);
Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper).copyString(result);
}
},
// --- GETCSS (unchanged) ---
getCss: function(iType) {
// Array nimmt Namen der gefundenen css-Dateien auf
let cssFiles = [];
// Suchmuster, also die Dateierweiterung css
let extcss = /\.css$/i;
let aFolder = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
if (iType == 3) aFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path + this.getDirSep() + "CSS");
else if (iType == 4) aFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path + this.getDirSep() + "CSSWeb");
else if (iType == 5) aFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path + this.getDirSep() + "CSSShadow");
// files mit Eintraegen im CSS- bzw. CSSWeb-Ordner befuellen
let files = aFolder.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);
// Ordner bzw. files durchlaufen und kontrollieren, ob gesuchte Dateien dabei sind
while (files.hasMoreElements()) {
let file = files.getNext().QueryInterface(Ci.nsIFile);
// css gefunden -> im Array ablegen
if (extcss.test(file.leafName)) cssFiles.push(file.leafName);
}
if (this.sortScripts) cssFiles.sort(this.stringComparison);
// Untermenue befuellen
if (iType == 3) this.fillMenu("submenu-css", "submenu-css-items", "Meine CSS-Dateien", cssFiles, "uProfMenu_css", 3);
else if (iType == 4) this.fillMenu("submenu-cssweb", "submenu-cssweb-items", "Meine CSSWeb-Dateien", cssFiles, "uProfMenu_css", 4);
else if (iType == 5) this.fillMenu("submenu-CSSShadow", "submenu-CSSShadow-items", "Meine CSSShadow-Dateien", cssFiles, "uProfMenu_css", 5);
},
// --- FILLMENU (ANGEPASST: Closure-Problem gelöst + Event-Handler korrigiert) ---
fillMenu: function(whichsubmenu, whichsubmenuitems, strlabel, scriptArray, sClass, sTyp) {
// Beschriftung des Untermenues mit Anzahl der gefundenen Dateien ergaenzen
var e = document.getElementById(whichsubmenu);
e.setAttribute('label', strlabel + ' (' + scriptArray.length + ')');
var popup = document.getElementById(whichsubmenuitems);
// zunaechst Untermenue zuruecksetzen
while (popup.hasChildNodes()) popup.removeChild(popup.firstChild);
var uProfMenu = this; // Für Closure
// Untermenue endlich befuellen
for (var i = scriptArray.length - 1; i > -1; i--) {
(function(index) {
var fileName = scriptArray[index];
var mitem;
// Korrektur durch Mira
if (sTyp == 0) {
mitem = uProfMenu.createME("menuitem", fileName, null, sClass, 0);
// Extrahiere Dateinamen für Anzeige (z. B. "chrome/scripts/test.uc.js" → "test.uc.js")
var displayName = fileName.split(/[\\/]/).pop();
mitem.setAttribute('label', displayName);
mitem.addEventListener('command', function() {
uProfMenu.edit(0, fileName); // Original-Pfad (mit Präfix) an edit() übergeben
}, true);
mitem.addEventListener('click', function(event) {
uProfMenu.openAtGithub(event, displayName);
}, true);
mitem.setAttribute("tooltiptext", "Linksklick: Bearbeiten,\nMittelklick: https://github.com/.../" + uProfMenu.cleanFileName(displayName) + " öffnen,\nRechtsklick: Suche auf GitHub");
}
// Korrektur ENDE
else if (sTyp == 1) {
mitem = uProfMenu.createME("menuitem", fileName, function() {
openTrustedLinkIn(fileName, 'tab');
}, sClass, 0);
}
else if (sTyp == 3) {
mitem = uProfMenu.createME("menuitem", fileName, function() {
uProfMenu.edit(3, fileName);
}, sClass, 0);
}
else if (sTyp == 4) {
mitem = uProfMenu.createME("menuitem", fileName, function() {
uProfMenu.edit(4, fileName);
}, sClass, 0);
}
else if (sTyp == 5) {
mitem = uProfMenu.createME("menuitem", fileName, function() {
uProfMenu.edit(5, fileName);
}, sClass, 0);
}
popup.insertBefore(mitem, popup.firstChild);
})(i);
}
},
// --- FILLCLIPBOARDVALUE (changed by Mira) --- ganz neu !!
fillClipboardValue: function(sArray) {
var retValue = "Meine Skripte (" + sArray.length + "):\n------------------------";
for (var i = 0; i < sArray.length; i++) {
retValue += "\n" + (i + 1) + ". " + sArray[i];
}
return retValue;
},
// --- CREATEME (ANGEPASST: sCommand als Funktion) ---
createME: function(sTyp, sLabel, sCommand, sClass, sId) {
// Anlegen von menuitem, menu oder menupop - fuer bestimmte Typen nicht eingesetzte Parameter werden als 0 uebergeben
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var m = document.createElementNS(XUL_NS, sTyp);
switch (sTyp) {
case "menuitem":
// this.createME("menuitem","Label des Items","ZuzuweisenderCodeFueroncommand","GewuenschteKlasseDesItems",0)
m.setAttribute('label', sLabel);
m.setAttribute('class', sClass);
if (sCommand && typeof sCommand === 'function') {
m.addEventListener('command', sCommand, true);
}
break;
case "menu":
// this.createME("menu","Label des Menues",0,0,"GewuenschteIdDesMenues")
m.setAttribute('label', sLabel);
m.setAttribute('id', sId);
break;
case "menupopup":
//this.createME("menupopup",0,0,0,"GewuenschteIdDesMenupopups");
m.setAttribute('id', sId);
break;
}
return m;
},
// --- OPENATGITHUB (unchanged) ---
openAtGithub: function(e, sScript) {
if (e.button == 1) {
// Mittelklick - Seite auf GitHub oeffnen (funktioniert nur, wenn Ordner- und bereinigter Dateiname [ohne Erweiterung] uebereinstimmen):
var sUrl = "https://github.com/ardiman/userChrome.js/tree/master/" + this.cleanFileName(sScript);
openWebLinkIn(sUrl, 'tab');
}
if (e.button == 2) {
// Rechtsklick - Suche auf GitHub starten (funktioniert nur, wenn der Dateiname im Code hinterlegt ist):
e.preventDefault();
var sUrl = "https://github.com/search?langOverride=&language=&q=" + sScript + "&repo=&start_value=1&type=Code";
openWebLinkIn(sUrl, 'tab');
}
},
// --- CLEANFILENAME (unchanged) ---
cleanFileName: function(sName) {
/* Das folgende Array enthaelt regulaere Ausdruecke, um ungueltige Zeichenfolgen entfernen:
/Datei-Erweiterungen am Ende/, /"ucjs_" am Anfang/, /"_"gefolgtVonZahlUndDanachBeliebigenZeichen/
/ "_fx"gefolgtVonZahl(en)/, /"-" oder "+" oder "."/, /"_v"gefolgtVonZahlen
*/
sName = sName.toLowerCase();
var regs = [/\.uc\.js$/, /\.uc\.xul$/, /^ucjs_/, /_\d.+/, /_fx\d+/, /[-+\.]/g, /_v\d+/];
for (var i = 0; i < regs.length; i++) {
sName = sName.replace(regs[i], "");
}
return sName;
}
};
// Initialisierung
uProfMenu.init();
Alles anzeigen
Es gibt einige Änderungen mit der Erklärung (ANGEPASST: sCommand als Funktion). Welchen Vorteil hat das gegenüber der vorherigen Version?
Erklärung einer KI!
Der entscheidende Punkt ist, dass der ursprüngliche Code den Befehl als **Zeichenkette** (`"uProfMenu.getScripts(1)"`) übergibt. Solche Strings wurden früher von `createME` intern typischerweise mit `eval()` oder über das `command`-Attribut des Menüeintrags ausgeführt. Die neue Variante übergibt stattdessen ein **echtes Funktionsobjekt**.
Das bringt mehrere Vorteile:
**1. Sicherheit / CSP-Kompatibilität**
Firefox verbietet in modernen Extensions die Ausführung von Strings via `eval()` oder `setTimeout("…")` – das verstößt gegen die Content Security Policy. Eine echte Funktion ist davon nicht betroffen und läuft auch unter strikten CSP-Regeln.
**2. Performance**
Ein String muss bei jedem Aufruf neu geparst und kompiliert werden. Die Funktion ist bereits beim Definieren kompiliert und wird direkt aufgerufen.
**3. Scope / Variablenbindung**
Die Funktion ist eine echte Closure und hält den richtigen Gültigkeitsbereich (lexikalischer Scope). Ein per `eval` ausgeführter String läuft oft in einem anderen Kontext und kann lokale Variablen nicht zuverlässig sehen.
**4. Refactoring, Linting, Minifying**
Eine Funktion ist echter Code: Sie wird von Lintern analysiert, beim Umbenennen von `getScripts` aktualisiert und von Bundlern/Minifiern mitbearbeitet. Ein String bleibt für all diese Werkzeuge unsichtbar.
**5. Bessere Fehlermeldungen**
Bei einem Fehler in der Funktion zeigt der Stacktrace die echte Zeile im Skript. Bei `eval`-Strings steht oft nur etwas wie „eval code“ – schwerer zu debuggen.
Kurz: Aus dem String wird echter, vorab kompilierter, CSP-konformer Code, der im richtigen Scope läuft und von Werkzeugen richtig erfasst wird.
Alles anzeigen
Um die "Geschichte mit dem helpMenu kümmere ich mich noch!
Habe da so eine Idee.
Ich habe allerdings inzwischen eine an einigen Stellen abweichende Version, die ich deshalb beibehalte.
Wärst Du so nett und postest sie hier?
Eventuell kann ich ja davon etwas lernen und/oder übernehmen.
In der Version fehlen viele Erläuterungen im Vergleich zur Version für FF 135, sowohl für die Konfiguration als auch innerhalb des Skripts zur Funktion einzelner Teile.
Erläuterungen die Konfiguration wie auch innerhalb des Skripts zur Funktion einzelner Teile,
habe ich, so weit mir möglich, alle wieder eingefügt und ergänzt.
Sobald ich mit der Änderung Button/Menü, also der Geschichte helpMenu fertig bin,
gibt es das "neue" Skript.
Und aus welchem Grund genau sollte das Script nur auf Anfrage oder nur privat geteilt werden?
Weil ich schon einmal doof angemacht wurde, weil es ja gar nicht um "mein" Skript ging.
Ich bin nun erholt und in Zukunft etwas vorsichtiger!
Das Skript gibt es nicht exklusiv per PN!
Ich wurde inzwischen danach gefragt und hier kommt es.
Im weiteren Verlauf des Threads werden einige Optionen erklärt.
// BookmarkCount.uc.js
/* ******************************************************************************************************************* */
/* Author BrokenHeart => https://www.camp-firefox.de/forum/thema/136572/?postID=1229536#post1229536 **** */
/* Correction from BrokenHeart => https://www.camp-firefox.de/forum/thema/136572/?postID=1229696#post1229696 **** */
/* Extension from Sören Henschel => https://www.camp-firefox.de/forum/thema/136572/?postID=1229555#post1229555 **** */
/* Customized by Mira inspired by grisu2099 ********************************************************************** */
/* Source => https://www.camp-firefox.de/forum/thema/136572/?postID=1229875#post1229883 **** */
/* Customized by Mira inspired by Horstmann ********************************************************************** */
/* Source => https://www.camp-firefox.de/forum/thema/136572/?postID=1229993#post1229993 **** */
/* Adjustments for 139 and customized by Mira inspired by Horstmann ********************************************** */
/* Source => https://www.camp-firefox.de/forum/thema/136572/?postID=1270254#post1270254 **** */
/* Bugfixes for 'popupshowing' to 'popupshown'inspired by BrokenHeart & Horstmann ************************************ */
/* Source => https://www.camp-firefox.de/forum/thema/136572/?postID=1274881#post1274881 **** *
/* ******************************************************************************************************************* */
/* Version 1.04a => https://www.camp-firefox.de/forum/thema/136572/?postID=1274881#post1274881 **** */
/* Version 1.05 => https://www.camp-firefox.de/forum/thema/136572/?postID=1291576#post1291576 **** */
/* ******************************************************************************************************************* */
/* Custom Counter in the Bookmarks for folders and links ************************************************************* */
/* ******************************************************************************************************************* */
(function() {
if (!window.gBrowser) return;
setTimeout(function() { setFunction(); }, 10);
let ProfilePath = PathUtils.toFileURI(PathUtils.join(PathUtils.profileDir, 'chrome', 'icons'));
// ■■ START UserConfiguration ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
//Custom icons in profile/chrome/icons folder
let icon1 = "folder-fat.svg"; // Custom Folder Icon
let icon2 = "bookmark-hollow.svg"; // Custom Link Icon
let icon3 = "arrow-right.svg"; // Custom Arrow Icon
// Custom settings
let bm_font_size = 12;
let cs_font_weight = 700;
let bm_icon_size = 16;
// NEU: Schriftfarben getrennt definieren
//let cs_font_color_1 = "#FFA500"; // Farbe für Folder-Zähler (links)
//let cs_font_color_2 = "#00FFFF"; // Farbe für Link-Zähler (rechts)
let cs_font_color_1 = "#FFD700"; // Farbe für Folder-Zähler (links)
let cs_font_color_2 = "#FFD700"; // Farbe für Link-Zähler (rechts)
// NEU: Symbolfarben getrennt definieren
//let cs_icon_color_1 = "#5fe575"; // Farbe für "Ordner", 1.Symbol
//let cs_icon_color_2 = "#fbf328"; // Farbe für "Link", 2.Symbol
//let cs_icon_color_3 = "#bbf700"; // Farbe für den Pfeil
let cs_icon_color_1 = "#C0C0C0"; // Farbe für "Ordner", 1.Symbol
let cs_icon_color_2 = "#C0C0C0"; // Farbe für "Link", 2.Symbol
let cs_icon_color_3 = "#C0C0C0"; // Farbe für den Pfeil
// NEU: Farbe für die Zahlenwerte und Symbole beim Hovern.
let cs_font_hovercolor_1 = "#FFD700"; // Farbe für Folder-Zähler (links)
let cs_font_hovercolor_2 = "#FFD700"; // Farbe für Link-Zähler (rechts) "#80ffff";
let cs_icon_hovercolor_1 = "#C0C0C0"; // Farbe für "Ordner", 1.Symbol "#ff0000";
let cs_icon_hovercolor_2 = "#C0C0C0"; // Farbe für "Link", 2.Symbol "#00ff00";
let cs_icon_hovercolor_3 = "#ffff80"; // Farbe für den Pfeil
// Calculated settings
let cs_font_size = `${bm_font_size}px`;
let cs_icon_size = `${bm_icon_size}px`;
let cs_width_one = `calc(${bm_icon_size}px + 1.4em)`;
let cs_width_uno = `calc(${bm_icon_size}px)`;
let cs_width_two = `calc(${bm_icon_size}px + 1.4em)`;
let cs_width_due = `calc(${bm_icon_size}px)`;
//let useStyle1 = true; // <- HIER Weiche setzen: true = Variante 1, false = Variante 2
let useStyle = 1; // <- HIER Weiche setzen: 0 = Symbole hinter den Zählern, 1 = Symbole vor den Zählern
// ■■ END UserConfiguration ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
// Symbole vor den Zählern
let css_one = `
#bmContent::before {
content: attr(data-value1) !important;
width: ${cs_width_one} !important;
align-items: center !important;
display: flex !important;
justify-content: end !important;
margin-left: 16px !important;
margin-right: -1px !important;
background-image: url("${ProfilePath}/${icon1}")!important;
background-position: center right calc(${cs_width_one} - ${cs_icon_size}) !important;
background-repeat: no-repeat !important;
background-size: ${cs_icon_size} ${cs_icon_size} !important;
color: ${cs_font_color_1} !important;
fill: ${cs_icon_color_1} !important;
}
#bmContent::after {
content: attr(data-value2) !important;
width: ${cs_width_two} !important;
align-items: center !important;
display: flex !important;
justify-content: end !important;
margin-left: 4px !important;
margin-right: -1px !important;
background-image: url("${ProfilePath}/${icon2}") !important;
background-position: center right calc(${cs_width_two} - ${cs_icon_size}) !important;
background-repeat: no-repeat !important;
background-size: ${cs_icon_size} ${cs_icon_size} !important;
color: ${cs_font_color_2} !important;
fill: ${cs_icon_color_2} !important;
}
`;
// Symbole hinter den Zählern
let css_two = `
#bmContent::before {
content: attr(data-value1) !important;
width: ${cs_width_one} !important;
align-items: center !important;
display: flex !important;
justify-content: end !important;
background-image: url("${ProfilePath}/${icon1}")!important;
background-position: center right calc(${cs_width_uno} - ${cs_icon_size}) !important;
background-repeat: no-repeat !important;
background-size: ${cs_icon_size} ${cs_icon_size} !important;
color: ${cs_font_color_1} !important;
fill: ${cs_icon_color_1} !important;
padding: 2px 20px 0px 10px !important;
margin-left: 16px !important;
margin-right: 12px !important;
}
#bmContent::after {
content: attr(data-value2) !important;
width: ${cs_width_two} !important;
align-items: center !important;
display: flex !important;
justify-content: end !important;
background-image: url("${ProfilePath}/${icon2}")!important;
background-position: center right calc(${cs_width_due} - ${cs_icon_size}) !important;
background-repeat: no-repeat !important;
background-size: ${cs_icon_size} ${cs_icon_size} !important;
color: ${cs_font_color_2} !important;
fill: ${cs_icon_color_2} !important;
padding: 2px 22px 0 0 !important;
margin-left: -14px !important;
margin-right: -1px !important;
}
`;
function setFunction() {
const css =`
/* Fix für Firefox Nightly - Label als Flex-Container */
#bookmarksMenuPopup > menu > label,
#bookmarksMenuPopup > menu > menupopup > menu > label,
#bookmarksMenuPopup > menu > menupopup > menu > menupopup > menu > label,
#PlacesToolbarItems > .bookmark-item > menupopup > menu > label {
display: flex !important;
justify-content: space-between !important;
}
/* Counter Container */
#bmContent {
display: flex !important;
margin-inline: auto 0 !important;
font-family: Consolas, "Lucida Console", "Courier New", monospace !important;
font-size: ${cs_font_size} !important;
font-weight: ${cs_font_weight} !important;
height: ${cs_icon_size} !important;
}
/* Dynamisch gewählter Counter-Stil */
${useStyle ? css_one : css_two}
/* Pfeil */
menupopup > menu::after {
content: "" !important;
background-image: url("${ProfilePath}/${icon3}")!important;
height: ${cs_icon_size} !important;
fill: ${cs_icon_color_3} !important;
margin-inline: 0 !important;
}
/* Farbe für die Zahlenwerte und Symbole beim Hovern. */
menupopup[placespopup="true"] > menu.bookmark-item:hover > .menu-text > #bmContent::before {
color: ${cs_font_hovercolor_1} !important;
fill: ${cs_icon_hovercolor_1} !important;
}
menupopup[placespopup="true"] > menu.bookmark-item:hover > .menu-text > #bmContent::after {
color: ${cs_font_hovercolor_2} !important;
fill: ${cs_icon_hovercolor_2} !important;
}
/* Farbe für den Pfeil beim Hovern. */
menupopup > menu:hover::after {
fill: ${cs_icon_hovercolor_3} !important; }
}
`;
const sss = Cc['@mozilla.org/content/style-sheet-service;1'].getService(Ci.nsIStyleSheetService);
const uri = Services.io.newURI('data:text/css,' + encodeURIComponent(css));
sss.loadAndRegisterSheet(uri, sss.AGENT_SHEET);
let bmbMenu = document.getElementById('bookmarks-menu-button');
let bookMenu = document.getElementById('bookmarksMenu');
let persToolBar = document.getElementById('PersonalToolbar');
if(bmbMenu) {
let bmbMenuPopup = document.getElementById('BMB_bookmarksPopup');
if(bmbMenuPopup) {
bmbMenuPopup.openPopup();
bmbMenuPopup.hidePopup();
bmbMenuPopup.setAttribute("hasbeenopened","true");
}
bmbMenu.addEventListener('popupshowing', onPopupShowing);
}
if(bookMenu) {
let bookMenuPopup = document.getElementById('bookmarksMenuPopup');
if(bookMenuPopup) {
bookMenuPopup.openPopup();
bookMenuPopup.hidePopup();
bookMenuPopup.setAttribute("hasbeenopened","true");
}
bookMenu.addEventListener('popupshowing', onPopupShowing);
}
if(persToolBar) {
persToolBar.addEventListener('popupshown', onPopupShowing);
}
}
function onPopupShowing(aEvent) {
let popup = aEvent.originalTarget;
for (let item of popup.children) {
if (item.localName != 'menu' || item.id?.startsWith('history')) continue;
setTimeout(() => {
let itemPopup = item.menupopup;
itemPopup.hidden = true;
itemPopup.collapsed = true;
itemPopup.openPopup();
itemPopup.hidePopup();
let menuitemCount = 0;
let menuCount = 0;
for (let subitem of itemPopup.children) {
if (subitem.classList.contains('bookmark-item') && !subitem.disabled && !subitem.hidden) {
if (subitem.localName == 'menuitem') menuitemCount++;
else if (subitem.localName == 'menu') menuCount++;
}
}
itemPopup.hidden = false;
itemPopup.collapsed = false;
// Neues Element für Zaehler
let bmCounta = item.childNodes[1];
if (!bmCounta) return; // Falls undefiniert
bmCounta.innerHTML = "";
let bmContent = document.createElement("bmContent");
bmContent.id = "bmContent";
bmCounta.appendChild(bmContent);
//let strCountOut1 = " " + menuCount + " "; // Has no brackets
//let strCountOut1 = "(" + menuCount + ")"; // Has round brackets
//let strCountOut1 = "[" + menuCount + "]"; // Has square brackets
let strCountOut1 = String(menuCount).padEnd(2, " ");
bmContent.setAttribute('data-value1', strCountOut1);
//let strCountOut2 = " " + menuitemCount + " "; // Has no brackets
//let strCountOut2 = "(" + menuitemCount + ")"; // Has round brackets
//let strCountOut2 = "[" + menuitemCount + "]"; // Has square brackets
// let strCountOut2 = String(menuitemCount).padEnd(2, " ");
// bmContent.setAttribute('data-value2', strCountOut2);
let strCountOut2 = (useStyle === 0)
? String(menuitemCount).padStart(4, "/ ") // (5, " | ")
: String(menuitemCount).padEnd(2, " "); //1 rechtsbündig / 2 linksbündig
bmContent.setAttribute('data-value2', strCountOut2);
}, 100);
}
}
})();
Alles anzeigen
Und auch hier habe ich schon eine ganze Weile ein funktionierendes Skript!
Poste es nur auf Wunsch,
Da ist man einmal im Urlaub, ts.
Das Skript funktionierte schon eine ganze Weile in der Nigtly so nicht mehr.
Und da ich in Urlaub war, konnte ich zwar verfolgen was hier geschah,
aber nicht eingreifen!
Das originale korrigierte Skript habe ich natürlich,
poste es aber nur auf Nachfrage.
Solch kleine Ungereimtheiten kann ich erst später ausbügeln!
Es funktioniert ja erst einmal.
Und ich würde ja schon sagen, dass es noch nicht ganz einer Endversion entspricht
Um den Konigbereich werde ich mich dann auch noch kümmern und mit Sicherheit erweitern, damit niand mehr im Code änderungen vornehmen muss.
So, genug von meiner Seite.
Testet weiter, schreibt, was nicht klappt oder was im Code noch verbessert werden könnte oder ob es da noch Leichen gibt.
So long...
Was passierte denn bisher bei Linksklick?
Ich beantworte mal meine Frage selber!!
Nichts.
Werde mir überlegen, ob ich das wieder auf den Mittelklick lege,
oder ob es in dem Konfigbereich dafür eine Einstellung geben wird,
oder, ob auf eine Taste, Mitte oder Rechte eine weitere Funktion drauf kommt!
Könnt ja mal darüber diskutieren.
Einstellungen oder ...
Überlegt mal was am ehesten Sinn ergibt.
Mh, ob wohl ich Option 1 präferiere.
Dann kann jeder selber festlegen mit welcher Taste der Tab mit about:config sich öffnet.
Gute n8
werde alles Weitere per Smartphone hier verfolgen,
eventuell auch mal eine Nachricht hinterlassen,
aber am Skript werde ich nichts mehr machen.
Bin dann mal weg.
Mein Schiff ich koooooome.
Schreibe ich so verwirrend?
Es geht nicht ums Menü!!
Aber, ja, ich werde die betreffend Zeile
var retValue = "Installierte Skripte (" + sArray.length + "):\n------------------------";
in
var retValue = "Meine Skripte (" + sArray.length + "):\n------------------------";
ändern![]()
Dann passt das alles auch zusammen!
Ergibt Sinn.
---------------------------------------------------------
Ist erledigt![]()
Mitleser
Das Script wurde von mir nur Fehlerbereinigt und moderat angepasst!
Es funktioniert genau so, wie das Ursprüngliche auch!
Wenn das Ursprüngliche für Linux, und wahrscheinlich auch für Apple angepasst werden musste,
so dann auch diese Version.
Bei dem Ausdruck "Eigene Skripte", ging es nur um die oberste Zeile,
wenn Du auf "Skriptliste in Zwischenablage" klickst
und dann alles aus der Zwischenablage dann irgendwo einfügst!
Siehe hier, einfach aus der Zwischenablage hier eingefügt:
Eigene Skripte (5):
------------------------
1. # check.uc.js
2. # 1 extensionsUpdateChecker.uc.js
3. # 1_TEST.uc.js
4. # 1_TEST_2.uc.js
5. # FoxInstanzStarter.uc.js
"Userskripte" oder "Benutzte Skripte" oder "Installierte Skripte" fielen mir ein.
Gefällt mir aber alles nicht so wirklich.
Daher die Frage, ob jemand einen besseren Begriff parat hat. ![]()
Wenn es keine Vorschläge geben sollte, tendiere ich dann doch z.Z. am ehesten zu "Userskripte".
Aber ich bin wankelmütig![]()
Kann morgen schon wieder ganz anders sein.
Ich konnte es nachvollziehen, ob wohl ich nicht vom Fach bin!
Klar, mithilfe des Werkzeuges bekomme ich auch so einiges hin.
Doch wirklich "programmieren" kann ich nicht!!
Für mich ist es eher wie hacken!
Aber im Gegensatz zu manch anderen lasse ich mir sehr oft
so ein Skript Zeile für Zeile von dem Werkzeug erklären,
damit ich so einigermaßen verstehe, was da so passiert und was der Code so macht.
Das eine oder andere habe ich tatsächlich gelernt und muss nicht bei jeder kleinen Änderung die KI bemühen.
Aber im Artikel ging es ja auch um noch tiefere Schichten und da bin ich definitiv raus!!
Er hat es aber sehr schön beschrieben!!
Vom Macher und Lösungsfinder zum Kontrolleur.
Bereinigte und überarbeitete Version!
/*
// ==UserScript==
// @name extras_config_menu.uc.js
// @compatibility Firefox 153*.*
// @include main
// @version 1.0.20260812
// @edit @aborix 7/21 CSS Dateien als Untermenü eingefügt
// @edit @2002Andreas 8/21 Shadow CSS Dateien als Untermenü + Ordner eingefügt
// @edit @BrokenHeart 1/25 Anpass. wg. Änderung der Sicherheitsrichtlinien bei 'inlineEvents'
// @edit @Mira 8/26 Anpassung für security.allow_unsafe_dangerous_privileged_evil_eval = false
// @edit @Mira 8/26 Anpassung für Userscripte im Unterordner "chrome/scripts", Expliziter Ausschluss von "userChromeShadow.uc.js"
// @edit @Mira 8/26 Anpassung für "Skriptliste in Zwischenablage"
// ==/UserScript==
*/
var uProfMenu = {
// --- KONFIGURATION (unchanged) ---
TextOpenExe: 'C:\\Program Files\\Microsoft VS Code\\Code.exe',
vFileManager: '',
warpmenuto: 'helpMenu',
sortScripts: 0,
gmOrdner: 0,
cssOrdner: 1,
abouts: ['about:about','about:addons','about:cache','about:config','about:crashes',
'about:downloads','about:home','about:logins','about:memory','about:support',
'about:preferences','about:performance','about:profiles'
],
showNormalPrefs: 1,
enableScriptsToClip: 2,
enableRestart: 0,
// --- INIT (ANGEPASST) ---
init: function() {
if (this.warpmenuto.toLowerCase() == 'menu') {
var zielmenu = document.getElementById('menu_ToolsPopup');
if (zielmenu == null) {
userChrome.log("extras_config_menu.uc.js findet Zielmenue nicht, evtl. weil ein anderes Fenster als das Hauptfenster geoeffnet wurde.");
return;
}
var menu = zielmenu.appendChild(this.createME("menu", "Config Men\u00FC", null, 0, "ExtraConfigMenu"));
menu.setAttribute("class", "menu-iconic");
// Ersetze ondblclick durch addEventListener
menu.addEventListener('dblclick', function() {
openTrustedLinkIn('about:config', 'tab');
}, true);
} else {
if (window.__SSi == "window0") {
CustomizableUI.createWidget({
id: "ExtraConfigMenu-button",
defaultArea: CustomizableUI.AREA_NAVBAR,
label: "Extra Config Menü",
tooltiptext: "Extra Config Menü\nRechtsklick öffnet about:config"
});
}
var menu = document.getElementById("ExtraConfigMenu-button");
// KORREKTUR:
if (!menu) {
return;
}
menu.setAttribute("type", "menu");
menu.addEventListener('click', function(event) {
if (event.button == 2 && !this.open) {
openTrustedLinkIn("about:config", "tab");
event.preventDefault();
}
}, true);
}
// CSS-Styles (unchanged)
var css = " \
#ExtraConfigMenu, #ExtraConfigMenu-button { \
list-style-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACnElEQVR4Xm2RzYtbZRSHn/fr3pvJzTB3qiNM2k2pMBUGhEHaqsUqdeFGQalCobgREaFu/B/cqCtxVSjoQhBEQRBmIfWDKgNGJUPt0Nhah9JJ4iSd5E6+bu5972tAO4SS5/DjXZ1znsMrNiq1eikMQqYYJCmjxNH5+zdW777L0J5KKl9VPmnf+ut9KWkwhbheuzNcOVYOmGKc5iRO0r1ykeXCx0h7kt4fC3z5wfqbQnAJwQHa5S7jAZSRuJ0mkf81cheobhBXZa+ri1uptQjHAZoZCEC1PiPgDuwxCfwerBU7b73zXn//3usCcdt4HkZ7SGZg431U51NUCgwlO3cV/bVXhR/6p9ut+nP9QYeNn7/n8qUPZxvQ/Q6VVWHk4ZqWRvlJjpx9hcGfW2wO95N2q8m3618A2WwDt/0RplSAXsBed57eyossHl5GYdHacG3zGpADM06wjQ1UUIN+CLHPvfAxojPnKLiE+bDE1R9+5GatAmgPeGCAteQ7l5GBhGSyuROyd/gFouUyWkqEErR2mwXAAA8BRS0AgMQBjSra30ZkEeDzz9Dn4ZcvMO51SMcJcTdGChmA0ABA6cAgzyG3I8jLEBylV4fWoaeIc0V7t0Uv7pFbC+CA+28mp/8+SwXKnMVmz1O9HpE+eobMZdjcoY1GIHD/NwIdoH1fBaNguzlg88pVyoUi4vTbFI8eJxsNAIfSkrliESllH/L0v0jktNNomFGv1TFrL3Fo9QSMR3jaEEXzLC09gjaKp595No0WjyCEB4zRclICUMDxtRMce/wJ1MIi2SglXShhfI/cOjxPoZRmbq4gXzt/gVrtBrdvbiG+Wf+p/mvll1BpiVAGhCDPxuAUDotz4HKHlIJON6bRbL4hhPjcMx5mkn8BBLEUrsVZbq0AAAAASUVORK5CYII=); \
margin-top: 0px !important; \
opacity: 1 !important; \
} \
#ExtraConfigMenu-button > dropmarker, #ExtraConfigMenu-button > hbox > .toolbarbutton-menu-dropmarker { \
display: none !important; \
}";
var sss = Cc['@mozilla.org/content/style-sheet-service;1'].getService(Ci.nsIStyleSheetService);
var uri = makeURI('data:text/css;charset=UTF-8,' + encodeURIComponent(css));
sss.loadAndRegisterSheet(uri, sss.AGENT_SHEET);
// Menü-Popup erstellen
var menupopup = menu.appendChild(this.createME("menupopup", null, null, 0, "ExtraConfigMenu-popup"));
// Event-Listener für popupshowing (unchanged, aber sicher)
menu.addEventListener('popupshowing', function(event) {
uProfMenu.getScripts(0);
uProfMenu.getCss(3);
uProfMenu.getCss(4);
uProfMenu.getCss(5);
}, true);
// --- UNTERMENÜS (unchanged) ---
var submenu = menupopup.appendChild(this.createME("menu", "Meine Scripte", null, 0, "submenu-ucjs"));
var submenupopup = submenu.appendChild(this.createME("menupopup", null, null, 0, "submenu-ucjs-items"));
var submenu = menupopup.appendChild(this.createME("menu", "css", null, 0, "submenu-css"));
var submenupopup = submenu.appendChild(this.createME("menupopup", null, null, 0, "submenu-css-items"));
var submenu = menupopup.appendChild(this.createME("menu", "CSSShadow", null, 0, "submenu-CSSShadow"));
var submenupopup = submenu.appendChild(this.createME("menupopup", null, null, 0, "submenu-CSSShadow-items"));
var submenu = menupopup.appendChild(this.createME("menu", "cssweb", null, 0, "submenu-cssweb"));
var submenupopup = submenu.appendChild(this.createME("menupopup", null, null, 0, "submenu-cssweb-items"));
// Skriptliste in Zwischenablage (ANGEPASST: sCommand als Funktion)
if (this.enableScriptsToClip) {
menupopup.appendChild(this.createME(
"menuitem",
"Skriptliste in Zwischenablage",
function() { uProfMenu.getScripts(1); },
"uProfMenu_clipboard",
0
));
}
menupopup.appendChild(document.createXULElement('menuseparator'));
// --- KONFIGDATEIEN (ANGEPASST: sCommand als Funktion) ---
menupopup.appendChild(this.createME(
"menuitem", "Bild Url",
function() { uProfMenu.edit(0, 'Bild Url.css'); },
"uProfMenu_edit", 0
));
menupopup.appendChild(this.createME(
"menuitem", "config Einträge.css",
function() { uProfMenu.edit(0, 'config Einträge.css'); },
"uProfMenu_edit", 0
));
menupopup.appendChild(this.createME(
"menuitem", "userChrome.css",
function() { uProfMenu.edit(0, 'userChrome.css'); },
"uProfMenu_edit", 0
));
menupopup.appendChild(this.createME(
"menuitem", "userChromeShadow.css",
function() { uProfMenu.edit(0, 'userChromeShadow.css'); },
"uProfMenu_edit", 0
));
menupopup.appendChild(this.createME(
"menuitem", "userContent.css",
function() { uProfMenu.edit(0, 'userContent.css'); },
"uProfMenu_edit", 0
));
menupopup.appendChild(this.createME(
"menuitem", "userChrome.js",
function() { uProfMenu.edit(0, 'userChrome.js'); },
"uProfMenu_edit", 0
));
menupopup.appendChild(this.createME(
"menuitem", "prefs.js",
function() { uProfMenu.edit(1, 'prefs.js'); },
"uProfMenu_edit", 0
));
menupopup.appendChild(this.createME(
"menuitem", "user.js",
function() { uProfMenu.edit(1, 'user.js'); },
"uProfMenu_edit", 0
));
// --- ORDNER (ANGEPASST: sCommand als Funktion) ---
menupopup.appendChild(document.createXULElement('menuseparator'));
switch (this.gmOrdner) {
case 1:
menupopup.appendChild(this.createME(
"menuitem", "GM-skripty",
function() { uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('ProfD') + uProfMenu.getDirSep() + 'gm_scripts'); },
"uProfMenu_folder", 0
));
break;
case 2:
menupopup.appendChild(this.createME(
"menuitem", "USL-skripty",
function() { uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm') + uProfMenu.getDirSep() + 'UserScriptLoader'); },
"uProfMenu_folder", 0
));
break;
case 3:
menupopup.appendChild(this.createME(
"menuitem", "Skripty Scriptish",
function() { uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('ProfD') + uProfMenu.getDirSep() + 'scriptish_scripts'); },
"uProfMenu_folder", 0
));
break;
}
menupopup.appendChild(this.createME(
"menuitem", "CSS-Ordner",
function() { uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm') + uProfMenu.getDirSep() + 'css'); },
"uProfMenu_folder", 0
));
menupopup.appendChild(this.createME(
"menuitem", "CSSShadow-Ordner",
function() { uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm') + uProfMenu.getDirSep() + 'CSSShadow'); },
"uProfMenu_folder", 0
));
menupopup.appendChild(this.createME(
"menuitem", "CSSWeb-Ordner",
function() { uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm') + uProfMenu.getDirSep() + 'CSSWeb'); },
"uProfMenu_folder", 0
));
menupopup.appendChild(this.createME(
"menuitem", "Chromeordner",
function() { uProfMenu.prefDirOpen('UChrm'); },
"uProfMenu_folder", 0
));
menupopup.appendChild(this.createME(
"menuitem", "Profilordner",
function() { uProfMenu.prefDirOpen('ProfD'); },
"uProfMenu_folder", 0
));
menupopup.appendChild(this.createME(
"menuitem", "Icons-Ordner",
function() { uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm') + uProfMenu.getDirSep() + 'Icons'); },
"uProfMenu_folder", 0
));
menupopup.appendChild(this.createME(
"menuitem", "Installationsordner",
function() { uProfMenu.prefDirOpen('CurProcD'); },
"uProfMenu_folder", 0
));
menupopup.appendChild(this.createME(
"menuitem", "Addonordner",
function() { uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('ProfD') + uProfMenu.getDirSep() + 'extensions'); },
"uProfMenu_folder", 0
));
menupopup.appendChild(this.createME(
"menuitem", "Startup-Cacheordner",
function() { uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('ProfLD') + uProfMenu.getDirSep() + 'startupCache'); },
"uProfMenu_folder", 0
));
// --- ABOUT-SEITEN (ANGEPASST: Closure-Problem gelöst) ---
if (this.abouts.length > 0) {
menupopup.appendChild(document.createXULElement('menuseparator'));
if (this.abouts[0] == '0') {
for (var i = 1; i < this.abouts.length; i++) {
(function(index) {
var about = uProfMenu.abouts[index];
menupopup.appendChild(uProfMenu.createME(
"menuitem", about,
function() { openTrustedLinkIn(about, 'tab'); },
"uProfMenu_about", 0
));
})(i);
}
} else {
var submenu = menupopup.appendChild(this.createME("menu", "uc.js", null, 0, "submenu-about"));
var submenupopup = submenu.appendChild(this.createME("menupopup", null, null, 0, "submenu-about-items"));
this.fillMenu("submenu-about", "submenu-about-items", "about:", this.abouts, "uProfMenu_about", 1);
}
}
// --- EINSTELLUNGEN & NEUSTART (ANGEPASST) ---
if (this.abouts.length == 0 && (this.showNormalPrefs || typeof(ToolRstartMod) != "undefined")) {
menupopup.appendChild(document.createXULElement('menuseparator'));
}
if (this.showNormalPrefs) {
menupopup.appendChild(this.createME(
"menuitem", "Einstellungen",
function() { try { openOptionsDialog(); } catch(e) { openPreferences(); } },
"uProfMenu_prefs", 0
));
}
if (this.enableRestart) {
menupopup.appendChild(this.createME(
"menuitem", "Neustart",
function() {
Services.appinfo.invalidateCachesOnRestart();
Services.startup.quit(Ci.nsIAppStartup.eRestart | Ci.nsIAppStartup.eAttemptQuit, 0);
},
0, 0
));
}
},
// --- HILFSFUNKTIONEN (unchanged) ---
getDirSep: function() {
var osString = Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULRuntime).OS;
var dirsep = "/";
switch(osString) {
case "WINNT": dirsep = "\\"; break;
case "Linux": dirsep = "/"; break;
case "Darwin": dirsep = "/"; break;
}
return dirsep;
},
// --- EDIT (changed by Mira) ---
edit: function(OpenMode, Filename) {
var Path = "";
var dSep = this.getDirSep();
// --- Pfad-Handling für chrome/scripts/ ---
if (Filename.includes("/") || Filename.includes("\\")) {
Path = this.getPrefDirectoryPath("ProfD") + dSep + Filename;
} else {
// Original-Logik
switch (OpenMode) {
case 0: Path = this.getPrefDirectoryPath("UChrm") + dSep + Filename; break;
case 1: Path = this.getPrefDirectoryPath("ProfD") + dSep + Filename; break;
case 2: Path = Filename; break;
case 3: Path = this.getPrefDirectoryPath("UChrm") + dSep + "CSS" + dSep + Filename; break;
case 4: Path = this.getPrefDirectoryPath("UChrm") + dSep + "CSSWeb" + dSep + Filename; break;
case 5: Path = this.getPrefDirectoryPath("UChrm") + dSep + "CSSShadow" + dSep + Filename; break;
}
}
this.launch(this.TextOpenExe, Path);
},
dirOpen: function(Path) {
if (this.vFileManager.length != 0) {
var file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
var process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess);
var args = [Path];
file.initWithPath(this.vFileManager);
process.init(file);
process.run(false, args, args.length);
} else {
var dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
dir.initWithPath(Path);
dir.launch();
}
},
prefDirOpen: function(prefDir) {
var Path = this.getPrefDirectoryPath(prefDir);
this.dirOpen(Path);
},
getPrefDirectoryPath: function(str) {
var file = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties)
.get(str, Components.interfaces.nsIFile);
if (str == 'CurProcD') file = file.parent;
return file.path;
},
launch: function(RanPath, OpenPath) {
var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsIFile);
var proc = Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess);
var args = [OpenPath];
file.initWithPath(RanPath);
if (!file.exists()) {
var pref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
RanPath = pref.getCharPref("view_source.editor.path");
file.initWithPath(RanPath);
}
proc.init(file);
proc.run(false, args, args.length);
},
stringComparison: function(a, b) {
a = a.toLowerCase().replace(/ä/g,"a").replace(/ö/g,"o").replace(/ü/g,"u").replace(/ß/g,"s");
b = b.toLowerCase().replace(/ä/g,"a").replace(/ö/g,"o").replace(/ü/g,"u").replace(/ß/g,"s");
return (a == b) ? 0 : (a > b) ? 1 : -1;
},
// --- GETSCRIPTS (changed by Mira) ---
getScripts: function(iType) {
let ucJsScripts = [];
let extjs = /\.uc\.js$/i;
// --- 1. Standard-UChrm-Ordner durchsuchen (ohne userChromeShadow.uc.js) ---
let uchrmFolder = Services.dirsvc.get("UChrm", Ci.nsIFile);
if (uchrmFolder.exists()) {
let files = uchrmFolder.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);
while (files.hasMoreElements()) {
let file = files.getNext().QueryInterface(Ci.nsIFile);
if (extjs.test(file.leafName) && file.leafName !== "userChromeShadow.uc.js") {
ucJsScripts.push(file.leafName);
}
}
}
// --- 2. chrome/scripts-Ordner durchsuchen (falls vorhanden) ---
let chromeScriptsFolder = Services.dirsvc.get("ProfD", Ci.nsIFile);
chromeScriptsFolder.append("chrome");
chromeScriptsFolder.append("scripts");
if (chromeScriptsFolder.exists()) {
let files = chromeScriptsFolder.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);
while (files.hasMoreElements()) {
let file = files.getNext().QueryInterface(Ci.nsIFile);
if (extjs.test(file.leafName)) {
ucJsScripts.push("chrome/scripts/" + file.leafName); // Pfad-Präfix für spätere Verarbeitung
}
}
}
if (this.sortScripts) ucJsScripts.sort(this.stringComparison);
if (iType == 0) {
this.fillMenu("submenu-ucjs", "submenu-ucjs-items", "Meine Scripte", ucJsScripts, "uProfMenu_ucjs", 0);
} else {
// Für Zwischenablage: Nur Dateinamen (ohne Pfad) verwenden
var simpleNames = ucJsScripts.map(f => f.split(/[\\/]/).pop());
var result = this.fillClipboardValue(simpleNames, []);
Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper).copyString(result);
}
},
// --- GETCSS (unchanged) ---
getCss: function(iType) {
let cssFiles = [];
let extcss = /\.css$/i;
let aFolder = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
if (iType == 3) aFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path + this.getDirSep() + "CSS");
else if (iType == 4) aFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path + this.getDirSep() + "CSSWeb");
else if (iType == 5) aFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path + this.getDirSep() + "CSSShadow");
let files = aFolder.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);
while (files.hasMoreElements()) {
let file = files.getNext().QueryInterface(Ci.nsIFile);
if (extcss.test(file.leafName)) cssFiles.push(file.leafName);
}
if (this.sortScripts) cssFiles.sort(this.stringComparison);
if (iType == 3) this.fillMenu("submenu-css", "submenu-css-items", "Meine CSS-Dateien", cssFiles, "uProfMenu_css", 3);
else if (iType == 4) this.fillMenu("submenu-cssweb", "submenu-cssweb-items", "Meine CSSWeb-Dateien", cssFiles, "uProfMenu_css", 4);
else if (iType == 5) this.fillMenu("submenu-CSSShadow", "submenu-CSSShadow-items", "Meine CSSShadow-Dateien", cssFiles, "uProfMenu_css", 5);
},
// --- FILLMENU (ANGEPASST: Closure-Problem gelöst + Event-Handler korrigiert) ---
fillMenu: function(whichsubmenu, whichsubmenuitems, strlabel, scriptArray, sClass, sTyp) {
var e = document.getElementById(whichsubmenu);
e.setAttribute('label', strlabel + ' (' + scriptArray.length + ')');
var popup = document.getElementById(whichsubmenuitems);
while (popup.hasChildNodes()) popup.removeChild(popup.firstChild);
var uProfMenu = this; // Für Closure
for (var i = scriptArray.length - 1; i > -1; i--) {
(function(index) {
var fileName = scriptArray[index];
var mitem;
// Korrektur durch Mira
if (sTyp == 0) {
mitem = uProfMenu.createME("menuitem", fileName, null, sClass, 0);
// Extrahiere Dateinamen für Anzeige (z. B. "chrome/scripts/test.uc.js" → "test.uc.js")
var displayName = fileName.split(/[\\/]/).pop();
mitem.setAttribute('label', displayName);
mitem.addEventListener('command', function() {
uProfMenu.edit(0, fileName); // Original-Pfad (mit Präfix) an edit() übergeben
}, true);
mitem.addEventListener('click', function(event) {
uProfMenu.openAtGithub(event, displayName);
}, true);
mitem.setAttribute("tooltiptext", "Linksklick: Bearbeiten,\nMittelklick: https://github.com/.../" + uProfMenu.cleanFileName(displayName) + " öffnen,\nRechtsklick: Suche auf GitHub");
}
// Korrektur ENDE
else if (sTyp == 1) {
mitem = uProfMenu.createME("menuitem", fileName, function() {
openTrustedLinkIn(fileName, 'tab');
}, sClass, 0);
}
else if (sTyp == 3) {
mitem = uProfMenu.createME("menuitem", fileName, function() {
uProfMenu.edit(3, fileName);
}, sClass, 0);
}
else if (sTyp == 4) {
mitem = uProfMenu.createME("menuitem", fileName, function() {
uProfMenu.edit(4, fileName);
}, sClass, 0);
}
else if (sTyp == 5) {
mitem = uProfMenu.createME("menuitem", fileName, function() {
uProfMenu.edit(5, fileName);
}, sClass, 0);
}
popup.insertBefore(mitem, popup.firstChild);
})(i);
}
},
// --- FILLCLIPBOARDVALUE (changed by Mira) ---
fillClipboardValue: function(sArray) {
var retValue = "Meine Skripte (" + sArray.length + "):\n------------------------";
for (var i = 0; i < sArray.length; i++) {
retValue += "\n" + (i + 1) + ". " + sArray[i];
}
return retValue;
},
// --- CREATEME (ANGEPASST: sCommand als Funktion) ---
createME: function(sTyp, sLabel, sCommand, sClass, sId) {
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var m = document.createElementNS(XUL_NS, sTyp);
switch (sTyp) {
case "menuitem":
m.setAttribute('label', sLabel);
m.setAttribute('class', sClass);
if (sCommand && typeof sCommand === 'function') {
m.addEventListener('command', sCommand, true);
}
break;
case "menu":
m.setAttribute('label', sLabel);
m.setAttribute('id', sId);
break;
case "menupopup":
m.setAttribute('id', sId);
break;
}
return m;
},
// --- OPENATGITHUB (unchanged) ---
openAtGithub: function(e, sScript) {
if (e.button == 1) {
var sUrl = "https://github.com/ardiman/userChrome.js/tree/master/" + this.cleanFileName(sScript);
openWebLinkIn(sUrl, 'tab');
}
if (e.button == 2) {
e.preventDefault();
var sUrl = "https://github.com/search?langOverride=&language=&q=" + sScript + "&repo=&start_value=1&type=Code";
openWebLinkIn(sUrl, 'tab');
}
},
// --- CLEANFILENAME (unchanged) ---
cleanFileName: function(sName) {
sName = sName.toLowerCase();
var regs = [/\.uc\.js$/, /\.uc\.xul$/, /^ucjs_/, /_\d.+/, /_fx\d+/, /[-+\.]/g, /_v\d+/];
for (var i = 0; i < regs.length; i++) {
sName = sName.replace(regs[i], "");
}
return sName;
}
};
// Initialisierung
uProfMenu.init();
Alles anzeigen
Endor Wenn Du magst, bitte nochmals testen,
und wenn Du diese Version für gut befindest, ....
So, wenn doch noch Fehler vorhanden sein sollten, was ja nie auszuschließen ist,
bin nun in Urlaub.
Entweder schaut jemand anders dann danach, oder es muss 14 Tage warten.
Eventuell habe ich heute Abend noch mal etwas Zeit.
Also testet, was das Zeug hält. ![]()
"Eigene Skripte"
Also so wirklich werde ich mit dieser Bezeichnung nicht wirklich warm!
Aber "Userskripte" oder "Benutzte Skripte" oder "Installierte Skripte" finde ich jetzt auch nicht soo dolle!
Hat denn niemand eine andere Idee?
![]()
Wenn Du
retValue = "userChromeJS/uc.js ("+s+"):\n------------------------\n"+sArray.join("\n")+"\n\nuserChromeJS/uc.xul ("+x+"):\n-------------------------\n"+xArray.join("\n");
und
retValue = retValue + "\n\nuserChromeJS/uc.xul ("+x+"):\n-------------------------";
auskommentiert hast, dürfte nuserChromeJS/uc.xul gar nicht "erscheinen"!
Und was mich auch irritiert ist das undefined für die installierten Skripts!
Test-Skript, schon vorbereitet!
var uProfMenu = {
// --- KONFIGURATION (unchanged) ---
TextOpenExe: 'C:\\Program Files\\Notepad++\\notepad++.exe',
vFileManager: '',
warpmenuto: 'helpMenu',
sortScripts: 0,
gmOrdner: 0,
cssOrdner: 1,
abouts: ['about:about','about:addons','about:cache','about:config','about:crashes',
'about:downloads','about:home','about:logins','about:memory','about:support',
'about:preferences','about:performance','about:profiles'
],
showNormalPrefs: 1,
enableScriptsToClip: 2,
enableRestart: 0,
// --- INIT (ANGEPASST) ---
init: function() {
if (this.warpmenuto.toLowerCase() == 'menu') {
var zielmenu = document.getElementById('menu_ToolsPopup');
if (zielmenu == null) {
userChrome.log("extras_config_menu.uc.js findet Zielmenue nicht, evtl. weil ein anderes Fenster als das Hauptfenster geoeffnet wurde.");
return;
}
var menu = zielmenu.appendChild(this.createME("menu", "Config Men\u00FC", null, 0, "ExtraConfigMenu"));
menu.setAttribute("class", "menu-iconic");
// Ersetze ondblclick durch addEventListener
menu.addEventListener('dblclick', function() {
openTrustedLinkIn('about:config', 'tab');
}, true);
} else {
if (window.__SSi == "window0") {
CustomizableUI.createWidget({
id: "ExtraConfigMenu-button",
defaultArea: CustomizableUI.AREA_NAVBAR,
label: "Extra Config Menü",
tooltiptext: "Extra Config Menü\nRechtsklick öffnet about:config"
});
}
var menu = document.getElementById("ExtraConfigMenu-button");
// KORREKTUR:
if (!menu) {
return;
}
menu.setAttribute("type", "menu");
menu.addEventListener('click', function(event) {
if (event.button == 2 && !this.open) {
openTrustedLinkIn("about:config", "tab");
event.preventDefault();
}
}, true);
}
// CSS-Styles (unchanged)
var css = " \
#ExtraConfigMenu, #ExtraConfigMenu-button { \
list-style-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACnElEQVR4Xm2RzYtbZRSHn/fr3pvJzTB3qiNM2k2pMBUGhEHaqsUqdeFGQalCobgREaFu/B/cqCtxVSjoQhBEQRBmIfWDKgNGJUPt0Nhah9JJ4iSd5E6+bu5972tAO4SS5/DjXZ1znsMrNiq1eikMQqYYJCmjxNH5+zdW777L0J5KKl9VPmnf+ut9KWkwhbheuzNcOVYOmGKc5iRO0r1ykeXCx0h7kt4fC3z5wfqbQnAJwQHa5S7jAZSRuJ0mkf81cheobhBXZa+ri1uptQjHAZoZCEC1PiPgDuwxCfwerBU7b73zXn//3usCcdt4HkZ7SGZg431U51NUCgwlO3cV/bVXhR/6p9ut+nP9QYeNn7/n8qUPZxvQ/Q6VVWHk4ZqWRvlJjpx9hcGfW2wO95N2q8m3618A2WwDt/0RplSAXsBed57eyossHl5GYdHacG3zGpADM06wjQ1UUIN+CLHPvfAxojPnKLiE+bDE1R9+5GatAmgPeGCAteQ7l5GBhGSyuROyd/gFouUyWkqEErR2mwXAAA8BRS0AgMQBjSra30ZkEeDzz9Dn4ZcvMO51SMcJcTdGChmA0ABA6cAgzyG3I8jLEBylV4fWoaeIc0V7t0Uv7pFbC+CA+28mp/8+SwXKnMVmz1O9HpE+eobMZdjcoY1GIHD/NwIdoH1fBaNguzlg88pVyoUi4vTbFI8eJxsNAIfSkrliESllH/L0v0jktNNomFGv1TFrL3Fo9QSMR3jaEEXzLC09gjaKp595No0WjyCEB4zRclICUMDxtRMce/wJ1MIi2SglXShhfI/cOjxPoZRmbq4gXzt/gVrtBrdvbiG+Wf+p/mvll1BpiVAGhCDPxuAUDotz4HKHlIJON6bRbL4hhPjcMx5mkn8BBLEUrsVZbq0AAAAASUVORK5CYII=); \
margin-top: 0px !important; \
opacity: 1 !important; \
} \
#ExtraConfigMenu-button > dropmarker, #ExtraConfigMenu-button > hbox > .toolbarbutton-menu-dropmarker { \
display: none !important; \
}";
var sss = Cc['@mozilla.org/content/style-sheet-service;1'].getService(Ci.nsIStyleSheetService);
var uri = makeURI('data:text/css;charset=UTF-8,' + encodeURIComponent(css));
sss.loadAndRegisterSheet(uri, sss.AGENT_SHEET);
// Menü-Popup erstellen
var menupopup = menu.appendChild(this.createME("menupopup", null, null, 0, "ExtraConfigMenu-popup"));
// Event-Listener für popupshowing (unchanged, aber sicher)
menu.addEventListener('popupshowing', function(event) {
uProfMenu.getScripts(0);
uProfMenu.getCss(3);
uProfMenu.getCss(4);
uProfMenu.getCss(5);
}, true);
// --- UNTERMENÜS (unchanged) ---
var submenu = menupopup.appendChild(this.createME("menu", "Meine Scripte", null, 0, "submenu-ucjs"));
var submenupopup = submenu.appendChild(this.createME("menupopup", null, null, 0, "submenu-ucjs-items"));
var submenu = menupopup.appendChild(this.createME("menu", "css", null, 0, "submenu-css"));
var submenupopup = submenu.appendChild(this.createME("menupopup", null, null, 0, "submenu-css-items"));
var submenu = menupopup.appendChild(this.createME("menu", "CSSShadow", null, 0, "submenu-CSSShadow"));
var submenupopup = submenu.appendChild(this.createME("menupopup", null, null, 0, "submenu-CSSShadow-items"));
var submenu = menupopup.appendChild(this.createME("menu", "cssweb", null, 0, "submenu-cssweb"));
var submenupopup = submenu.appendChild(this.createME("menupopup", null, null, 0, "submenu-cssweb-items"));
// Skriptliste in Zwischenablage (ANGEPASST: sCommand als Funktion)
if (this.enableScriptsToClip) {
menupopup.appendChild(this.createME(
"menuitem",
"Skriptliste in Zwischenablage",
function() { uProfMenu.getScripts(1); },
"uProfMenu_clipboard",
0
));
}
menupopup.appendChild(document.createXULElement('menuseparator'));
// --- KONFIGDATEIEN (ANGEPASST: sCommand als Funktion) ---
menupopup.appendChild(this.createME(
"menuitem", "Bild Url",
function() { uProfMenu.edit(0, 'Bild Url.css'); },
"uProfMenu_edit", 0
));
menupopup.appendChild(this.createME(
"menuitem", "config Einträge.css",
function() { uProfMenu.edit(0, 'config Einträge.css'); },
"uProfMenu_edit", 0
));
menupopup.appendChild(this.createME(
"menuitem", "userChrome.css",
function() { uProfMenu.edit(0, 'userChrome.css'); },
"uProfMenu_edit", 0
));
menupopup.appendChild(this.createME(
"menuitem", "userChromeShadow.css",
function() { uProfMenu.edit(0, 'userChromeShadow.css'); },
"uProfMenu_edit", 0
));
menupopup.appendChild(this.createME(
"menuitem", "userContent.css",
function() { uProfMenu.edit(0, 'userContent.css'); },
"uProfMenu_edit", 0
));
menupopup.appendChild(this.createME(
"menuitem", "userChrome.js",
function() { uProfMenu.edit(0, 'userChrome.js'); },
"uProfMenu_edit", 0
));
menupopup.appendChild(this.createME(
"menuitem", "prefs.js",
function() { uProfMenu.edit(1, 'prefs.js'); },
"uProfMenu_edit", 0
));
menupopup.appendChild(this.createME(
"menuitem", "user.js",
function() { uProfMenu.edit(1, 'user.js'); },
"uProfMenu_edit", 0
));
// --- ORDNER (ANGEPASST: sCommand als Funktion) ---
menupopup.appendChild(document.createXULElement('menuseparator'));
switch (this.gmOrdner) {
case 1:
menupopup.appendChild(this.createME(
"menuitem", "GM-skripty",
function() { uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('ProfD') + uProfMenu.getDirSep() + 'gm_scripts'); },
"uProfMenu_folder", 0
));
break;
case 2:
menupopup.appendChild(this.createME(
"menuitem", "USL-skripty",
function() { uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm') + uProfMenu.getDirSep() + 'UserScriptLoader'); },
"uProfMenu_folder", 0
));
break;
case 3:
menupopup.appendChild(this.createME(
"menuitem", "Skripty Scriptish",
function() { uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('ProfD') + uProfMenu.getDirSep() + 'scriptish_scripts'); },
"uProfMenu_folder", 0
));
break;
}
menupopup.appendChild(this.createME(
"menuitem", "CSS-Ordner",
function() { uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm') + uProfMenu.getDirSep() + 'css'); },
"uProfMenu_folder", 0
));
menupopup.appendChild(this.createME(
"menuitem", "CSSShadow-Ordner",
function() { uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm') + uProfMenu.getDirSep() + 'CSSShadow'); },
"uProfMenu_folder", 0
));
menupopup.appendChild(this.createME(
"menuitem", "CSSWeb-Ordner",
function() { uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm') + uProfMenu.getDirSep() + 'CSSWeb'); },
"uProfMenu_folder", 0
));
menupopup.appendChild(this.createME(
"menuitem", "Chromeordner",
function() { uProfMenu.prefDirOpen('UChrm'); },
"uProfMenu_folder", 0
));
menupopup.appendChild(this.createME(
"menuitem", "Profilordner",
function() { uProfMenu.prefDirOpen('ProfD'); },
"uProfMenu_folder", 0
));
menupopup.appendChild(this.createME(
"menuitem", "Icons-Ordner",
function() { uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm') + uProfMenu.getDirSep() + 'Icons'); },
"uProfMenu_folder", 0
));
menupopup.appendChild(this.createME(
"menuitem", "Installationsordner",
function() { uProfMenu.prefDirOpen('CurProcD'); },
"uProfMenu_folder", 0
));
menupopup.appendChild(this.createME(
"menuitem", "Addonordner",
function() { uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('ProfD') + uProfMenu.getDirSep() + 'extensions'); },
"uProfMenu_folder", 0
));
menupopup.appendChild(this.createME(
"menuitem", "Startup-Cacheordner",
function() { uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('ProfLD') + uProfMenu.getDirSep() + 'startupCache'); },
"uProfMenu_folder", 0
));
// --- ABOUT-SEITEN (ANGEPASST: Closure-Problem gelöst) ---
if (this.abouts.length > 0) {
menupopup.appendChild(document.createXULElement('menuseparator'));
if (this.abouts[0] == '0') {
for (var i = 1; i < this.abouts.length; i++) {
(function(index) {
var about = uProfMenu.abouts[index];
menupopup.appendChild(uProfMenu.createME(
"menuitem", about,
function() { openTrustedLinkIn(about, 'tab'); },
"uProfMenu_about", 0
));
})(i);
}
} else {
var submenu = menupopup.appendChild(this.createME("menu", "uc.js", null, 0, "submenu-about"));
var submenupopup = submenu.appendChild(this.createME("menupopup", null, null, 0, "submenu-about-items"));
this.fillMenu("submenu-about", "submenu-about-items", "about:", this.abouts, "uProfMenu_about", 1);
}
}
// --- EINSTELLUNGEN & NEUSTART (ANGEPASST) ---
if (this.abouts.length == 0 && (this.showNormalPrefs || typeof(ToolRstartMod) != "undefined")) {
menupopup.appendChild(document.createXULElement('menuseparator'));
}
if (this.showNormalPrefs) {
menupopup.appendChild(this.createME(
"menuitem", "Einstellungen",
function() { try { openOptionsDialog(); } catch(e) { openPreferences(); } },
"uProfMenu_prefs", 0
));
}
if (this.enableRestart) {
menupopup.appendChild(this.createME(
"menuitem", "Neustart",
function() {
Services.appinfo.invalidateCachesOnRestart();
Services.startup.quit(Ci.nsIAppStartup.eRestart | Ci.nsIAppStartup.eAttemptQuit, 0);
},
0, 0
));
}
},
// --- HILFSFUNKTIONEN (unchanged) ---
getDirSep: function() {
var osString = Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULRuntime).OS;
var dirsep = "/";
switch(osString) {
case "WINNT": dirsep = "\\"; break;
case "Linux": dirsep = "/"; break;
case "Darwin": dirsep = "/"; break;
}
return dirsep;
},
/*
// --- EDIT (unchanged) ---
edit: function(OpenMode, Filename) {
var Path = "";
var dSep = this.getDirSep();
switch (OpenMode) {
case 0: Path = this.getPrefDirectoryPath("UChrm") + dSep + Filename; break;
case 1: Path = this.getPrefDirectoryPath("ProfD") + dSep + Filename; break;
case 2: Path = Filename; break;
case 3: Path = this.getPrefDirectoryPath("UChrm") + dSep + "CSS" + dSep + Filename; break;
case 4: Path = this.getPrefDirectoryPath("UChrm") + dSep + "CSSWeb" + dSep + Filename; break;
case 5: Path = this.getPrefDirectoryPath("UChrm") + dSep + "CSSShadow" + dSep + Filename; break;
}
this.launch(this.TextOpenExe, Path);
},
*/
// --- EDIT (changed by Mira) ---
edit: function(OpenMode, Filename) {
var Path = "";
var dSep = this.getDirSep();
// --- Pfad-Handling für chrome/scripts/ ---
if (Filename.includes("/") || Filename.includes("\\")) {
Path = this.getPrefDirectoryPath("ProfD") + dSep + Filename;
} else {
// Original-Logik
switch (OpenMode) {
case 0: Path = this.getPrefDirectoryPath("UChrm") + dSep + Filename; break;
case 1: Path = this.getPrefDirectoryPath("ProfD") + dSep + Filename; break;
case 2: Path = Filename; break;
case 3: Path = this.getPrefDirectoryPath("UChrm") + dSep + "CSS" + dSep + Filename; break;
case 4: Path = this.getPrefDirectoryPath("UChrm") + dSep + "CSSWeb" + dSep + Filename; break;
case 5: Path = this.getPrefDirectoryPath("UChrm") + dSep + "CSSShadow" + dSep + Filename; break;
}
}
this.launch(this.TextOpenExe, Path);
},
dirOpen: function(Path) {
if (this.vFileManager.length != 0) {
var file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
var process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess);
var args = [Path];
file.initWithPath(this.vFileManager);
process.init(file);
process.run(false, args, args.length);
} else {
var dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
dir.initWithPath(Path);
dir.launch();
}
},
prefDirOpen: function(prefDir) {
var Path = this.getPrefDirectoryPath(prefDir);
this.dirOpen(Path);
},
getPrefDirectoryPath: function(str) {
var file = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties)
.get(str, Components.interfaces.nsIFile);
if (str == 'CurProcD') file = file.parent;
return file.path;
},
launch: function(RanPath, OpenPath) {
var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsIFile);
var proc = Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess);
var args = [OpenPath];
file.initWithPath(RanPath);
if (!file.exists()) {
var pref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
RanPath = pref.getCharPref("view_source.editor.path");
file.initWithPath(RanPath);
}
proc.init(file);
proc.run(false, args, args.length);
},
stringComparison: function(a, b) {
a = a.toLowerCase().replace(/ä/g,"a").replace(/ö/g,"o").replace(/ü/g,"u").replace(/ß/g,"s");
b = b.toLowerCase().replace(/ä/g,"a").replace(/ö/g,"o").replace(/ü/g,"u").replace(/ß/g,"s");
return (a == b) ? 0 : (a > b) ? 1 : -1;
},
/*
// --- GETSCRIPTS (unchanged) ---
getScripts: function(iType) {
let ucJsScripts = [];
let extjs = /\.uc\.js$/i;
let aFolder = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
aFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path);
let files = aFolder.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);
while (files.hasMoreElements()) {
let file = files.getNext().QueryInterface(Ci.nsIFile);
if (extjs.test(file.leafName)) ucJsScripts.push(file.leafName);
}
if (this.sortScripts) ucJsScripts.sort(this.stringComparison);
if (iType == 0) {
this.fillMenu("submenu-ucjs", "submenu-ucjs-items", "Meine Scripte", ucJsScripts, "uProfMenu_ucjs", 0);
} else {
var result = this.fillClipboardValue(ucJsScripts, []);
Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper).copyString(result);
}
},
*/
// --- GETSCRIPTS (changed by Mira) ---
getScripts: function(iType) {
let ucJsScripts = [];
let extjs = /\.uc\.js$/i;
// --- 1. Standard-UChrm-Ordner durchsuchen (ohne userChromeShadow.uc.js) ---
let uchrmFolder = Services.dirsvc.get("UChrm", Ci.nsIFile);
if (uchrmFolder.exists()) {
let files = uchrmFolder.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);
while (files.hasMoreElements()) {
let file = files.getNext().QueryInterface(Ci.nsIFile);
if (extjs.test(file.leafName) && file.leafName !== "userChromeShadow.uc.js") {
ucJsScripts.push(file.leafName);
}
}
}
// --- 2. chrome/scripts-Ordner durchsuchen (falls vorhanden) ---
let chromeScriptsFolder = Services.dirsvc.get("ProfD", Ci.nsIFile);
chromeScriptsFolder.append("chrome");
chromeScriptsFolder.append("scripts");
if (chromeScriptsFolder.exists()) {
let files = chromeScriptsFolder.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);
while (files.hasMoreElements()) {
let file = files.getNext().QueryInterface(Ci.nsIFile);
if (extjs.test(file.leafName)) {
ucJsScripts.push("chrome/scripts/" + file.leafName); // Pfad-Präfix für spätere Verarbeitung
}
}
}
if (this.sortScripts) ucJsScripts.sort(this.stringComparison);
if (iType == 0) {
this.fillMenu("submenu-ucjs", "submenu-ucjs-items", "Meine Scripte", ucJsScripts, "uProfMenu_ucjs", 0);
} else {
// Für Zwischenablage: Nur Dateinamen (ohne Pfad) verwenden
var simpleNames = ucJsScripts.map(f => f.split(/[\\/]/).pop());
var result = this.fillClipboardValue(simpleNames, []);
Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper).copyString(result);
}
},
// --- GETCSS (unchanged) ---
getCss: function(iType) {
let cssFiles = [];
let extcss = /\.css$/i;
let aFolder = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
if (iType == 3) aFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path + this.getDirSep() + "CSS");
else if (iType == 4) aFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path + this.getDirSep() + "CSSWeb");
else if (iType == 5) aFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path + this.getDirSep() + "CSSShadow");
let files = aFolder.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);
while (files.hasMoreElements()) {
let file = files.getNext().QueryInterface(Ci.nsIFile);
if (extcss.test(file.leafName)) cssFiles.push(file.leafName);
}
if (this.sortScripts) cssFiles.sort(this.stringComparison);
if (iType == 3) this.fillMenu("submenu-css", "submenu-css-items", "Meine CSS-Dateien", cssFiles, "uProfMenu_css", 3);
else if (iType == 4) this.fillMenu("submenu-cssweb", "submenu-cssweb-items", "Meine CSSWeb-Dateien", cssFiles, "uProfMenu_css", 4);
else if (iType == 5) this.fillMenu("submenu-CSSShadow", "submenu-CSSShadow-items", "Meine CSSShadow-Dateien", cssFiles, "uProfMenu_css", 5);
},
// --- FILLMENU (ANGEPASST: Closure-Problem gelöst + Event-Handler korrigiert) ---
fillMenu: function(whichsubmenu, whichsubmenuitems, strlabel, scriptArray, sClass, sTyp) {
var e = document.getElementById(whichsubmenu);
e.setAttribute('label', strlabel + ' (' + scriptArray.length + ')');
var popup = document.getElementById(whichsubmenuitems);
while (popup.hasChildNodes()) popup.removeChild(popup.firstChild);
var uProfMenu = this; // Für Closure
for (var i = scriptArray.length - 1; i > -1; i--) {
(function(index) {
var fileName = scriptArray[index];
var mitem;
/*
if (sTyp == 0) {
mitem = uProfMenu.createME("menuitem", fileName, null, sClass, 0);
mitem.addEventListener('command', function() {
uProfMenu.edit(0, fileName);
}, true);
mitem.addEventListener('click', function(event) {
uProfMenu.openAtGithub(event, fileName);
}, true);
mitem.setAttribute("tooltiptext", "Linksklick: Bearbeiten,\nMittelklick: https://github.com/.../" + uProfMenu.cleanFileName(fileName) + " öffnen,\nRechtsklick: Suche auf GitHub");
}
*/
// Korrektur durch Mira
if (sTyp == 0) {
mitem = uProfMenu.createME("menuitem", fileName, null, sClass, 0);
// Extrahiere Dateinamen für Anzeige (z. B. "chrome/scripts/test.uc.js" → "test.uc.js")
var displayName = fileName.split(/[\\/]/).pop();
mitem.setAttribute('label', displayName);
mitem.addEventListener('command', function() {
uProfMenu.edit(0, fileName); // Original-Pfad (mit Präfix) an edit() übergeben
}, true);
mitem.addEventListener('click', function(event) {
uProfMenu.openAtGithub(event, displayName);
}, true);
mitem.setAttribute("tooltiptext", "Linksklick: Bearbeiten,\nMittelklick: https://github.com/.../" + uProfMenu.cleanFileName(displayName) + " öffnen,\nRechtsklick: Suche auf GitHub");
}
// Korrektur ENDE
else if (sTyp == 1) {
mitem = uProfMenu.createME("menuitem", fileName, function() {
openTrustedLinkIn(fileName, 'tab');
}, sClass, 0);
}
else if (sTyp == 3) {
mitem = uProfMenu.createME("menuitem", fileName, function() {
uProfMenu.edit(3, fileName);
}, sClass, 0);
}
else if (sTyp == 4) {
mitem = uProfMenu.createME("menuitem", fileName, function() {
uProfMenu.edit(4, fileName);
}, sClass, 0);
}
else if (sTyp == 5) {
mitem = uProfMenu.createME("menuitem", fileName, function() {
uProfMenu.edit(5, fileName);
}, sClass, 0);
}
popup.insertBefore(mitem, popup.firstChild);
})(i);
}
},
/*
// --- FILLCLIPBOARDVALUE (unchanged) ---
fillClipboardValue: function(sArray, xArray) {
var retValue;
var s = sArray.length;
var x = xArray.length;
switch(this.enableScriptsToClip) {
case 1:
// retValue = "userChromeJS/uc.js ("+s+"):\n------------------------\n"+sArray.join("\n")+"\n\nuserChromeJS/uc.xul ("+x+"):\n-------------------------\n"+xArray.join("\n");
// retValue = "userChromeJS/uc.js ("+s+"):\n------------------------\n"+sArray.join("\n")+"\n\nUserskripte ("+x+"):\n-------------------------\n"+xArray.join("\n");
break;
default:
// retValue = "userChromeJS/uc.js ("+s+"):\n------------------------";
retValue = "Eigene Skripte ("+s+"):\n------------------------";
for (var i = 0; i < s; i++) {
j = i + 1;
retValue = retValue + "\n" + j + ". " + sArray[i];
}
// retValue = retValue + "\n\nuserChromeJS/uc.xul ("+x+"):\n-------------------------";
// retValue = retValue + "\n\nUserskripte ("+x+"):\n-------------------------";
if (this.enableScriptsToClip == 2) s = 0;
for (var i = 0; i < x; i++) {
j = i + s + 1;
retValue = retValue + "\n" + j + ". " + xArray[i];
}
break;
}
return retValue;
},
*/
// --- FILLCLIPBOARDVALUE (changed by Mira) ---
fillClipboardValue: function(sArray, xArray) {
var retValue;
var s = sArray.length;
var x = xArray.length;
switch(this.enableScriptsToClip) {
case 1:
break;
default:
retValue = "Eigene Skripte ("+s+"):\n------------------------";
for (var i = 0; i < s; i++) {
j = i + 1;
retValue = retValue + "\n" + j + ". " + sArray[i];
}
if (this.enableScriptsToClip == 2) s = 0;
for (var i = 0; i < x; i++) {
j = i + s + 1;
retValue = retValue + "\n" + j + ". " + xArray[i];
}
break;
}
return retValue;
},
// --- CREATEME (ANGEPASST: sCommand als Funktion) ---
createME: function(sTyp, sLabel, sCommand, sClass, sId) {
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var m = document.createElementNS(XUL_NS, sTyp);
switch (sTyp) {
case "menuitem":
m.setAttribute('label', sLabel);
m.setAttribute('class', sClass);
if (sCommand && typeof sCommand === 'function') {
m.addEventListener('command', sCommand, true);
}
break;
case "menu":
m.setAttribute('label', sLabel);
m.setAttribute('id', sId);
break;
case "menupopup":
m.setAttribute('id', sId);
break;
}
return m;
},
// --- OPENATGITHUB (unchanged) ---
openAtGithub: function(e, sScript) {
if (e.button == 1) {
var sUrl = "https://github.com/ardiman/userChrome.js/tree/master/" + this.cleanFileName(sScript);
openWebLinkIn(sUrl, 'tab');
}
if (e.button == 2) {
e.preventDefault();
var sUrl = "https://github.com/search?langOverride=&language=&q=" + sScript + "&repo=&start_value=1&type=Code";
openWebLinkIn(sUrl, 'tab');
}
},
// --- CLEANFILENAME (unchanged) ---
cleanFileName: function(sName) {
sName = sName.toLowerCase();
var regs = [/\.uc\.js$/, /\.uc\.xul$/, /^ucjs_/, /_\d.+/, /_fx\d+/, /[-+\.]/g, /_v\d+/];
for (var i = 0; i < regs.length; i++) {
sName = sName.replace(regs[i], "");
}
return sName;
}
};
// Initialisierung
uProfMenu.init();
Alles anzeigen
Ergebniss sollte in etwa so aussehen:
Eigene Skripte (56):
------------------------
1. # check.uc.js
2. # 1 extensionsUpdateChecker.uc.js
3. # 1_TEST.uc.js
4. # 1_TEST_2.uc.js
5. # FoxInstanzStarter.uc.js
6. # TEST-CSSLoader.uc.js
7. 00 sidebar_test.uc.js
8. 00_toggle_toolbar_Horst.uc.js
9. 01 Button_for_AboutConfig.uc.js
10. 01 Button_for_Erweiterungen_verschiebbar.uc.js
11. 02 Button_for_PersonalToolbar.uc.js
12. 05 Button_for_About-Dialog.uc.js
13. 05 Button_for_Addons-UpDate-Check.uc.js
14. 05 Button_for_Browser-Werkzeuge.uc.js
15. 05 Button_for_Downloads.uc.js
16. 05 Button_for_ProfilesChanges.uc.js
17. 05 Button_for_QuickLinks-about.uc.js
18. 05 Button_for_QuickLinks-cf.uc.js
19. 05 Button_for_Restart_Firefox.uc.js
20. 05 Button_for_Werkzeuge-fuer-Webentwickler.uc.js
21. 06 Button_for_Chromefolder.uc.js
22. 06 Button_for_Profilfolder.uc.js
23. 06 Button_for_QuickLink.uc.js
24. 06 Button_for_QuickLinks.uc.js
25. 07 Button_for_Firefox-Verzeichnisse.uc.js
26. 09 Button_for_Restart_in_Hamburger-Menu.uc.js
27. aboutConfig_menu.uc.js
28. aboutConfig_menu_2.uc.js
29. addonbar_vertical.uc.js
30. Anzeige.uc.js
31. AutoPopup.uc.js
32. BackupProfile.uc.js
33. BookmarkCount.uc.js
34. Clock+Date.uc.js
35. CloseTab.uc.js
36. ContextTranslate-DeepL.uc.js
37. ContextTranslate-Google.uc.js
38. FavIconInUrlBar.uc.js
39. Fenster_schließen.uc.js
40. Hamburger-Menu.uc.js
41. newTabButtonUndoTabList.uc.js
42. newTabFromHistory.uc.js
43. OpenLinkWith.uc.js
44. OpenPageWith.uc.js
45. Private-Browsing-Label verschiebbar.uc.js
46. ReloadAllTabs.uc.js
47. ReloadTab_by_double click.uc.js
48. Scrollbar.2.0.8.b.uc.js
49. SkipToTopAndBottom.uc.js
50. TabContextCloseAllTabs.uc.js
51. ToggleFindbar.uc.js
52. Tooltips.uc.js
53. uBlock Update.uc.js
54. UndoListInTabmenuToo.uc.js
55. Warnung.uc.js
56. wetterfuchsbutton.uc.js
Alles anzeigen
Der zweite Eintrag userChromeJS/uc.xul (0): kann ja nicht erscheinen.
Ah, jetzt ja!
Einfach beide Zeilen
retValue = "userChromeJS/uc.js ("+s+"):\n------------------------\n"+sArray.join("\n")+"\n\nuserChromeJS/uc.xul ("+x+"):\n-------------------------\n"+xArray.join("\n");
und
per " // " auskommentieren.
Und wer mag, kann
das userChromeJS/uc.js z.B. in "Userskripte" oder "Eigene Skripte" oder "Installierte Skripte" ändern. ![]()
Oder wir legen das jetzt hier fest und ich poste noch einmal das komplett überarbeitete Skript.
"Userskripte" oder "Eigene Skripte" oder "Installierte Skripte"
Ich weiß nicht so recht, was am besten passt, was am ehesten zu trifft,
was am ehesten Sinn macht (ergibt).
2002Andreas Mach doch bitte mal einen Sreenshot.
Denn ich sehe so einen Menüeintrag bei mir nicht!
Oder bist Du im Skript auf "userChromeJS/uc.xul" gestoßen?
_______________________________________________
Ah!
Im Skript.
DAS lass ich mal unangetastet!!
Ich weiß nicht, was der Teil tut
und ich bin z.Z. schon am Koffer packen und habe daher keine Zeit mehr mich intensiv mit dem Skript zu beschäftigen.
Wenn es Zeit hat, und das hat es, da bin ich mir sicher, beschäftige ich mich gegen Ende des Monats damit.