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

Beiträge von bege

  • -moz-image-region ersetzen, Bilddatei mit vielen Symbolen

    • bege
    • 12. März 2023 um 22:07
    Zitat von grisu2099
    Zitat von bege

    aborix hatte mir ein Skript geschrieben, mit dem allen Menüeinträgen wieder die Class .menu-iconic oder .menuitem-iconic zugewiesen wurde.

    Das Skript würde ich gerne mal testen... ;)

    JavaScript: addMenuClass_aborix.uc.js
    setTimeout(function() {
        var ucjsAC = {
            init : function () {
                const menu = document.querySelectorAll('menu');
                menu.forEach(query => query.classList.add('menu-iconic'));
                
                const menuitem = document.querySelectorAll('menuitem');
                menuitem.forEach(query => query.classList.add('menuitem-iconic'));
            },
        }
    ucjsAC.init();
    }, 5000);
    Alles anzeigen

    Das funktioniert nur für Menüeinträge, die beim Start des Fx vorhanden sind. Vereinzelt erstellen Erweiterungen sie erst später, da funktioniert es nicht.

  • -moz-image-region ersetzen, Bilddatei mit vielen Symbolen

    • bege
    • 12. März 2023 um 21:16
    Zitat von 2002Andreas

    Den Code habe ich mal etwas angepasst, und bemerke keinerlei Probleme mit der :is Version.

    CSS
    menupopup menuitem.menuitem-iconic {
      margin-left: -6px;
    }
    
    menupopup :is(menu,menuitem):not(menuitem.menuitem-iconic):before {
      color: transparent !important;
      content: -moz-label-content;
      height:16px;
      width:16px;
      margin-right: 6px;
      margin-left: -4px;
    }
    #context-openlinkintab:before,
    #context-inspect-a11y:before,
    #context-inspect:before,
    #context-bookmarklink:before {
      background-image: url("file:///C:/Users/Andi/Icons%20Firefox/mosaic.png");
      background-position: -430px -144px;
    }
    
    #context-viewimage:before {
      background-image: url("file:///C:/Users/Andi/Icons%20Firefox/mosaic.png");
      background-position: -96px -144px;
    }
    
    #context-copylink:before {
      background-image: url("file:///C:/Users/Andi/Icons%20Firefox/mosaic.png");
      background-position: -80px -144px;
    }
    
    #context-saveimage:before {
      background-image: url("file:///C:/Users/Andi/Icons%20Firefox/mosaic.png");
      background-position: -130px -144px;
    }
    Alles anzeigen

    Evtl. kann Sören ja genaueres dazu sagen, ob das per :is keine gute Lösung in diesem Fall ist.

    Das macht mich auf einen Unterschied zu meinem bisherigen Code aufmerksam. aborix hatte mir ein Skript geschrieben, mit dem allen Menüeinträgen wieder die Class .menu-iconic oder .menuitem-iconic zugewiesen wurde. Dadurch habe ich nur list-style-image und -moz-image-region im CSS-Code benötigt, kein background und  :before oder sonst etwas.

    Jetzt bleibt also nur entweder das komplett umzubauen, oder eben doch die mosaic.png in einzelne Dateien aufzuspalten.

  • -moz-image-region ersetzen, Bilddatei mit vielen Symbolen

    • bege
    • 11. März 2023 um 21:29
    Zitat von 2002Andreas
    Zitat von Speravir

    zusammenfassen kann

    Z.B. so:

    CSS
    :is(menu,menuitem):before {
      color: transparent !important;
      content: -moz-label-content;
      height:16px;
      width:16px;
      margin-right: 6px;
      margin-left: -8px;
    }
    
    #context-bookmarklink:before {
      background-image: url("file:///C:/Users/Andi/Icons%20Firefox/mosaic.png");
      background-position: -430px -144px;
    }
    
    #context-viewimage:before {
      background-image: url("file:///C:/Users/Andi/Icons%20Firefox/mosaic.png");
      background-position: -96px -144px;
    }
    
    #context-copylink:before {
      background-image: url("file:///C:/Users/Andi/Icons%20Firefox/mosaic.png");
      background-position: -80px -144px;
    }
    
    #context-saveimage:before {
      background-image: url("file:///C:/Users/Andi/Icons%20Firefox/mosaic.png");
      background-position: -130px -144px;
    }
    Alles anzeigen

    Großartig, vielen Dank.


    Zitat von Speravir
    Zitat von 2002Andreas

    Z.B. so:

    Genau. Wobei hier vermutlich statt menu,menuitem besser mit den IDs der Kontextemenüeinträge zu hantieren wäre.

    Auch dir vielen Dank für die Vorarbeit. Wenn ich den CSS-Code der alten CuteMenus-Erweiterung nutze, wäre das ansprechen jeder ID wegen der vielen IDs nicht umsetzbar. Ich werde mir das mit etwas Muße mal anschauen und dann sehen, welcher Weg der einfachste ist.

  • -moz-image-region ersetzen, Bilddatei mit vielen Symbolen

    • bege
    • 8. März 2023 um 18:53
    Zitat von Sören Hentzschel

    Naja, anpassen musst du jetzt so oder so, auf die eine oder die andere Weise.


    Ab voraussichtliich Anfang Juli nicht mehr. ;)


    Bei dem Beispiel kann ich leider nicht direkt helfen. Da geht es um ein Kontextmenü und ich nutze macOS. Auf macOS werden die nativen Kontextmenüs des Betriebssystems genutzt, die können nicht via CSS angepasst werden. Aber um das mal etwas zu skizzieren:

    Mit einer Einzelgrafik kannst du einfach list-style-image überschreiben und die Zeile mit -moz-image-region entfernen. Fertig. Du musst dir null Gedanken über irgendwelche Koordinaten machen.

    Für ein Image Sprite musst du zusätzlich dazu, list-style-image und -moz-image-region zu entfernen, background-image definieren, background-size mit der Größe des Bildes und background-position mit den Start-Koordinaten, die anders angegeben werden als bei -moz-image-region. Möglicherweise brauchst du noch background-repeat. Im einfachsten Fall musst du noch width und height mit den Abmessungen der einzelnen Grafik angeben. Nur kann es je nach Element sein, dass du dieses damit verkleinerst, was unerwünscht wäre. Dann müsste man einen Teil des Codes in ein Pseudoelement (::before oder ::after) geben, welches man dann vermutlich absolut positionieren würde, was wiederum über ein halbes Dutzend weiterer Zeilen CSS bringt.

    Der Vorteil von Image Sprites ist eigentlich nur, dass man Dateigröße und die Anzahl benötigter Anfragen einsparen kann. Ein Gewinn der Dateigröße existiert aber halt auch nur, wenn man wirklich zumindest annähernd alle Icons verwendet. Und die Anzahl an Anfragen spielt heute im Web keine große Rolle mehr und im Kontext der Browseroberfläche sowieso nicht.

    Wenn man sowieso nur zwei Grafiken kombiniert (beispielsweise normal und :hover), kann ein Image Sprite eine elegante Lösung sein, auch weil der Aufwand überschaubar bleibt. Im :hover-Beispiel vermeidet man damit außerdem ein Flackern, wenn die :hover-Grafik noch nicht im Cache ist, wofür man sonst einen Workaround bräuchte, der wiederum mehr Zeilen CSS benötigt. Aber in diesem Fall glaube ich wirklich, dass man sich mit den Einzelgrafiken einen größeren Gefallen tut, weil die Bilddatei erstens so viel Unbenutztes beinhaltet und damit unnötig Ressourcen beansprucht, zweitens weil die Anpassung sehr viel einfacher ist und man nicht für jede Grafik einzeln die Position abmessen muss.

    Alles anzeigen

    Vielen Dank. 👍 Na, dann kann ich mich ja an die Arbeit machen.

  • -moz-image-region ersetzen, Bilddatei mit vielen Symbolen

    • bege
    • 7. März 2023 um 23:01
    Zitat von Sören Hentzschel

    Das ist richtig. Das macht es von der Anpassung her aber auch wesentlich komplizierter, weil du mehr CSS benötigst und ganz andere Positionsangaben benötigst. Die Grafik zurechtzuschneiden und einzubinden, ist da definitiv einfacher. Ich wollte mit meiner Aussage auch nur darauf hinaus, dass es technisch kein Muss ist, Einzelgrafiken zu erstellen. Der bessere Weg ist das nicht unbedingt, vor allem wenn das Image Sprite wie in diesem Fall aus mehreren hundert (!) Icons besteht, von denen sehr wahrscheinlich nur wenige überhaupt benutzt werden. Die Anwendungsfälle, bei denen Mozilla auf background-image umgestellt hat, waren bei weitem nicht so komplex.

    Ich nutze für die Symbole immer noch den CSS-Code der Uralt-Erweiterung CuteMenus, die tatsächlich viel mehr Code und Grafiken enthält, als benötigt werden. Nur erspart mir das eine Menge Arbeit, weil ich nicht selbst für jeden Menüeintrag den Code erstellen muss. Und in Thunderbird funktioniert es auch noch. Wenn ich das Image Sprite aufteile, habe ich auch eine Menge Arbeit, um den Code anzupassen.

    Könntest du mir für obiges Beispiel den Code angeben, wenn ich das Image Sprite behalten will? Dann kann ich sehen, welche Änderung weniger Arbeit macht.

  • -moz-image-region ersetzen, Bilddatei mit vielen Symbolen

    • bege
    • 7. März 2023 um 22:27
    Zitat von 2002Andreas

    Z.B. so:

    CSS
    #context-viewimage::before {
        background: url("file:///C:/Users/Andi/Icons%20Firefox/4.jpg")!important;
        margin-right: 8px !important; 
        margin-left: -6px !important;
        content: '' !important;
        display: block !important;
        width: 16px !important;
        height: 16px !important;
        background-repeat: no-repeat !important;
        background-position: 0px 0px !important;
        }
    Alles anzeigen

    D.h., du musst jetzt ein einzelnes Icon dafür nehmen.

    Das habe ich kapiert. Aber diese Aussage von Soeren

    Zitat

    Die andere Option, Einzelgrafiken aus solchen Mehrfachgrafiken zu machen, wie Aris es getan hat, geht natürlich auch, ist aber auch nicht zwingend notwendig

    aus RE: Entwicklung Firefox verstehe ich so, dass ich weiterhin die große Datei verwenden kann.

  • -moz-image-region ersetzen, Bilddatei mit vielen Symbolen

    • bege
    • 7. März 2023 um 20:33
    Zitat von 2002Andreas
    Zitat von bege

    wie ich -moz-image-region ersetzen muss

    Dazu gibt es schon einen Thread incl. Beispielen und Erklärungen:

    Beitrag

    RE: -moz-image-region entfällt

    […]

    […]

    Um keine Missverständnisse aufkommen zu lassen: list-style-image kann sehr wohl weiterhin genutzt werden, nur ab Firefox 112 nicht mehr mit sogenannten Sprite-Grafiken, das sind diese Grafiken, die aus mehreren Teilbildern bestehen (für die Suchmaschine: „CSS sprites“; im SelfHTML-Wiki: Sprites-Tutorial).

    Aris hat für seine Sammlung CustomCSSforFx genau die Lösung gewählt, die Sprites in ihre Teilgrafiken zu zerlegen und letztere jetzt einzeln anzusprechen.

    […]

    Ohne es mir im Detail…
    Speravir
    2. März 2023 um 23:56

    Dankeschön. Ich habe beide Threads gelesen und verstehen immer noch nicht, wie ich den obigen Code mit background-image und background-position ersetzten kann. Kannst du mir das an dem obigen Beispiel zeigen?

  • -moz-image-region ersetzen, Bilddatei mit vielen Symbolen

    • bege
    • 3. März 2023 um 00:47
    Zitat von Sören Hentzschel

    Ein konkretes Beispiel würde es einfacher machen. Den Selektor finde ich im Quellcode von Firefox nicht und die Grafik bitte auch anhängen.

    Zweiter Versuch:

    (Grafik in neuem Tab öffenen)

    CSS
    #context-viewimage {
    list-style-image:url('../../../../icons/mosaic.png')!important;
    -moz-image-region:rect(144px 112px 160px 96px)!important
    }

  • -moz-image-region ersetzen, Bilddatei mit vielen Symbolen

    • bege
    • 1. März 2023 um 21:06
    Zitat von Sören Hentzschel

    Weil hier und auch im GitHub-Issue clip-path erwähnt wurde: Der Zusammenhang zu -moz-image-region ist vor allem, dass auf dessen MDN-Seite erwähnt wird, dass die Syntax ähnlich zu clip ist, was wiederum zu Gunsten von clip-path nicht länger verwendet werden soll. Der naheliegende Ersatz für -moz-image-region, weil viel unkomplizierter, ist in vielen Fällen aber ganz einfach die Umsetzung als background. So hat es Mozilla beispielsweise hier gemacht:

    https://hg.mozilla.org/mozilla-central/rev/d8e1a8bee539

    Die andere Option, Einzelgrafiken aus solchen Mehrfachgrafiken zu machen, wie Aris es getan hat, geht natürlich auch, ist aber auch nicht zwingend notwendig und hat nach seinen eigenen Angaben die Dateigröße um 40 Prozent vergrößert, was ich für einen ziemlich starken Anstieg halte, falls das wirklich nur darauf zurückzuführen ist (womit die Gesamtgröße natürlich immer noch überschaubar ist und das kein Problem oder dergleichen darstellt, also alles gut). Die Austauschbarkeit ist bei Einzelgrafiken sicherlich einfacher. Die Wartbarkeit höher als die Dateigröße zu gewichten, ist auch vollkommen legitim.

    Ich habe noch nicht verstanden, wie ich -moz-image-region ersetzen muss, wenn ich eine Datei mit vielen Symbolen nicht in einzelne Dateien aufspalten will. Wie muss dann der neue Code für dieses Beispiel aussehen?

    CSS
    #idShowPicture {
    list-style-image:url('../../../../icons/mosaic.png')!important;
    -moz-image-region:rect(144px 112px 160px 96px)!important
    }
  • Skript "OpenbookModoki" funktioniert nicht mehr

    • bege
    • 29. Januar 2023 um 21:21
    Zitat von Mira_Belle
    Zitat von Sören Hentzschel

    Man ersetze alle collapsed durch hidden, dann sollte es wieder funktionieren.

    Funktioniert. Danke.

    Habe Dich verewigt und einen Link hierher gesetzt.

    Danke allen, die daran beteiligt waren.

    Wenn ich ein Schlagwort eingeben will, wird nach dem ersten Buchstaben das erste vorhandene Schlagwort mit diesem Anfangsbuchstaben eingefügt und hervorgehoben. Das führt dazu, dass mit dem zweiten eingegebenen Buchstaben der erste wieder weg ist.

    Lösche ich alles und gebe nochmal den ersten Buchstaben ein, werden nur die folgenden Buchstaben hervorgehoben und man bekommt immer die passenden vorhandenen Schlagwörter angezeigt. So sollte es gleich zu Beginn sein.

    Wie muss das Skript geändert werden, damit es gleich beim ersten Tippen richtig funktionert?

    Edit:

    In Aris' Version https://github.com/Aris-t2/Custom…_expanded.uc.js funktioniert das Schlagwörter-Feld, aber es fehlt das Schlüsselwort-Feld. Beim Vergleichen der Skripte schwirrt mir der Kopf, ich hoffe, jemand von euch findet den Haken.

  • Keine Erweiterunen mehr im Überhangmenü nach Update auf Fx109.0

    • bege
    • 22. Januar 2023 um 19:59
    Zitat von reni

    Sorry, wenn ich mich hier mein "einklinke" - Wer bestimmt eigentlich die Reihenfolge in dem Erweiterungsmenü und die Anzahl der angezeigten Erweiterungen?

    Bei mir stehen oben diejenigen, die ich vorher im Überhangmenü hatte, darunter alle anderen alphabetisch.


    Zitat von 2002Andreas
    Zitat von reni

    Wer bestimmt eigentlich die Reihenfolge

    Mozilla ;)

    In Zukunft werden die aber verschiebbar sein.

    Wenigstens etwas, das zur Übersichtlichkeit beiträgt.

  • Keine Erweiterunen mehr im Überhangmenü nach Update auf Fx109.0

    • bege
    • 22. Januar 2023 um 19:57
    Zitat von 2002Andreas
    Zitat von bege

    Habe ich etwas übersehen oder falsch verstanden

    Die sind jetzt alle in dem neuen Button oben rechts für Erweiterungen.

    Wenn nicht, sieh mal im Anpassenfenster nach.


    Zitat von bege

    das Überhangmenü tatsächlich nicht mehr für Addon-Buttons verwendet werden

    Richtig.

    Siehe bitte auch mal hier:

    Beitrag

    Addons-icon verstecken/entfernen

    kann ich dieses "puzzleteil" icon, das zum anzeigen und verwalten der addons hinzugefügt wurde, irgendwie los werden?

    Es gibt ka schon im Anwendungsmenü den Bereich Addons und themes, über den ich alles machen kann, dieses neue icon finde ich komplett unnötig. Ich kann es über "Symbolleiste anpassen" aber leider nicht verschieben. Gibt es es vielleicht eine Möglichkeit über about:config ?
    Thaliel
    18. Januar 2023 um 03:31

    So sieht das dann für die Zukunft aus:

    Alles anzeigen

    Danke für die prompte Antwort.

    Jetzt habe ich also zwei "Überhangmenüs", eins für Firefox-Funktionen und eines für Addons und kann nicht nur die Addon-Buttons darin anzeigen lassen, die ich ab und zu brauche, sondern muss durch alle nicht angezeigten Addon-Buttons scrollen. Schade, finde ich sehr umständlich.

  • Keine Erweiterunen mehr im Überhangmenü nach Update auf Fx109.0

    • bege
    • 22. Januar 2023 um 19:47

    Hallo,

    nach dem Update auf Fx109.0 sind alle Addon-Button aus dem Erweiterungsmenü verschwunden und auch im Pool von "Symbolleiste anpassen" gibt es keine Addon-Button mehr und es können auch keine mehr dorthin verschoben werden. Das Hinzufügen geht nur über den neuen Addon-Button. Die vorhandenen Buttons können auch nicht mehr ins Überhangmenü verschoben werden, sondern nur noch per Klick auf "an Symbolleiste anheften" entfernt werden.

    Habe ich etwas übersehen oder falsch verstanden, oder kann das Überhangmenü tatsächlich nicht mehr für Addon-Buttons verwendet werden, die man nicht so oft braucht? Das würde bedeuten, dass ich alle Buttons in einer Symbolleiste anzeigen muss, was Platzverschwendung und unübersichtlich wäre.

  • Skript "OpenbookModoki" funktioniert nicht mehr

    • bege
    • 22. Januar 2023 um 19:04

    Ich hatte damit schon länger noch ein anderes Problem. Wenn ich ein Stichwort eingeben wollte, sprang der Cursor nach dem ersten Buchstaben in das Feld für den Namen des Lesezeichens und löschte mit dem zweiten eingegebenen Buchstaben den dortigen Inhalt.

  • userChrome.js Scripte für den Fuchs (Diskussion)

    • bege
    • 29. November 2022 um 13:43
    Zitat von Doesbaddel

    Deshalb sage ich erstmal vielen Dank für die Hilfe und überlege weiter.

    Ich nutze die Erweiterung auch und ich weiß keine Lösung für deine Frage. Aber die Erweiterung setzt doch ein Symbol in die Adressleiste, das genau diese Funktion hat: Ein Klick und die Seite ist gespeichert. Hat es einen bestimmten Grund, dass du das über das Kontextmenü und nicht über dieses Symbol machen willst?

  • userChrome.js Scripte für den Fuchs (Diskussion)

    • bege
    • 24. September 2022 um 19:23

    Dharkness Wie schon geschrieben passt es für mich besser wie es ist. Vielleicht findet sich noch jemand, der es so sieht wie du und es umschreiben will.

  • userChrome.js Scripte für den Fuchs (Diskussion)

    • bege
    • 24. September 2022 um 14:13
    Zitat von Dharkness

    Hallo bege,

    warum im Menupopup noch ein Menupopup Namens Style-Loader-Menü erzeugen und da dann die Menuitems einfügen, kann man die Menuitems nicht direkt im Menupopup des Buttons einfügen?

    Kann man bestimmt, aber das ist wohl vom ursprünglichen Entwickler des Skripts so angelegt. Ich finde das auch übersichtlicher, weil ich eine Menge CSS-Dateien habe und seltener die anderen Menüpunkte nutze. Und für einen schnellen Zugriff auf eine Datei habe ich die Strg+Linksklick-Funktion hinzugefügt.

  • userChrome.js Scripte für den Fuchs (Diskussion)

    • bege
    • 24. September 2022 um 02:56

    Wer das Skript in #3092 vor dem Lesen dieses Beitrags kopiert hat, bitte nochmal updaten. Ich habe noch ein paar Korrekturen hinzugefügt.

  • userChrome.js Scripte für den Fuchs (Diskussion)

    • bege
    • 23. September 2022 um 22:10

    Ich habe das von Speravir überarbeitete Skript UserCSSLoader.uc.js aus dem Github von Endor übernommen. Danke für die Übersichtlichen Konfigurationseinstellungen am Anfang des Skripts und die Rechtschreibkorrekturen!

    Die Mittelklick-Funktion funktioniert bei mir aber nicht. In meiner Version des Skripts funktioniert sie und in Speravirs Version fehlt in Zeile 300 der Eintrag onmouseup : "if (event.button == 1) event.preventDefault();",

    Vielleicht liegt es daran.

    Ich habe das ergänzt und weitere Ergänzungen aus meiner Version eingefügt.

    • die Möglichkeit, dem eigenen Dateimanager einen Parameter mit zu übergeben (vor langer Zeit von aborix hinzugefügt)
    • die Wahl, außer dem verschiebbaren Button auch ein Menü anzuzeigen, habe ich auch noch in die Konfigurationseinstellungen gelegt
    • die Möglichkeit, außer dem CSS-Ordner auch den Chrome-Ordner anzuzeigen
    • mit Strg+Linksklick kann man die CSS-Datei im Dateimanager anzeigen lassen (mein Dateimanager markiert dabei die Datei. Den Windows-Explorer konnte ich nicht dazu "überreden", das wäre wohl ein größerer Umbau. Mit dem Windows-Explorer tut Strg+Linksklick auf eine Datei also nichts anderes als im Untermenü die Option "CSS-Ordner öffnen".
    • dem Untermenü habe ich eine ID zugefügt, damit ich per CSS ein Symbol anzeigen lassen kann
    • ich habe die Funktion getFileFromURLSpec durch die in anderen Skripten geänderte Funktion getURLSpecFromActualFile ersetzt. Ob das nötig ist, weiß ich nicht.
    • der Eintrag closeMenus(event.target); in den Zeilen 370 und 507 ergibt in der Fehlerkonsole einen allgemeinen Fehler, die Editierfunktion funktioniert aber trotzdem. In Thunderbird ergibt es den Fehler "closeMenus is undefined", was auch stimmt, und die Editierfunktion funktioniert nicht. Ich habe die Zeile mal auskommentiert, weil ich nicht weiß, wofür sie ursprünglich mal gedacht war.

    Will/soll Endor diese Version ins Github übernehmen?

    JavaScript: UserCSSLoader0.0.4k+uc.js
    // ==UserScript==
    // @name           UserCSSLoader
    // @description    CSS Codes - Styles laden und verwalten
    // @namespace      http://d.hatena.ne.jp/Griever/
    // @author         Griever
    // @include        main
    // @license        MIT License
    // @compatibility  Firefox 4 - 102*
    // @charset        UTF-8
    // @version        0.0.4K+
    // @note           Aktualisierung von Speravir - www.camp-firefox.de
    // @note           Fx92: getURLSpecFromFile() -> getURLSpecFromActualFile()
    // @note           AUTHOR_SHEET Verwendung hinzugefügt, wichtig: am Ende des Dateinamens .author.css
    // @note           Version 0.0.4.g ermoeglicht "Styles importieren" per Mittelklick und Verwendung
    // @note           eines anderen Dateimanager (siehe in Konfiguration)
    // @note           + ergänzt um einen Parameter für den Dateimanager (vFMParameter in der Konfiguration) von aborix
    // @note           Frei verschiebbare Schaltfläche eingebaut von aborix
    // @note           0.0.4 Remove E4X
    // @note           CSSEntry-Klasse erstellt
    // @note           Style-Test-Funktion überarbeitet
    // @note           Wenn die Datei gelöscht wurde, CSS beim Neu-Erstellen und Löschen des Menüs abbrechen
    // @note           uc einlesen .uc.css temporäre Korrespondenz zum erneuten Lesen
    // ==/UserScript==
    
    /****** Bedienungsanleitung ******
    
    CSS-Ordner im Chrome-Ordner erstellen, CSS-Dateien dort ablegen - speichern.
    Diejenigen, deren Dateiname mit "xul-" beginnen, diejenigen, die mit ".as.css" enden, sind AGENT_SHEET, 
    alle anderen außer USER_SHEET werden gelesen. Da der Inhalt der Datei nicht überprüft wird,
    darauf achten, @ Namespace Angabe nicht zu vergessen!
    
    CSS-Menü wird zur Menüleiste hinzugefügt
    Linksklick auf Stil, zum aktivieren/deaktivieren
    Mittelklick auf Stil zum aktivieren/deaktivieren, ohne Menü zu schließen
    Rechtsklick auf Stil zum Öffnen im Editor
    Strg+Linksklick zum Anzegen im Dateimanager
    
    Verwenden des in "view_source.editor.path" angegebenen Editors
    Dateiordner kann in Konfiguration geändert werden
    
     **** Anleitung Ende ****/
    
    (function(){
    
    /* Konfiguration */
    // Position: als Menü anzeigen = 1, als frei verschiebbare-Schaltfläche = 0
    let position = 0;
    // alternativer Dateimanager, Bsp.:
    // let filemanager = "C:\\Programme\\totalcmd\\TOTALCMD.EXE";
    let filemanager = "";
    // eventuelle Parameter für den alternativen Dateimanager, sonst filemanagerParam = "";
    let filemanagerParam = "";
    // Unterordner für die CSS-Dateien:
    let cssFolder = "CSS";
    // zusätzlich Chrome-Ordner im Untermenü anzeigen: 1 = ja, 0 = nein
    let showChrome = 0;
    /* Ende Konfiguration */
    
    let { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
    if (!window.Services)
        Cu.import("resource://gre/modules/Services.jsm");
    // Wenn beim Start ein anderes Fenster angezeigt wird (das zweite Fenster), wird es beendet
    let list = Services.wm.getEnumerator("navigator:browser");
    while(list.hasMoreElements()){ if(list.getNext() != window) return; }
    
    const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
    
    if (window.UCL) {
        window.UCL.destroy();
        delete window.UCL;
    }
    
    window.UCL = {
        vFileManager: filemanager,
        vFMParameter: filemanagerParam,
        USE_UC: "UC" in window,
        AGENT_SHEET: Ci.nsIStyleSheetService.AGENT_SHEET,
        USER_SHEET : Ci.nsIStyleSheetService.USER_SHEET,
        AUTHOR_SHEET: Ci.nsIStyleSheetService.AUTHOR_SHEET,
        readCSS : {},
        get disabled_list() {
            let obj = [];
            try {
                    obj = this.prefs.getCharPref("disabled_list").split("|");
            } catch(e) {}
            delete this.disabled_list;
            return this.disabled_list = obj;
        },
        get prefs() {
                delete this.prefs;
                return this.prefs = Services.prefs.getBranch("UserCSSLoader.")
        },
        get styleSheetServices(){
                delete this.styleSheetServices;
                return this.styleSheetServices = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
        },
        get FOLDER() {
            let aFolder;
            try {
                // UserCSSLoader.FOLDER verwenden
                let folderPath = this.prefs.getCharPref("FOLDER");
                aFolder = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile)
                aFolder.initWithPath(folderPath);
            } catch (e) {
                aFolder = Services.dirsvc.get("UChrm", Ci.nsIFile);
                aFolder.appendRelativePath(cssFolder);
            }
            if (!aFolder.exists() || !aFolder.isDirectory()) {
                aFolder.create(Ci.nsIFile.DIRECTORY_TYPE, 0664);
            }
            delete this.FOLDER;
            return this.FOLDER = aFolder;
        },
        get CHRMFOLDER() {
            let bFolder;
            try {
                // UserCSSLoader.CHRMFOLDER verwenden
                let CHRMfolderPath = this.prefs.getCharPref("CHRMFOLDER");
                bFolder = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile)
                bFolder.initWithPath(CHRMfolderPath);
            } catch (e) {
                bFolder = Services.dirsvc.get("UChrm", Ci.nsIFile);
            }
            if (!bFolder.exists() || !bFolder.isDirectory()) {
                bFolder.create(Ci.nsIFile.DIRECTORY_TYPE, 0664);
            }
            delete this.CHRMFOLDER;
            return this.CHRMFOLDER = bFolder;
        },
    
        getFocusedWindow: function() {
            let win = document.commandDispatcher.focusedWindow;
            if (!win || win == window) win = content;
            return win;
        },
    
        init: function() {
            let cssmenu = $C("menu", {
                id: "usercssloader-menu",
                label: "CSS",
                tooltiptext: "UserCSSLoader\n\nLinksklick: Stylesheets anzeigen\nMittelklick: Styles importieren",
                accesskey: "C",
                onclick: "if (event.button == 1) UCL.rebuild()"
            });
            let menupopup = $C("menupopup", {
                id: "usercssloader-menupopup"
            });
            cssmenu.appendChild(menupopup);
    
            let menu = $C("menu", {
                label: "Style-Loader-Menü",
                id: "style-loader-menu",
                accesskey: "M"
            });
            menupopup.appendChild(menu);
            menupopup.appendChild($C("menuseparator"));
            
            let mp = $C("menupopup", { id: "usercssloader-submenupopup" });
            menu.appendChild(mp);
            mp.appendChild($C("menuitem", {
                label: "Styles importieren",
                accesskey: "R",
                acceltext: "Alt + R",
                oncommand: "UCL.rebuild();"
            }));
            mp.appendChild($C("menuseparator"));
            mp.appendChild($C("menuitem", {
                label: "CSS-Datei erstellen",
                accesskey: "D",
                oncommand: "UCL.create();"
            }));
            mp.appendChild($C("menuitem", {
                label: "CSS-Ordner öffnen",
                accesskey: "O",
                oncommand: "UCL.openFolder();"
            }));
            if (showChrome == 1) {
              mp.appendChild($C("menuitem", {
                label: "Chrome Ordner öffnen",
                accesskey: "O",
                oncommand: "UCL.openCHRMFolder();"
              }));
            }
            mp.appendChild($C("menuitem", {
                label: "userChrome.css bearbeiten",
                hidden: false,
                oncommand: "UCL.editUserCSS(\'userChrome.css\');"
            }));
            mp.appendChild($C("menuitem", {
                label: "userContent.css bearbeiten",
                hidden: false,
                oncommand: "UCL.editUserCSS(\'userContent.css\');"
            }));
            mp.appendChild($C("menuseparator"));
            mp.appendChild($C("menuitem", {
                label: "Style-Test (Chrome)",
                id: "usercssloader-test-chrome",
                hidden: true,
                accesskey: "C",
                oncommand: "UCL.styleTest(window);"
            }));
            mp.appendChild($C("menuitem", {
                label: "Style-Test (Web)",
                id: "usercssloader-test-content",
                hidden: true,
                accesskey: "W",
                oncommand: "UCL.styleTest();"
            }));
            mp.appendChild($C("menuitem", {
                label: "Styles dieser Seite auf userstyles.org finden",
                      hidden: false,
                accesskey: "S",
                oncommand: "UCL.searchStyle();"
            }));
    
            menu = $C("menu", {
                label: ".uc.css",
                accesskey: "U",
                hidden: !UCL.USE_UC
            });
            menupopup.appendChild(menu);
            mp = $C("menupopup", { id: "usercssloader-ucmenupopup" });
            menu.appendChild(mp);
            mp.appendChild($C("menuitem", {
                label: "Importieren(.uc.js)",
                oncommand: "UCL.UCrebuild();"
            }));
            mp.appendChild($C("menuseparator", { id: "usercssloader-ucseparator" }));
    
            CustomizableUI.createWidget({
                id: 'usercssloader-menu-item',
                type: 'custom',
                defaultArea: CustomizableUI.AREA_NAVBAR,
                onBuild: function(aDocument) {
                    let toolbaritem = aDocument.createElementNS(XULNS, 'toolbaritem');
                    toolbaritem.id = 'usercssloader-menu-item';
                    toolbaritem.className = 'chromeclass-toolbar-additional';
                    return toolbaritem;
                }
            });
            $('usercssloader-menu-item').appendChild(cssmenu);
    
            if (position == 1) {
            let refNode = $('helpMenu');
            refNode.parentNode.insertBefore(cssmenu, refNode.nextSibling);
            }
    
            $("mainKeyset").appendChild($C("key", {
                id: "usercssloader-rebuild-key",
                oncommand: "UCL.rebuild();",
                key: "R",
                modifiers: "alt",
            }));
            this.rebuild();
            this.initialized = true;
            if (UCL.USE_UC) {
                setTimeout(function() {
                    UCL.UCcreateMenuitem();
                }, 1000);
            }
            window.addEventListener("unload", this, false);
        },
        uninit: function() {
            const dis = [];
            for (let x of Object.keys(this.readCSS)) {
                if (!this.readCSS[x].enabled)
                    dis.push(x);
            }
            this.prefs.setCharPref("disabled_list", dis.join("|"));
            window.removeEventListener("unload", this, false);
        },
        destroy: function() {
            var i = document.getElementById("usercssloader-menu");
            if (i) i.parentNode.removeChild(i);
            var i = document.getElementById("usercssloader-rebuild-key");
            if (i) i.parentNode.removeChild(i);
            this.uninit();
        },
        handleEvent: function(event) {
            switch(event.type){
                case "unload": this.uninit(); break;
            }
        },
        rebuild: function() {
            let ext = /\.css$/i;
            let not = /\.uc\.css/i;
            let files = this.FOLDER.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);
    
            while (files.hasMoreElements()) {
                let file = files.getNext().QueryInterface(Ci.nsIFile);
                if (!ext.test(file.leafName) || not.test(file.leafName)) continue;
                let CSS = this.loadCSS(file);
                CSS.flag = true;
            }
            for (let leafName of Object.keys(this.readCSS)) {
                const CSS = this.readCSS[leafName];
                if (!CSS.flag) {
                    CSS.enabled = false;
                    delete this.readCSS[leafName];
                }
                delete CSS.flag;
                this.rebuildMenu(leafName);
            }
            if (this.initialized) {
                if (typeof(StatusPanel) !== "undefined")
                    StatusPanel._label = "Style importiert";
                else
                    XULBrowserWindow.statusTextField.label = "Styles importieren";
            }
        },
        loadCSS: function(aFile) {
            var CSS = this.readCSS[aFile.leafName];
            if (!CSS) {
                CSS = this.readCSS[aFile.leafName] = new CSSEntry(aFile);
                if (this.disabled_list.indexOf(CSS.leafName) === -1) {
                    CSS.enabled = true;
                }
            } else if (CSS.enabled) {
                CSS.enabled = true;
            }
            return CSS;
        },
        rebuildMenu: function(aLeafName) {
            var CSS = this.readCSS[aLeafName];
            var menuitem = document.getElementById("usercssloader-" + aLeafName);
            if (!CSS) {
                if (menuitem)
                    menuitem.parentNode.removeChild(menuitem);
                return;
            }
            if (!menuitem) {
                menuitem = $C("menuitem", {
                    label : aLeafName,
                    id : "usercssloader-" + aLeafName,
                    class : "usercssloader-item " + (CSS.SHEET == this.AGENT_SHEET? "AGENT_SHEET" : CSS.SHEET == this.AUTHOR_SHEET? "AUTHOR_SHEET": "USER_SHEET"),
                    type : "checkbox",
                    autocheck : "false",
                    oncommand : "UCL.toggle('"+ aLeafName +"');",
                    onclick : "UCL.itemClick(event);",
                    onmouseup : "if (event.button == 1) event.preventDefault();",
                    tooltiptext : "Linksklick: an/aus, Menü schließt\nMittelklick: an/aus, Menü bleibt offen\nRechtsklick: bearbeiten\nStrg+Linksklick: im Dateimanager anzeigen"
                    });
                document.getElementById("usercssloader-menupopup").appendChild(menuitem);
            }
            menuitem.setAttribute("checked", CSS.enabled);
        },
        toggle: function(aLeafName) {
            var CSS = this.readCSS[aLeafName];
            if (!CSS || event.ctrlKey) return;
            CSS.enabled = !CSS.enabled;
            this.rebuildMenu(aLeafName);
        },
        itemClick: function(event) {
            let label = event.currentTarget.getAttribute("label");
            
            if (event.button == 0) {
               if (event.ctrlKey) {
                  event.preventDefault();
                  event.stopPropagation();
                  UCL.openFolder (label);
               } else {return;
               }
            }
                  event.preventDefault();
                  event.stopPropagation();
            if (event.button == 1) {
                this.toggle(label);
            }
            else if (event.button == 2) {
                // closeMenus(event.target);
                this.edit(this.getFileFromLeafName(label));
            }
        },
        getFileFromLeafName: function(aLeafName) {
            let f = this.FOLDER.clone();
            f.QueryInterface(Ci.nsIFile); // use appendRelativePath
            f.appendRelativePath(aLeafName);
            return f;
        },
        styleTest: function(aWindow) {
            aWindow || (aWindow = this.getFocusedWindow());
            new CSSTester(aWindow, function(tester){
                if (tester.saved)
                    UCL.rebuild();
            });
        },
        searchStyle: function() {
            let word;
            try {
                word = gBrowser.currentURI.host;
            } catch {
                word = gBrowser.currentURI.spec;
            }
            openWebLinkIn("https://userstyles.org/styles/search/" + word, "tab", {});
        },
        openFolder:function(label){
            if (label) {
            var target= this.FOLDER.path +  "\\" + label
            } else {
               var target= this.FOLDER.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=[this.vFMParameter,target];
                file.initWithPath(this.vFileManager);
                process.init(file);
                // Verzeichnis mit anderem Dateimanager öffnen
                process.run(false, args, args.length);
            } else {
                // Verzeichnis mit Dateimanager des Systems öffnen
                this.FOLDER.launch();
            }
        },
        openCHRMFolder:function(){
            if (this.vFileManager.length != 0) {
                var file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
                var process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess);
                var args=[this.vFMParameter,this.CHRMFOLDER.path];
                file.initWithPath(this.vFileManager);
                process.init(file);
                // Verzeichnis mit anderem Dateimanager öffnen
                process.run(false, args, args.length);
            } else {
                // Verzeichnis mit Dateimanager des Systems öffnen
                this.CHRMFOLDER.launch();
            }
       },
    
        editUserCSS: function(aLeafName) {
            let file = Services.dirsvc.get("UChrm", Ci.nsIFile);
            file.appendRelativePath(aLeafName);
            this.edit(file);
        },
        edit: function(aFile) {
            var editor = Services.prefs.getCharPref("view_source.editor.path");
            if (!editor) return alert("Unter about:config den vorhandenen Schalter:\n view_source.editor.path mit dem Editorpfad ergänzen");
            try {
                var UI = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
                UI.charset = window.navigator.platform.toLowerCase().indexOf("win") >= 0? "Shift_JIS": "UTF-8";
                var path = UI.ConvertFromUnicode(aFile.path);
                var app = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsIFile);
                app.initWithPath(editor);
                var process = Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess);
                process.init(app);
                process.run(false, [path], 1);
            } catch (e) {}
        },
        create: function(aLeafName) {
            if (!aLeafName) aLeafName = prompt("Name des Styles", dateFormat(new Date(), "%Y_%m%d_%H%M%S"));
            if (aLeafName) aLeafName = aLeafName.replace(/\s+/g, " ").replace(/[\\/:*?\"<>|]/g, "");
            if (!aLeafName || !/\S/.test(aLeafName)) return;
            if (!/\.css$/.test(aLeafName)) aLeafName += ".css";
            let file = this.getFileFromLeafName(aLeafName);
            this.edit(file);
        },
        UCrebuild: function() {
            let re = /^file:.*\.uc\.css(?:\?\d+)?$/i;
            let query = "?" + new Date().getTime();
            Array.slice(document.styleSheets).forEach(function(css){
                if (!re.test(css.href)) return;
                if (css.ownerNode) {
                    css.ownerNode.parentNode.removeChild(css.ownerNode);
                }
                let pi = document.createProcessingInstruction('xml-stylesheet','type="text/css" href="'+ css.href.replace(/\?.*/, '') + query +'"');
                document.insertBefore(pi, document.documentElement);
            });
            UCL.UCcreateMenuitem();
        },
        UCcreateMenuitem: function() {
            let sep = $("usercssloader-ucseparator");
            let popup = sep.parentNode;
            if (sep.nextSibling) {
                let range = document.createRange();
                range.setStartAfter(sep);
                range.setEndAfter(popup.lastChild);
                range.deleteContents();
                range.detach();
            }
            let re = /^file:.*\.uc\.css(?:\?\d+)?$/i;
            Array.slice(document.styleSheets).forEach(function(css) {
                if (!re.test(css.href)) return;
                let fileURL = decodeURIComponent(css.href).split("?")[0];
                let aLeafName = fileURL.split("/").pop();
                let m = $C("menuitem", {
                    label : aLeafName,
                    tooltiptext : fileURL,
                    id : "usercssloader-" + aLeafName,
                    type : "checkbox",
                    autocheck : "false",
                    checked : "true",
                    oncommand : "if (!event.ctrlKey) {this.setAttribute('checked', !(this.css.disabled = !this.css.disabled));}",
                    onclick : "UCL.UCItemClick(event);"
                });
                m.css = css;
                popup.appendChild(m);
            });
        },
        UCItemClick: function(event) {
            if (event.button == 0) return;
            event.preventDefault();
            event.stopPropagation();
            if (event.button == 1) {
                event.target.doCommand();
            }
            else if (event.button == 2) {
                // closeMenus(event.target);
                let fileURL = event.currentTarget.getAttribute("tooltiptext");
                let file = Services.io.getProtocolHandler("file").QueryInterface(Components.interfaces.nsIFileProtocolHandler).getURLSpecFromActualFile(fileURL);
                this.edit(file);
            }
        },
    };
    
    function CSSEntry(aFile) {
        this.path = aFile.path;
        this.leafName = aFile.leafName;
        this.lastModifiedTime = 1;
        this.SHEET = /^xul-|\.as\.css$/i.test(this.leafName) ? 
            Ci.nsIStyleSheetService.AGENT_SHEET:
            /\.author\.css$/i.test(this.leafName)?
            Ci.nsIStyleSheetService.AUTHOR_SHEET:
            Ci.nsIStyleSheetService.USER_SHEET;
    }
    CSSEntry.prototype = {
        sss: Components.classes["@mozilla.org/content/style-sheet-service;1"]
                .getService(Components.interfaces.nsIStyleSheetService),
        _enabled: false,
        get enabled() {
            return this._enabled;
        },
        set enabled(isEnable) {
            var aFile = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsIFile)
            aFile.initWithPath(this.path);
            var isExists = aFile.exists(); // true, wenn die Datei existiert
            var lastModifiedTime = isExists ? aFile.lastModifiedTime : 0;
            var isForced = this.lastModifiedTime != lastModifiedTime; // true, wenn es eine Änderung in der Datei gibt
            var fileURL = Services.io.getProtocolHandler("file").QueryInterface(Components.interfaces.nsIFileProtocolHandler).getURLSpecFromActualFile(aFile);
            var uri = Services.io.newURI(fileURL, null, null);
            if (this.sss.sheetRegistered(uri, this.SHEET)) {
                // Wenn diese Datei bereits gelesen wurde
                if (!isEnable || !isExists) {
                    this.sss.unregisterSheet(uri, this.SHEET);
                }
                else if (isForced) {
                    // Nach Stornierung erneut einlesen
                    this.sss.unregisterSheet(uri, this.SHEET);
                    this.sss.loadAndRegisterSheet(uri, this.SHEET);
                }
            } else {
                // Datei wurde nicht gelesen
                if (isEnable && isExists) {
                    this.sss.loadAndRegisterSheet(uri, this.SHEET);
                }
            }
            if (this.lastModifiedTime !== 1 && isEnable && isForced) {
                log(this.leafName + " wurde aktualisiert");
            }
            this.lastModifiedTime = lastModifiedTime;
            return this._enabled = isEnable;
        },
    };
    
    function CSSTester(aWindow, aCallback) {
        this.win = aWindow || window;
        this.doc = this.win.document;
        this.callback = aCallback;
        this.init();
    }
    CSSTester.prototype = {
        sss: Components.classes["@mozilla.org/content/style-sheet-service;1"]
                .getService(Components.interfaces.nsIStyleSheetService),
        preview_code: "",
        saved: false,
        init: function() {
            this.dialog = openDialog(
                "data:text/html;charset=utf8,"+encodeURIComponent('<!DOCTYPE HTML><html lang="de"><head><title>CSSTester</title></head><body></body></html>'),
                "",
                "width=550,height=400,dialog=no");
            this.dialog.addEventListener("load", this, false);
        },
        destroy: function() {
            this.preview_end();
            this.dialog.removeEventListener("unload", this, false);
            this.previewButton.removeEventListener("click", this, false);
            this.saveButton.removeEventListener("click", this, false);
            this.closeButton.removeEventListener("click", this, false);
        },
        handleEvent: function(event) {
            switch(event.type) {
                case "click":
                    if (event.button != 0) return;
                    if (this.previewButton == event.currentTarget) {
                        this.preview();
                    }
                    else if (this.saveButton == event.currentTarget) {
                        this.save();
                    }
                    else if (this.closeButton == event.currentTarget) {
                        this.dialog.close();
                    }
                    break;
                case "load":
                    var doc = this.dialog.document;
                    doc.body.innerHTML = '\
                        <style type="text/css">\
                            :not(input):not(select) { padding: 0px; margin: 0px; }\
                            table { border-spacing: 0px; }\
                            body, html, #main, #textarea { width: 100%; height: 100%; }\
                            #textarea { font-family: monospace; }\
                        </style>\
                        <table id="main">\
                            <tr height="100%">\
                                <td colspan="4"><textarea id="textarea"></textarea></td>\
                            </tr>\
                            <tr height="40">\
                                <td><input type="button" value="Vorschau" id="Vorschau"/></td>\
                                <td><input type="button" value="Speichern" id="Speichern"/></td>\
                                <td width="80%"><span class="log"></span></td>\
                                <td><input type="button" value="Schließen" id="Schliessen"/></td>\
                            </tr>\
                        </table>\
                    ';
                    this.textbox = doc.querySelector("textarea");
                    this.previewButton = doc.querySelector('input[value="Vorschau"]');
                    this.saveButton = doc.querySelector('input[value="Speichern"]');
                    this.closeButton = doc.querySelector('input[value="Schließen"]');
                    this.logField = doc.querySelector('.log');
                    var code = "@namespace url(" + this.doc.documentElement.namespaceURI + ");\n";
                    code += this.win.location.protocol.indexOf("http"||"https") === 0 ?
                        "@-moz-document domain(" + this.win.location.host + ") {\n\n\n\n}":
                        "@-moz-document url(" + this.win.location.href + ") {\n\n\n\n}";
                    this.textbox.value = code;
                    this.dialog.addEventListener("unload", this, false);
                    this.previewButton.addEventListener("click", this, false);
                    this.saveButton.addEventListener("click", this, false);
                    this.closeButton.addEventListener("click", this, false);
                    this.textbox.focus();
                    let p = this.textbox.value.length - 3;
                    this.textbox.setSelectionRange(p, p);
                    break;
                case "unload":
                    this.destroy();
                    this.callback(this);
                    break;
            }
        },
        preview: function() {
            var code = this.textbox.value;
            if (!code || !/\:/.test(code))
                return;
            code = "data:text/css;charset=utf-8," + encodeURIComponent(this.textbox.value);
            if (code == this.preview_code)
                return;
            this.preview_end();
            var uri = Services.io.newURI(code, null, null);
            this.sss.loadAndRegisterSheet(uri, Ci.nsIStyleSheetService.AGENT_SHEET);
            this.preview_code = code;
            this.log("Preview");
        },
        preview_end: function() {
            if (this.preview_code) {
                let uri = Services.io.newURI(this.preview_code, null, null);
                this.sss.unregisterSheet(uri, Ci.nsIStyleSheetService.AGENT_SHEET);
                this.preview_code = "";
            }
        },
        save: function() {
            var data = this.textbox.value;
            if (!data) return;
            var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
            fp.init(window, "", Ci.nsIFilePicker.modeSave);
            fp.appendFilter("CSS Files","*.css");
            fp.defaultExtension = "css";
            if (window.UCL)
                fp.displayDirectory = UCL.FOLDER;
            var res = fp.show();
            if (res != fp.returnOK && res != fp.returnReplace) return;
            var suConverter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
            suConverter.charset = "UTF-8";
            data = suConverter.ConvertFromUnicode(data);
            var foStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
            foStream.init(fp.file, 0x02 | 0x08 | 0x20, 0664, 0);
            foStream.write(data, data.length);
            foStream.close();
            this.saved = true;
        },
        log: function() {
            this.logField.textContent = dateFormat(new Date(), "%H:%M:%S") + ": " + $A(arguments);
        }
    };
    
    UCL.init();
    
    function $(id) { return document.getElementById(id); }
    function $A(arr) { return Array.slice(arr); }
    function $C(name, attr) {
        var el = document.createXULElement(name);
        if (attr) Object.keys(attr).forEach(function(n) { el.setAttribute(n, attr[n]) });
        return el;
    }
    function dateFormat(date, format) {
        format = format.replace("%Y", ("000" + date.getFullYear()).substr(-4));
        format = format.replace("%m", ("0" + (date.getMonth()+1)).substr(-2));
        format = format.replace("%d", ("0" + date.getDay()).substr(-2));
        format = format.replace("%H", ("0" + date.getHours()).substr(-2));
        format = format.replace("%M", ("0" + date.getMinutes()).substr(-2));
        format = format.replace("%S", ("0" + date.getSeconds()).substr(-2));
        return format;
    }
    
    function log() { Application.console.log(Array.slice(arguments)); }
    
    })();
    Alles anzeigen
  • Wie erstellt man keyboard shortcuts ?

    • bege
    • 7. Juli 2022 um 22:34

    Hier ein Beispiel, das aborix mal erstellt hat. Es schließt alle Tabs.

    JavaScript
    // ==UserScript==
    // key.CloseAllTabs_aborix.uc.js
    // https://www.camp-firefox.de/forum/viewtopic.php?p=1099118#p1099118
    // ==/UserScript== 
    
    (function() {
       setTimeout(function() {
      var browser_chrome = 'chrome://browser/content/browser.xhtml';
    
      if (location != browser_chrome)
        return;
     
      let key = document.createXULElement('key');
      key.id = 'key_closeAllTabs';
      key.setAttribute('key', 'W');
      // key.setAttribute('keycode', 'VK_F1')
      key.setAttribute('modifiers', 'alt');
      key.setAttribute('oncommand',
        'gBrowser.removeAllTabsBut(gBrowser.selectedTab); gBrowser.removeTab(gBrowser.selectedTab);');
      document.getElementById('mainKeyset').appendChild(key);
       }, 6000);
    })();
    Alles anzeigen

    Der timout-Wert am Ende muss angepasst werden.

Unterstütze uns!

Jährlich (2025)

0 %

0% (0,00 von 650 EUR)

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