Deine Dateipfade für die Icons funktionieren nur sehr begrenzt
Funktionieren hervorragend.
Es ist nun mal:
ZitatEine andere Variante zum Beenden von Firefox.
Deine Dateipfade für die Icons funktionieren nur sehr begrenzt
Funktionieren hervorragend.
Es ist nun mal:
ZitatEine andere Variante zum Beenden von Firefox.
Und noch eine andere Variante, ohne Button aber im Kontextmenü, funktioniert mit FF 138 und 140:
//Fox_schließen_Context
(function() {
if (location.href !== 'chrome://browser/content/browser.xhtml')
return;
const label = 'Fox schließen';
const oncommand = "goQuitApplication(event);";
const curProfDir = PathUtils.toFileURI(PathUtils.join(PathUtils.profileDir));
const menuitem1 = document.createXULElement('menuitem');
menuitem1.id = 'contextTest';
menuitem1.setAttribute('label', label);
menuitem1.setAttribute('oncommand', oncommand);
const refItem1 = document.getElementById('context-inspect');
refItem1.parentNode.insertBefore(menuitem1, refItem1.nextSibling);
})();
Alles anzeigen
Das Problem ist Zeile 13!
Und noch eine andere Variante, ohne Button aber im Kontextmenü, funktioniert mit FF 138 und 140:
Funktioniert top in 115esr!
Für aktuellere Versionen evtl. eher sowas:
//Fox_schließen_Context
(function() {
if (location.href !== 'chrome://browser/content/browser.xhtml')
return;
const label = 'Fox schließen';
//const oncommand = "goQuitApplication(event);";
//const curProfDir = PathUtils.toFileURI(PathUtils.join(PathUtils.profileDir));
const menuitem1 = document.createXULElement('menuitem');
menuitem1.id = 'contextTest';
menuitem1.setAttribute('label', label);
//menuitem1.setAttribute('oncommand', oncommand);
menuitem1.addEventListener('command', () => {
goQuitApplication(event);
});
const refItem1 = document.getElementById('context-inspect');
refItem1.parentNode.insertBefore(menuitem1, refItem1.nextSibling);
})();
Alles anzeigen
Oder so:
// JavaScript Document
// M_Quit_Firefox.uc.js
// Das Script erstellt einen neuen Menüeintrag, der ein einzelnes Firefox-Fenster separat schließt (Linksklick) oder Firefox beendet (Mittel-/Rechtsklick). Das .svg-Icon kann - je nach Hover-Zustand - mit zwei unterschiedlichen Farben gefüllt werden [fill]. Beim Überfahren des Menuitems rotiert das Icon um 180deg [rotate: 180deg].
// Das Menü für den Menüeintrag kann selektiert werden (Seitenkontextmenü oder Tabkontextmenü).
// Die Position des Menüeintrags innerhalb des Menüs kann bestimmt werden.
// Eine Darstellung des Menüeintrags mit/ohne Icon kann gewählt werden.
// Für das mitgelieferte Icon als .svg-Datei mit [moz-context-properties] ändert das Script - bei gewählter Iconanzeige [const isIcon = 1;] - die Einstellung [svg.context-properties.content.enabled] in about:config auf 'true'.
(function() {
if (!window.gBrowser)
return;
const
// ■■ START UserConfiguration ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
id = 'contextQuit', // ID des neuen menuitems
label = 'Fenster schließen/Firefox beenden', // Bezeichnung des neuen menuitems
tooltiptext = 'Fenster schließen/Firefox beenden\n\nLinksklick: Fenster schließen\nMittel-/Rechtsklick: Firefox beenden',
// Icon-------------------------------------------------------
isIcon = 1,
// isIcon = 1, mit Icon
// isIcon = 0, ohne Icon; die Konstanten icon, iconPath, iconColOu und iconColOv haben dann keine Funktion und sollten unberührt bleiben
icon = 'quit-16.svg', // [Name.Dateiendung] des anzuzeigenden Symbols
iconPath = '/chrome/icons/', // Pfad zum Ordner der das Icon beinhaltet
iconColOu = 'red', // Farbe des Icons (nur .svg-Datei mit [moz-context-properties], bei anderen Icons hat const iconColOu keine Funktion)
iconColOv = 'currentColor', // Farbe des Icons beim Überfahren des Items (nur .svg-Datei mit [moz-context-properties], bei anderen Icons hat const iconColOv keine Funktion)
// Menü-------------------------------------------------------
isMenu = 2,
// isMenu = 1, für Seitenkontextmenü;
// isMenu = 2, für Tabkontextmenü';
isPos = 12,
// Option A:
// isPos = 12, [Zahlen von -5 bis 20]
// Menuitem an einer bestimmten Position im Menü einfügen
// wie in CSS: [order:12!important;]
// Option B:
// isPos = 'context-inspect'; [String]
// Menuitem auf diesen Menüpunkt folgend einfügen
// wie in CSS: [#context-inspect]
// ■■ END UserConfiguration ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
curProfDir = PathUtils.toFileURI(PathUtils.join(PathUtils.profileDir)),
cl = 'image',
menu1 = document.getElementById('contentAreaContextMenu'),
menu2 = document.getElementById('tabContextMenu'),
menuitem = document.createXULElement('menuitem');
//const end
menuitem.id = id;
menuitem.setAttribute('label', label);
menuitem.setAttribute('tooltiptext', tooltiptext);
//mit Icon
if (isIcon === 1) {
//----
if (Services.prefs.getBoolPref('svg.context-properties.content.enabled') == false) {
Services.prefs.setBoolPref('svg.context-properties.content.enabled', true );
}
//----
menuitem.classList.add('menuitem-iconic');
menuitem.style.MozContextProperties = 'fill';
menuitem.style.listStyleImage = 'url("' + curProfDir + iconPath + icon + '")';
//Icon start
switch (isMenu) {
case 1:
menu1.addEventListener('popupshowing', () => {
menuitem.querySelector(cl).style.fill = iconColOu;
});
break;
case 2:
menu2.addEventListener('popupshowing', () => {
menuitem.querySelector(cl).style.fill = iconColOu;
});
break;
}
//Icon over
menuitem.addEventListener('mouseover', () => {
menuitem.querySelector(cl).setAttribute('style','fill:'+iconColOv+';rotate: 180deg; transition: rotate 0.2s ease-in-out 0.1s;');
});
//Icon out
menuitem.addEventListener('mouseout', () => {
menuitem.querySelector(cl).setAttribute('style','fill:'+iconColOu+';rotate: 0deg; transition: rotate 0.2s ease-in-out 0.1s;');
});
}
//Icon end
//click
menuitem.addEventListener('click', () => {
if (event.button === 0) {
event.target.ownerGlobal.BrowserCommands.tryToCloseWindow(event);
}
else
if (event.button === 1 || event.button === 2) {
event.target.ownerGlobal.goQuitApplication(event);
}
});
//Position order
if (isPos > -6 && isPos < 21) {
if (isMenu === 1) {
menu1.append(menuitem);
}
else
if (isMenu === 2) {
menu2.append(menuitem);
}
menuitem.style.order = isPos;
}
//Position reference
else {
const refItem = document.getElementById(isPos);
refItem.parentNode.insertBefore(menuitem, refItem.nextSibling);
}
//----
})();
Alles anzeigen
@Horstmanns Variante funktioniert für beide Versionen. Dankeschön für den Hinweis. Meine ältere Anweisung im Nightly hat funktioniert, daher bin ich davon ausgegangen, daß diese im 138er ebenfalls ok ist. War leider nicht so, sorry. Aber jetzt funktioniert es für beide Versionen, habs gerade nochmal getestet.
Moinsen.
Für sowohl Kontext und Button habe ich 2 Skripte zusammengefügt:
// Button > Firefox beenden
// angepasst für Fx 138 by Mira_Belle
/* ----------------------------------------------------------------------------------- */
/* Zu beachten ist, dass die Grafiken sich im richtigen Ordner befinden müssen */
/* %appdata%\Mozilla\Firefox\Profiles\"Profilname"\chrome\icons */
/* ----------------------------------------------------------------------------------- */
(function() {
if (location != 'chrome://browser/content/browser.xhtml') return;
try {
CustomizableUI.createWidget({
id: "fp-quit",
type: 'custom',
defaultArea: CustomizableUI.AREA_NAVBAR,
onBuild: function(aDocument) {
let buttonicon = "quit.svg";
let fallbackIcon = "chrome://global/skin/icons/warning.svg";
let iconFile = Services.dirsvc.get("ProfD", Ci.nsIFile);
iconFile.append("chrome");
iconFile.append("icons");
iconFile.append(buttonicon);
let iconExists = iconFile.exists();
let iconURL = iconExists
? "file://" + iconFile.path.replace(/\\/g, "/")
: fallbackIcon;
// Immer einfärben (lime), bei Fallback ggf. andere Farbe zusätzlich
let iconStyle = 'list-style-image: url("' + iconURL + '"); fill: lime;';
if (!iconExists) {
iconStyle += ' fill: red;';
}
let toolbaritem = aDocument.createElementNS(
'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul',
'toolbarbutton'
);
let props = {
id: "fp-quit",
class: 'toolbarbutton-1 chromeclass-toolbar-additional',
label: "Beenden",
tooltiptext: "Beenden",
style: iconStyle
};
for (let p in props)
toolbaritem.setAttribute(p, props[p]);
return toolbaritem;
}
});
} catch (e) { }
document.getElementById('fp-quit').addEventListener( "click", onClick );
function onClick(event) {
goQuitApplication(event);
}
})();
//Fox_schließen_Context
(function() {
if (location.href !== 'chrome://browser/content/browser.xhtml')
return;
const label = 'Fox schließen';
//const oncommand = "goQuitApplication(event);";
//const curProfDir = PathUtils.toFileURI(PathUtils.join(PathUtils.profileDir));
const menuitem1 = document.createXULElement('menuitem');
menuitem1.id = 'contextTest';
menuitem1.setAttribute('label', label);
//menuitem1.setAttribute('oncommand', oncommand);
menuitem1.addEventListener('command', () => {
goQuitApplication(event);
});
const refItem1 = document.getElementById('context-inspect');
refItem1.parentNode.insertBefore(menuitem1, refItem1.nextSibling);
})();
Alles anzeigen
Funktionieren tut das hier (138.0.3), aber: Macht das eigentlich Sinn?
Grüße Lionsson
Funktionieren tut das hier (138.0.3), aber: Macht das eigentlich Sinn?
Ich glaube, dass sich hier die Frage nach der Sinnhaftigkeit gar nicht stellt. Es ist in diesem Fall reine Geschmackssache, ob man das lieber in einer Datei oder in zwei getrennten Dateien haben möchte.
Das "Aneinanderheften" von Funktionen des Typs...
...kann man durchaus machen, da es sich auf Modulebene dabei um Funktionen handelt, die sich automatisch selber starten ("self- invoking"). Allerdings sollte man es nicht übertreiben und hier beliebige Skripte zusammenführen, die inhaltlich nicht zusammengehören. Auch könnte man sich im konkreten Fall natürlich überlegen, die Funktionalität des Kontextmenü-Eintrags gleich in die erste Funktion zu schreiben.
Frage!
Wenn man schon zwei Funktionen "aneinanderheftet" ist es dann nicht besser (gut) wie auch immer,
wenn man dann den Funktionen "Namen" verpasst?
Und wenn es nur zur Unterscheidung ist!
Aber ich denke, man sollte getrennte Scripte besser getrennt lassen
und nicht alles, nur weil es irgendwie geht, mit einander verwurschteln!
Funktioniert mal etwas nicht, muss das eine, ganze Skript überprüft werden.
Wenn man die Scripte getrennt lässt, funktioniert halt nur eine Sache nicht!
...mitunter hilft ja das Denken in Extremen.
Gibt es Performance-Unterschiede (Startgeschwindigkiet, Stabilität,...) zwischen den Optionen einerseits z.B. 100 einzelnen JS-Dateien für 100 Funktionen oder andererseits einer einzigen JS-Datei mit allen Funktionen.
Übersichtlichkeit, Auffindbarkeit und ähnliche Kriterien mal außen vor gelassen: vielleicht ist es ja etwas theoretisch gedacht, aber die isolierte Betrachtung eines Problems kann ja manchmal zu mehr Klarheit verhelfen.
GL
Wenn man schon zwei Funktionen "aneinanderheftet" ist es dann nicht besser (gut) wie auch immer,
wenn man dann den Funktionen "Namen" verpasst?
Klar kannst du das machen, wenn du das übersichtlicher findest. Da die Funktion aber von nirgendwo anders als beim Start aufgerufen wird, ist es aber auch nicht unbedingt hilfreicher.
In deinem Beispiel hast du der Funktion aber keinen Namen verpasst, sondern du hast einen "Parameter" übergeben?!
Gibt es Performance-Unterschiede (Startgeschwindigkiet, Stabilität,...) zwischen den Optionen einerseits z.B. 100 einzelnen JS-Dateien für 100 Funktionen oder andererseits einer einzigen JS-Datei mit allen Funktionen.
Die Performance oder Stabilität kannst du ignorieren, da diese Funktionen pro Modul ja nur einmal (beim Start) aufgerufen werden. Da ist es egal, ob sich diese Funktionalität in einer oder mehreren Dateien befindet. Da sind die Unterschiede einmalig(!) bei vielleicht einer 1/100 Sekunde oder noch viel weniger.
In deinem Beispiel hast du der Funktion aber keinen Namen verpasst, sondern du hast einen "Parameter" übergeben?!
Oh, stimmt, da war was!
In der Klammer nicht keine "Namen" oder "Bezeichnungen" sondern Parameter!
Solche Sachen vergesse ich hin und wieder. Danke für den "Klaps".