Wikipedia:Technik/Browser/Greasemonkey

aus Wikipedia, der freien Enzyklopädie
Zur Navigation springen Zur Suche springen

Greasemonkey und Browser-Benutzerskripte


Diese Projektseite beschreibt Möglichkeiten, auf der lokalen Festplatte[1] gespeichertes JavaScript (JS) in der momentanen Wiki-Seite auszuführen.

Dieses Vorgehen hat folgende Vorteile:

  1. Nicht angemeldeten Benutzern („IP“) stehen in vollem Umfang JavaScript-Werkzeuge zur Verfügung.
  2. Die Inhalte bleiben der Web-Öffentlichkeit verborgen; anders als über Einstellungen.
  3. Der Quelltext lässt sich spontan auf der Festplatte abändern und wird beim Abruf der nächsten Wiki-Seite schon wirksam.
    Das ist auch für die Entwicklung von Skripten interessant, und es erspart das Hochladen neuer Versionen der Wiki-Benutzerseiten.

Die Skripte können zwischen mehreren Browsern geteilt werden; allerdings bleibt man auf die Reichweite der lokalen Speichermedien beschränkt.

Diese Seite zielt auf automatisch ablaufende Prozeduren ab. Zu einzeln manuell ausgelösten Aktionen siehe auch Bookmarklets.

Zwei Konzepte[Quelltext bearbeiten]

Ursprünglich gab es nur Greasemonkey.

  • Das war (und ist weiterhin) eine Bibliothek von Skripten in einem Add-on, das die Vorfilterung übernahm und eine Reihe von Hilfsfunktionen bereitstellte.
    • Skriptdateien auf der Festplatte konnten zur Berücksichtigung angemeldet werden.
  • Inzwischen gibt es auch „Browser-Benutzerskripte“. – Nicht zu verwechseln mit den „Wiki-Benutzerskripten“, etwa common.js und Skin-spezifisch.
    • Das Prinzip ist ähnlich.
    • In einem zu deklarierenden Verzeichnis auf der Festplatte werden Dateien abgelegt, deren Name beispielsweise auf .user.js enden muss.
    • Opera bot das bereits seit einer Weile an; Firefox realisierte es später und für mehrere andere Browser ist es 2015 noch im Gespräch.
    • Angestrebt wird, die gesamten Konfigurationsmöglichkeiten von Greasemonkey in die normale Benutzeroberfläche der Browser zu integrieren; etwa als Experten-Modus.

Allen Systemen gleich ist die Filterung.

  • Es soll nicht beim Besuch jeder Website jedes Skript gestartet werden.
  • Vielmehr soll auf bestimmten Webseiten, oft einer ganzen Domain, ein bestimmtes Skript ausgeführt werden.
  • Dafür gibt es Deklarationen zu Beginn jeder Skriptdatei; etwa wie folgt:
// ==UserScript==
// @include     http://de.wikipedia.org/*
// @include     https://de.wikipedia.org/*
// ==/UserScript==
  • Greasemonkey oder der Browser prüfen diese Regeln. Sind alle Bedingungen erfüllt, wird das Skript für die aktuelle Seite ausgeführt; sonst nicht.
  • Die Syntax unterscheidet sich von System zu System etwas.

In der Regel kann das lokale Skript maximal die gleichen Aktivitäten (sandbox) ausführen, die auch ein Skript innerhalb des HTML-Dokuments ausführen darf.

Wenn allerdings Greasemonkey über ein Add-on benutzt wird, könnte dieses Add-on weitergehende Aktivitäten und Schnittstellen dafür bereitstellen.

  • So erlaubt ein Greasemonkey für Firefox die Abspeicherung von Parameterwerten in den Firefox-Einstellungen (about:config).
  • Ajax-Anfragen müssen nicht der Same-Origin-Bedingung unterliegen. So erlaubt die Funktion GM_xmlhttpRequest() die Abfrage von beliebigen Domains, etwa der Cloud-Helferlein, und das anschließende Einfügen der Antworten in die Wiki-Seite. Diese ist darin normalerweise begrenzt auf wikipedia.org usw.

Manche Browser oder Sicherheitszubehör (etwa NoScript) begrenzen den Zugriff auf lokale Dateien über URL mit file:/ – dies muss dann ausdrücklich erlaubt werden.

Zusammenarbeit mit MediaWiki[Quelltext bearbeiten]

Zu dem Zeitpunkt, zu dem das Benutzerskript (egal nach welchem System) ausgeführt wird, ist möglicherweise die Wikiseite noch gar nicht oder nur teilweise geladen.

Es ist erforderlich, das Laden abzuwarten, etwa um auf die Skriptbibliotheken von MediaWiki zugreifen zu können.

  • Manchmal gibt es hierzu Deklarationen wie
// @run-at      document-end
  • Greasemonkey-Pakete stellen teilweise Hilfsfunktionen zur Verfügung.
  • Immer funktioniert der folgende Weg:Anm.
function MeineStartfunktion() {
   //Dank AJAX, wird diese Funktion mehrfach aufgerufen. Wurde der Hauptteil der Seite geladen, wird der Listener entfernt.
   window.document.removeEventListener( "load", MeineStartfunktion, true );
   // mw und $ sind jetzt bekannt und können für weitere Aktivitäten genutzt werden.
   // ...
   // ...
}
window.document.addEventListener( "load", MeineStartfunktion, true );
  • Früher als das Ereignis "load" würde "DOMContentLoaded" eintreten, was zu schnellerem Aufbau der endgültigen Seite führt. Dies ist nicht in allen Browserversionen verfügbar.

Nach dem Laden kann genauso mit Skripten gearbeitet werden wie sonst auch.

  • Zu beachten ist, dass es sich bei diesem window um dasjenige der Wiki-Seite handeln muss; ggf. abzubilden über unsafeWindow (der Name verweist schon deutlich auf mögliche Sicherheitsprobleme) oder fortgeschrittene Techniken wie XPCSafeJSObjectWrapper.
  • Das für die Skripte sichtbare window gehört teilweise zu einem übergeordneten Kontext; nicht der Inhalt des Browser-Fensters (Tab), sondern das Browser-Fenster selbst. Hier sind teilweise Zugriffe auf den gesamten Browser oder die Eigenschaften dieses Fensters möglich, die einem Dokument aus dem Internet verwehrt bleiben.

Neben der automatisierten Ausführung beim Laden jeder Wiki-Seite käme auch ein interaktiver Start über Bookmarklets in Frage.

Im Einzelfall kann es sein, dass ein Skript nicht auf die Situation vorbereitet ist, dass ein Benutzer nicht angemeldet ist. Es ist aber sehr selten, dass wirklich auf Informationen zugegriffen wird, die nur bei angemeldeten Benutzern bekannt sind; falls doch, ist diese Situation in aktuellen Skripten bereits abgefangen.

Die Benutzerskripte sind genau wie durch angemeldete Benutzer einzubinden mittels mw.loader.load(URL); – zu den Einzelheiten siehe die Dokumentation zum einzelnen Skript.

Um die sonst nur angemeldeten Benutzern zur Verfügung stehenden Helferlein (Gadgets) zu nutzen, ist die in der Dokumentation zum Gadget angegebene Modul-ID anzugeben. Sollte dort nichts vermerkt sein, kann sie aus Spezial:Gadgets entnommen werden. Danach ist hier nur noch anzugeben: mw.loader.load(Modul-ID); – dem Namen des Gadgets ist ext.gadget. voranzustellen, um die Modul-ID zu bilden.

Beispiel:
mw.loader.load("ext.gadget.PermaPageLink");

Genau wie die JS-Ressourcen, die angemeldete Benutzer offen als Benutzerseiten präsentieren, können auch CSS-Deklarationen mittels lokaler Definitionen ersetzt oder ergänzt werden.

Zu den generell möglichen Vereinbarungen siehe WP:CSS.

Browser-CSS[Quelltext bearbeiten]

Manche Browser (etwa Opera bis zur Hauptversion 12) bieten die Möglichkeit, universelle Stile zu deklarieren.

  • Problem: Die Definition wird auf sämtliche besuchten Seiten angewendet. Das mindert die Performance; im Einzelfall kann es durch Namenskonflikte zu unerwünschten Effekten auf unbeteiligten Webseiten kommen.

Ein Lösungsweg kann sein, den spezifisch für Wikis vorhandenen Selektor body.mediawiki auszunutzen; das betrifft dann allerdings jedes Wiki, das mit der MediaWiki-Software arbeitet.

Firefox[Quelltext bearbeiten]

Bereits seit einigen Jahren und Versionen gibt es die Möglichkeit, bei der Mozilla-Familie den allgemeinen Browser-Stil wie auch das Erscheinungsbild bei jedem einzelnen Browser-Benutzer zu konfigurieren.

  1. Konfigurationsseite aufsuchen
    • about:support in der URL-Adresszeile eingeben oder
    • HilfeInformationen zur Fehlerbehebung
  2. Abschnitt „Allgemeine Informationen“
    • Feld „Profilordner“
      • Button Ordner anzeigen
  3. Man gelangt in das persönliche Browser-Benutzer-Profil im Dateisystem seines Rechners.
  4. Darin einen Unterordner chrome anlegen, falls noch nicht vorhanden.
  5. In chrome eine Datei userContent.css anlegen, falls noch nicht vorhanden.
  6. Darin können nun CSS-Anweisungen geschrieben werden, die sich aber auf jede besuchte Website auswirken.
  7. Anschließend ist wohl ein Browser-Neustart erforderlich, damit die Änderungen wirksam werden.
  8. Um den Effekt zu begrenzen, kann spezifiziert werden:
@-moz-document domain(wikipedia.org) {
    .cn-fundraising { 
       display: none;
    }
}
(hier Ausblenden der Werbebanner)
Alles im eingeklammerten Bereich bleibt auf die jeweilige Domain begrenzt:
@-moz-document domain(wikipedia.org) {

}

Add-on[Quelltext bearbeiten]

Über Add-ons könnten die Domains näher spezifiziert werden, für die zusätzliche Regeln aktiviert werden sollen.

  • Add-ons, die analoge Regeln zu Greasemonkey bieten (ohne Gewähr):
  • localFileContent erlaubt die Zuordnung lokaler Dateien zu wenigen Domains; wenn dies nur für Wiki-Domains benutzt wird, lassen sich auch CSS-Dateien gezielt einbinden.

JavaScript: Lokale Dateien[Quelltext bearbeiten]

Manche Browser unterbinden den Zugriff auf lokale Dateien völlig, so etwa Firefox seit Version 28 aus Sicherheitsgründen. Ansonsten kann statt http:// das Protokoll file:/ für den lokalen Dateizugriff benutzt werden.

  • Das ansonsten hierfür verwendete mw.loader.load() ist dafür nicht geeignet, da es die Protokolle im Internet http:// oder https:// voraussetzt und das lokale file:/ nicht unterstützt.
  • Die veraltete, jedoch 2014/15 wohl noch nutzbare wikibits-Funktion window.importStylesheetURI() unterliegt dieser Beschränkung nicht.
  • loadResourceFile greift auf lokale Dateien zu und fügt sie ein.
  • Über eine unauffällig gehostete Datei im Netz könnte versucht werden, CSS einzubringen; dem steht allerdings entgegen, dass eine Seite unter https keine Ressourcen von fremden Domains akzeptieren soll (same origin policy).
  • localFileContent (Firefox) ist ein Add-On, das weiterhin kontrolliert für bestimmte Dateien und Domains das Laden zulässt.

JavaScript: Textdefinition[Quelltext bearbeiten]

  • Die Deklarationen können als Zeichenkette in ein JS-Programm integriert werden.
    • mw.util.addCSS() kann benutzt werden, um CSS-Deklarationen direkt in der Seite wirksam werden zu lassen.
    • Die Hilfsfunktion GM_addStyle() der Greasemonkey-Pakete macht genau das Gleiche; sofern vorhanden.
    • Problem: Zeilenumbrüche innerhalb einer Zeichenkette sind in JavaScript eigentlich nicht erlaubt. Zeichenkettenbegrenzer (' und ") müssten aufeinander abgestimmt werden.
  • Falls der Browser den lokalen Zugriff erlaubt, könnte der Import mittels einer einzelnen CSS-Zeile funktionieren:
    @import("file:/Meine Dateien/Wiki/mein.css")
  • Das Benutzerskript loadResourceFile stellt eine Hilfsfunktion loadFiles() bereit, mittels derer sich lokale JS- und CSS-Dateien in die Wiki-Seite laden lassen.
    • Weiterhin können damit spontan interaktiv lokale JS- und CSS-Dateien in die Wiki-Seite geladen werden.
  • LocalFileContent (Firefox) ist ein Add-On, das kontrolliert für bestimmte Dateien und Domains das Laden zulässt.
  1. Festplatte als bekanntester häufigster Vertreter; gilt selbstverständlich für sämtliche lokalen Speichermedien einschließlich lokalem Netzwerk.