Firefox-Erweiterungen mit dem Add-on-SDK erstellen – Teil II

Firefox-icon_cc-by-nc-nd_from_BenjigarnerIm ersten Teil der Reihe wurde erläutert, wie das Add-on-SDK eingerichtet und ein Symbol zur Add-on-Leiste hinzugefügt wird. Es soll nun mit der Erweiterung möglich sein, den gerade markierten Begriff in Wikipedia nachzuschlagen. Außerdem wird erklärt, wie ein Eintrag im Kontextmenü angelegt wird und wie man seine Erweiterung mit anderen Firefox-Nutzern teilen kann.

Ermitteln des ausgewählten Textes

Die an die Erweiterung gestellte Aufgabe umfasst zwei Teilaufgaben: Als erstes muss festgestellt werden, welcher Text gerade markiert ist und anschließend muss der Wikipedia-Artikel in einem neuem Tab geöffnet werden.

Um den Inhalt der aktuellen Auswahl zu bekommen, stellt das SDK das Modul selection [2] zur Verfügung. Um das Modul nutzen zu können, muss es zunächst – wie schon vom widget-Modul bekannt – per

1
var selection = require("sdk/selection");

in die main.js eingebunden werden. Mit der Ende Januar erschienenen SDK-Version 1.13 hat sich die Syntax von require übrigens ein wenig verändert [3]. Wegen Änderungen an der SDK-Struktur muss nun sdk/ vor den Modulnamen geschrieben werden; die alte Syntax (require("selection")) ist aber aus Kompatibilitätsgründen zur Zeit auch noch gültig.

Die aktuelle Auswahl soll dann ausgelesen werden, wenn das „W“-Widget angeklickt wird. Dafür wird eine Funktion verwendet, die aufgerufen wird, wenn das click-Event [4] des Widgets ausgelöst wird. Ein erster Ansatz, der die aktuelle Auswahl selection.text in die Fehlerkonsole [5] schreiben soll, könnte so aussehen:

1
2
3
4
5
6
7
8
9
10
11
var selection = require("sdk/selection");
var widgets = require("sdk/widget");

var widget = widgets.Widget({
id: 'wikipedia-icon',
label: 'Wikipedia',
content: '<b style="font-family:Times">W</b>',
onClick: function() {
console.log(selection.text);
}
});

Testet man nun den Code mit cfx run (vorher das Laden des SDK per source bin/active nicht vergessen!), öffnet eine Webseite, markiert Text, klickt auf das „W“ und schaut in der Fehlerkonsole („Extras -> Web-Entwickler -> Fehlerkonsole“) nach, sieht man aber nur „info: meine-erweiterung: null“. null bedeutet, dass kein Text markiert ist. Wie kann das sein? Sobald auf das „W“ geklickt wird, verliert die Webseite – und damit auch die Selektion – den Fokus und es gibt nun tatsächlich keinen markierten Text mehr.

Das Problem lässt sich lösen, indem sich die Erweiterung immer den zuletzt markierten Text merkt. Dazu wird das select-Ereignis des selection-Moduls verwendet:

1
2
3
4
5
6
7
var selectedText;

function selectionChanged(event) {
selectedText = selection.text;
}

selection.on("select", selectionChanged);

Die Funktion selectionChanged wird jedes Mal aufgerufen, wenn ein anderer Text markiert wird. Dieser Text wird dann in der Variablen selectedText gespeichert. Die onClick-Funktion muss jetzt noch in

console.log(selectedText);

geändert werden. Erneutes Testen zeigt, dass dieser Lösungsansatz wie gewollt funktioniert.

ffox_addonsdk_konsole.png
Das Wort „Mozilla“ wurde markiert und mit einem Klick auf das „W“ öffnet sich die Fehlerkonsole.

Öffnen eines Tabs

Nun soll der zum ausgewählten Text passende Wikipedia-Artikel in einem neuen Tab angezeigt werden. Das dafür nötige Modul heißt tabs [6] und wird mit

1
var tabs = require("sdk/tabs");

eingebunden. Um einen neuen Tab zu öffnen, wird die Funktion open verwendet:

1
2
3
4
onClick: function() {
console.log(selectedText);
tabs.open("http://de.wikipedia.org/w/index.php?search=" + selectedText);
}

Ein Eintrag im Kontextmenü

Damit der Benutzer der Erweiterung mit der Maus nicht immer den „langen“ Weg zum „W“-Symbol zurücklegen muss, soll nun ein Eintrag im Kontextmenü [7] angelegt werden. Das benötigte Modul context-menu [8] wird wie üblich mit

1
var cm = require("sdk/context-menu");

geladen. Der Code zum Erzeugen des Menüeintrags könnte so aussehen:

1
2
3
4
5
6
7
8
9
cm.Item({
label: "Wikipediaartikel aufrufen",
context: cm.SelectionContext(),
contentScript: 'self.on("click", self.postMessage);',
onMessage: function() {
console.log(selectedText);
tabs.open("http://de.wikipedia.org/w/index.php?search=" + selectedText);
}
});

Die Beschriftung des Menüeintrags ist „Wikipediaartikel aufrufen“ (label) und der Eintrag wird nur dann angezeigt, wenn auf der angezeigten Seite Text markiert ist (context).

Um mit der Benutzeroberfläche (also auch Menüeinträgen) zu kommunizieren, werden sogenannte „Content Scripts“ [9] verwendet. Der Sinn der Content-Skripte ist der, dass es, wenn in Firefox in Zukunft die Benutzeroberfläche, Add-ons und auch Webinhalte in unterschiedlichen Prozessen ausgeführt werden, nicht mehr möglich sein wird, dass Skripte des Benutzeroberflächen-Prozesses auf Inhalte der Add-on-Skripte zugreifen können; deshalb werden diese schon jetzt strikt getrennt.

Content-Skripte werden in der Regel als separate Dateien angelegt (dazu gibt es in einem späteren Teil mehr Informationen). Da in diesem Fall das Skript nur aus einem Befehl besteht, ist es auch legitim, diesen Befehl direkt in der main.js anzugeben. Das Skript sendet mit self.postMessage eine (leere) Nachricht an die Erweiterung, sobald das click-Event ausgelöst wird. Dann wird die unter onMessage angegebene Funktion aufgerufen, welche dann auf die bekannte Weise den Wikipediaartikel lädt.

Um doppelten Code zu vermeiden, ist es sinnvoll, den Code zum Anzeigen des Artikels in eine eigene Funktion zu schreiben:

1
2
3
4
5
6
7
8
9
10
11
12
13
function openArticle() {
console.log(selectedText);


tabs.open("http://de.wikipedia.org/w/index.php?search=" + selectedText);
}

cm.Item({
label: "Wikipediaartikel aufrufen",
context: cm.SelectionContext(),
contentScript: 'self.on("click", self.postMessage);',
onMessage: openArticle
});

Die onClick-Eigenschaft des Widgets wird analog angepasst.

ffox_addonsdk_kontextmenue.png
Der Menüeintrag „Wikipediaartikel aufrufen“.

Erstellen von XPI-Dateien

Wenn man anderen seine Erweiterung zur Verfügung stellen möchte, gibt man diese in der Regel als installierbare XPI-Datei [10] weiter.

Eine solche Datei erzeugt man mit dem Befehl

1
cfx xpi

Die XPI-Datei wird dann durch Ziehen in ein Firefox-Fenster installiert.

Nach der Installation sollte die Add-on-Leiste automatisch eingeblendet werden. Ist dies nicht der Fall, so liegt das daran, dass der Benutzer die Add-on-Leiste in der Vergangenheit manuell geschlossen hat. Sie kann dann über „Ansicht -> Symbolleisten -> Add-on-Leiste“ wieder angezeigt werden.

Zusammenfassung und Ausblick

Bisher wurde gezeigt, wie man Widgets in der Add-on-Leiste anzeigt (Modul widget), die aktuelle Auswahl abfragt (selection), Tabs öffnet (tabs) und Einträge im Kontextmenü erzeugt (context-menu). Im nächsten Artikel wird unter anderem gezeigt werden, wie Panels (kleine Pop-Ups) erstellt werden.

Die komplette Erweiterung kann als Archiv ffox_addonsdk_2.tar.gz und als installierbare Erweiterung ffox_addonsdk_2.xpi heruntergeladen werden.

Der Artikel Firefox-Erweiterungen mit dem Add-on-SDK erstellen – Teil II von Markus Brenneis, erschienen bei freiesMagazin unterliegt der CC-BY-SA-3.0 Unportted. Es wird die Erlaubnis gewährt, den Artikel unter den Bestimmungen der Creative-Commons-Lizenz zu kopieren, zu verteilen und/oder zu modifizieren.