Schon immer wollte ich mehr darüber wissen, wie im Firefox Addons erstellt werden. Weniger hinsichtlich der Programmierung in den verschiedenen Internettechnologien, mehr vom Prozess betrachtet, wie diese auf die Endgeräte kommen. Da kam nachfolgende Herausforderung in einem mittelständischen Unternehmen zur richtigen Zeit.
Aufgabenstellung
Die interne Bookshelf-Wissensdatenbank1 ist für die Anwender leichter zugänglich zu machen. Das kann mit einem eigenen Suchdienst-Provider2 erfolgen. Auch das Markieren eines Wortes auf einer beliebigen Website und Suche per Rechtsklick aus dem Kontextmenü heraus ist eine Möglichkeit. Besondere Herausforderung bei diesem Kunden: Viele Arbeitsplätze sind aus guten Gründen nicht mit dem Internet verbunden. Ein Deployment innerhalb des Enterprise AD3 muss per Gruppenrichtlinie4 von eigenen, nicht-öffentlichen Servern erfolgen.
Voraussetzungen
Zum Einsatz kommt ausschließlich der Firefox ESR5, eine für Unternehmen angepasste Version mit der Fähigkeit, Addons auch außerhalb von addons.mozilla.org6 (abgekürzt: AMO) installieren zu können. Mozilla nennt diese Art der Verteilung “self-distribution”.7 Darüber hinaus wird ein Firefox-Entwickler-Konto benötigt. Die Registrierung ist kostenlos und benötigt lediglich eine funktionierende Email-Adresse.8
Aufbau
Ein Firefox-Addon ist vereinfacht gesagt Javascript-Code, das im geöffneten Firefox zwischen Anwender und einer Website ausgeführt wird. Es kann auf Objekte und Events des Browsers über eine API zugreifen9 und ihm stehen alle Elemente einer geöffneten Website im DOM10 zur Verfügung.
Als Bundle11 trägt ein Addon die Dateierweiterung .xpi12 und ist nichts anderes als eine gezippte Datei. Die Struktur für die enthaltenen Skripte, Sprachfassungen, Dateisignaturen und sonstige Assets wie Grafiken und Icons ist vorgegeben. Die wichtigsten Informationen stehen in einer manifest.json Datei im Root des Bundles. Ein eindeutiger Name muss nach dem Schema addon-name@domain-des-herstellers zusammen gesetzt sein.13
Damit das Addon auf einen Rechtsklick reagieren kann, wird eine background.js Datei14 erstellt, die das Kontextmenü um einen Eintrag erweitert. Mit dem aktuell markierten Text als Suchbegriff wird ein neues Tab mit den Suchergebnissen geöffnet. Der Host books.name.local in den nachfolgenden Quelltexten ist als Platzhalter zu verstehen.
browser.browserAction.onClicked.addListener(
function(tab) {
browser.tabs.create( { url: "https://books.name.local" } );
}
);
searchBooks = function(word) {
var query = word.selectionText;
query = query.replace(" ", " ");
browser.tabs.create({url: "https://books.name.local/search?term=" + query});
};
browser.contextMenus.create({
title: "Suche in Wissensdatenbank nach \"%s\"",
contexts:["selection"],
onclick: searchBooks
});
Zusätzlich ist die Wissensdatenbank als Such-Provider im Firefox anzulegen. Das erfolgt in der für jedes Addon obligatorischen Manifest-Datei im Abschnitt “chrome_settings_overrides”:15
"chrome_settings_overrides": {
"search_provider": {
"name": "Interne Wissensdatenbank",
"keyword": "@books",
"favicon_url": "https://books.name.local/favicon.ico",
"search_url": "https://books.name.local/search?term={searchTerms}",
"encoding": "UTF-8",
"is_default": true
}
},
Auch wenn das Erstellen eines Addons als 5-Minuten-Sache beworben wird16 habe ich mit 2-3 Stunden deutlich länger gebraucht. Haupthindernis war die schlechte und unübersichtliche Dokumentation im Mozilla Development Network17. Vor 10-15 Jahren war diese einst wegweisend und Referenz für alle Internet-Technologien. Heute ist diese gefühlt nur noch ein Schatten ihrer selbst. Aus für mich unerklärlich und besonders ärgerlichen Gründen fehlen Datumsangaben oder mindestens Hinweise “Achtung, nicht mehr gültig!” auf veraltete Versionen. So habe ich zum Beispiel Zeit für ein Bash-Skript verloren, weil ich fälschlicherweise annahm, die Signaturen im .xpi Bundle selbst vor einem Upload erzeugen zu müssen. Erfreulicherweise erledigt das Mozilla, zeigt aber eine Warnung.
Das Signieren und Freischalten erfolgte erfreulich schnell. Gefühlt nur wenige Minuten nach dem Upload konnte ich die fertige .xpi Datei wieder herunter laden. Antworten auf Fragen nach dem Quelltext oder Review-Hinweise an Mozilla brauchte ich nicht zu geben.
Ein alternativer Weg ohne Web-Oberfläche ist mit dem Kommandozeilen-Tool web-ext möglich.18 Bei weiterer Betrachtung, insbesondere dessen Voraussetzungen und Abhängigkeiten, habe ich von einer Installation Abstand genommen.19
Deployment
Das Side-Loading durch einfaches Kopieren der Datei in einen Ordner funktioniert seit Firefox 74 nicht mehr.20 Wer ein Addon nur für sich erstellt, kann es manuell durch Öffnen im Firefox ESR auch ohne Signing nutzen. Die Nutzung in einem Standard-Firefox oder bei Download von einem eigenen Server macht ein Signing durch Mozilla erforderlich.21 Ein Webserver mit der .xpi Datei muss den entsprechenden Content-Type gesetzt haben.22
Für das AD-Deployment im Netzwerk des Kunden wird das neue Addon in die Liste der bestehenden Addons mit dem https-Download-Link aufgenommen. Zusätzlich sind die “sicheren” Addon-Seiten um den eigenen Server zu ergänzen. Das .admx Template kann von Github geladen werden.23 Das Mozilla-Projekt bietet leider keine eigene Ressourcen.
Positiv bei der automatischen Verteilung via Gruppenrichtlinien im Vergleich zur manuellen Weitergabe ist, dass Endanwender nicht mit zusätzlichen Sicherheitshinweisen oder Nachfragen im Firefox belästigt werden. Lediglich bei Änderung der Standard-Suchmaschine gibt es eine.
Wie es sich gehört bekam der Kunde das Firefox-Addon für die Suche in seiner internen Wissensdatenbank als Git-Repository in einer freien GPL-Lizenz übergeben.
Zusammenfassung
Hat man den Bogen einmal raus, ist das Erstellen, Signieren und Verteilen von Firefox-Addons sehr einfach. Der Firefox übernimmt bei Hinterlegung einer passenden Update-URL in der Manifest-Datei auch die automatische Aktualisierung sofern keine anderweitigen Einstellungen in einer Gruppenrichtlinie dem entgegenstehen.
In der Theorie lassen sich Addons browserübergreifend sowohl für Mozilla Firefox, Google Chrome, Microsoft Edge, Apple Safari und demnächst auch Gnome Web erstellen. Praktisch unterscheiden sich die APIs so deutlich, dass ich mich bei dem Versuch in eine Zeit zurück geworfen fühlte, als unter jeder Seite ein “Best viewed in 800x600 with” Button eingeblendet war.
Die Dokumentation im Mozilla Development Network empfinde ich als suboptimal, wenn nicht sogar sträflich vernachlässigt. Für mich leider ein Anzeichen für krasses Mißmanagement24, wo viel Geld in Marketing und Management geworfen wird. Die relevanten Dinge25 und eine schlanke Engine zum Einbinden in eigene Softwareprojekte á la Blink26 oder WebKit27 fehlen. Das aber ist eine Geschichte für ein andermal.
In diesem Sinne,
Euer Tomas Jakobs
https://support.mozilla.org/en-US/kb/add-or-remove-search-engine-firefox ↩︎
https://extensionworkshop.com/documentation/publish/submitting-an-add-on/#self-distribution ↩︎
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API ↩︎
https://extensionworkshop.com/documentation/develop/extensions-and-the-add-on-id/ ↩︎
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Background_scripts ↩︎
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json ↩︎
https://extensionworkshop.com/documentation/develop/web-ext-command-reference/#web-ext-sign ↩︎
https://blog.mozilla.org/addons/2019/10/31/firefox-to-discontinue-sideloaded-extensions/ ↩︎
https://extensionworkshop.com/documentation/enterprise/enterprise-distribution/#signed-vs-unsigned ↩︎
https://extensionworkshop.com/documentation/publish/self-distribution/#options ↩︎
https://heise.de/news/Mozilla-streicht-Stellen-und-Projekte-4876909.html ↩︎