
Mit dem Add-on SDK, auch bekannt als Jetpack, hat Mozilla zusammen mit dem Add-on Builder eine großartige Möglichkeit geschaffen, auf einfache Weise Add-ons für Mozilla Firefox zu erstellen, zu deren Erstellung keine besonderen Kenntnisse notwendig sind. Entsprechende APIs erlauben dabei den Zugriff auf elementare Browserfunktionen, so dass man alleine hierdurch und gegebenenfalls ganz gewöhnliche Webstandards wie JavaScript sehr viel erreichen kann. Außerdem ist für derartige Erweiterungen zur Installation kein Neustart des Browsers notwendig.
Durch dieses How To möchte ich all jene zu dieser Thematik hinführen, die gerne selber die eine oder andere Anpassung an Firefox selbst vornehmen wollen, bisher aber vor der Thematik Add-on-Entwicklung zurückgeschreckt sind. Am Ende werden wir sehen, dass es überhaupt kein Hexenwerk ist, Programmierkenntnisse sind zumindest für einfache Anwendungen überhaupt nicht notwendig. Bewusst gehe ich nur auf einen Bruchteil der gebotenen Möglichkeiten ein, der Fokus sollte erst einmal darauf liegen, den Leser auf den Geschmack kommen zu lassen.
In diesem Beispiel werden wir eine simple Erweiterung schreiben, welche die Add-on Bar um Favicons anderer Seiten erweitert und diese verlinkt. Um das Ganze noch etwas spannender zu machen, werden wir die Erweiterung nach und nach in der Funktionalität erweitern, um so einen kurzen Einblick in verschiedene APIs zu bekommen.
Hilfreich bei der Entwicklung ist die wirklich hervorragende Dokumentation. Außerdem kann über einen Button im Add-on Builder jederzeit die aktuelle Version im Editor live getestet werden. Fehler werden in der Konsole angezeigt, welche ebenfalls über einen Button im Add-on Builder erreichbar ist.
Zu allererst starten wie den Add-on Builder und erstellen unser neues Projekt. In den Projekt-Einstellungen werden wir der Erweiterung einen Namen und eine Beschreibung verpassen, auf der linken Seite lassen wir als Bibliothek die aktuelle Version des SDK, aktuell Version 1.1, ausgewählt.
Erst einmal werden wir dafür sorgen, dass in der Add-on Bar Favicons angezeigt werden. Hierfür bedienen für uns der Widget-API. Um diese nutzen zu können, müssen wir sie einbinden. Anschließend können wir diese bereits gemäß Dokumentation in der main()-Funktion nutzen:
var widgets = require('widget');
widgets.Widget({
id: 'sh-at',
label: 'soeren-hentzschel.at',
contentURL: 'http://www.soeren-hentzschel.at/favicon.ico'
});
Und schon haben wir ein Icon in der unteren Leiste des Browsers. Wir könnten statt contentURL auch einfach content übergeben und wären so in der Lage, Text zu schreiben. Hierbei sollte allerdings noch das Attribut width gesetzt werden, um dem Widget die benötigte Breite mitzuteilen, ansonsten wird der Text unter Umständen abgeschnitten. Wichtig ist nur, dass das Widget entweder content oder contentURL enthält. Der Inhalt des label-Attributes ist (genauso wie eine eindeutige ID) zwingend erforderlich und erscheint außerdem, wenn man mit der Maus über das Element fährt.
Natürlich ist das jetzt noch nicht sonderlich spektakulär. Als nächstes wollen wir, dass sich bei Klick auf einen Link eine bestimmte Seite öffnet. Dafür binden wir zunächst die Tabs-API ein. Anschließend erweitern wir unser Widget um ein onClick-Event. Die Methode tabs.open() öffnet dabei eine Seite in einem neuen Tab und fokussiert diesen.
var tabs = require('tabs');
widgets.Widget({
// ...
onClick: function() {
tabs.open('http://www.soeren-hentzschel.at');
}
});
Im Prinzip reicht das schon, das Add-on erfüllt bereits mit diesen wenigen Zeilen Code seine Grundfunktionaltiät. Wir können jetzt auf den Download-Button klicken und erhalten damit bereits eine voll funktionale Erweiterung für Firefox, welche sich andere User einfach installieren können!
Natürlich können beliebig viele Widgets auf diese Weise in einem einzigen Add-on platziert werden. Also tun wir genau dies und erstellen nun unser zweites Widget. Um ein wenig Abwechslung reinzubekommen, werden wir nun für eines unserer Widgets nicht auf ein fremdes Favicon verweisen, sondern dieses direkt mitliefern. Wir ahnen es, auch zur Bereitstellung von Ressouren gibt es eine API, die sogenannte Self-API, welche wir auf äquivalente Weise einbinden. Anschließend gelangen wir über data.url() als contentURL auf unser Icon. Doch, halt! Wo ist unser Icon? Die Einbindung erfolgt denkbar einfach: Wir klicken auf der linken Seite auf das Plus bei Data und laden unser Icon über die Eingabemaske einfach hoch und benennen dieses gegebenenfalls noch um.
var self = require('self');
widgets.Widget({
// ...
contentURL: self.data.url('sh-at.ico')
});
Wie wir bereits festgestellt haben, werden Seiten in einem neuen Tab geöffnet und direkt fokussiert. Dieses Verhalten wollen wir jetzt ändern, doch nicht nur das – es wäre doch eine feine Sache, wenn wir dem User die Kontrolle darüber geben könnten, wie dieser die Seiten öffnet. Eine richtig schöne Prefs-API gibt es derzeit noch nicht, ist als P1-Priorität aber derzeit in Entwicklung. Zumindest aber gibt uns die aktuelle Version des SDKs über preferences-services die Möglichkeit, Schalter von about:config auszulesen. Eine dazu passende Oberfläche zum Setzen der Einstellungen in XUL umzusetzen würde den Rahmen dieses Artikels klar sprengen, ist an dieser Stelle aber auch nicht sonderlich wichtig.
Folgende zwei Möglichkeiten wollen wir dem User bieten: Entweder werden die Seiten weiter in einem neuen Tab geöffnet, dabei allerdings im Hintergrund geladen, also nicht weiter direkt fokussiert. Oder die Seite ersetzt den derzeit aktiven Tab. Besprechen wir also zuerst einmal, wie wir diese Ziele jeweils fix ohne entsprechende Einstellung erreichen.
Für Fall 1 müssen wir der Methode tabs.open() das Attribut inBackground mitgeben und auf true setzen. Dadurch ändert sich der Aufruf leicht:
widgets.Widget({
// ...
onClick: function() {
tabs.open({
url: 'http://www.soeren-hentzschel.at',
inBackground: true
}
}
});
In Fall 2 verzichten wir auf Einsatz der Funktion tab.oben() und setzen stattdessen das Attribut tabs.activeTab.url auf die entsprechende URL:
widgets.Widget({
// ...
onClick: function() {
tabs.activeTab.url = 'http://www.soeren-hentzschel.at'
}
});
Nach dieser grundsätzlichen Überlegung sind wir soweit, dass wir den User entscheiden lassen können. Entsprechend der bisher eingesetzten APIs werden wir nun preferences-service einbinden. Damit es überhaupt zu einer Überprüfung kommen wird, müssen wir die bisherige onClick-Funktion durch eine neue Funktion ersetzen, welche wir nun außerhalb der main()-Funktion erstellen werden und die die Überprüfung übernimmt. Im Beispiel nennen wir die Funktion openTab() und übergeben wie bereits der alten Funktion die URL als Parameter. In dieser Funktion überprüfen wir mittels prefs.get() die zu überprüfende Einstellung sowie den Standardwert, welcher greift, falls der User keine entsprechende Einstellung gesetzt hat (in diesem Fall ‘extensions.quicklaunch.tabsinbackground’ und true) und führen dann eine Fallentscheidung durch: Ist der Schalter true, wird Fall 1 ausgeführt, andernfalls Fall 2.
var prefs = require('preferences-service');
function openTab(url) {
if(prefs.get('extensions.quicklaunch.tabsinbackground', true) === true)
tabs.open({
url: url,
inBackground: true
});
else
tabs.activeTab.url = url;
}
widgets.Widget({
// ...
onClick: function() {
openTab('http://www.soeren-hentzschel.at');
}
});
Die nächste Idee ist, dass wir den Betreibern der verlinkten Seite eine simple Möglichkeit geben wollen festzustellen, dass Besucher über unsere Erweiterung auf die Seite gekommen sind. Dafür wollen wir der URL einen ref getauften Parameter anhängen, beispielsweise soll die URL http://www.soeren-hentzschel.at/?ref=quicklaunch übermittelt werden. Die Schwierigkeit hierbei ist, dass dieser Parameter je nachdem, ob bereits Parameter in der URL stecken, mit ? oder & eingeleitet werden muss. Zu diesem Zweck schreiben wir uns eine einfache Funktion, die das überprüft – das ist übrigens bis hierhin die einzige Stelle, wo wirklich JavaScript verwendet wird.
Den Link in unserer openTab()-Funktion erweitern wir hinterher um dieses Anhängsel.
function addReferer(url) {
var operator = (url.indexOf('?') === -1) ? '?' : '&';
return url + operator + 'ref=quicklaunch';
}
function openTab(url) {
var refurl = addReferer(url);
if(prefs.get('extensions.quicklaunch.tabsinbackground', true) === true)
tabs.open({
url: refurl,
inBackground: true
});
else
tabs.activeTab.url = refurl;
}
Als letztes Schmankerl in diesem Tutorial werden wir die Erweiterung noch um eine Logfunktion erweitern. Gerade bei größeren Erweiterungen ist es meiner Meinung nach wichtig, eine vernünftige Fehlerausgabe bereitzustellen, weswegen es mir an dieser Stelle zumindest einmal wichtig ist erwähnt zu haben, wie man Meldungen in die Konsole schreiben kann. In diesem Beispiel werden wir – wieder in Abhängigkeit einer User-Einstellung – jeden Klick inklusive Zeitpunkt festhalten. Diese Einstellung setzen wir als Standard auf false. Zum Schreiben der Log-Funktionen kann ganz einfach die Funktion console.log() verwendet werden. Wir setzen diese an das Ende unserer openTab()-Funktion:
function openTab(url) {
// ...
if(prefs.get('extensions.quicklaunch.consolelog', false) === true)
console.log('Quick Launch :\t' + new Date() + '\n' + refurl);
}
Am Ende noch einmal der komplette Beispiel-Code:
var widgets = require('widget');
var self = require('self');
var tabs = require('tabs');
var prefs = require('preferences-service');
function addReferer(url) {
var operator = (url.indexOf('?') === -1) ? '?' : '&';
return url + operator + 'ref=quicklaunch';
}
function openTab(url) {
var refurl = addReferer(url);
if(prefs.get('extensions.quicklaunch.tabsinbackground', true) === true)
tabs.open({
url: refurl,
inBackground: true
});
else
tabs.activeTab.url = refurl;
if(prefs.get('extensions.quicklaunch.consolelog', false) === true)
console.log('Quick Launch :\t' + new Date() + '\n' + refurl);
}
exports.main = function() {
widgets.Widget({
id: 'sh-at',
label: 'soeren-hentzschel.at',
contentURL: self.data.url('sh-at.ico'),
onClick: function() {
openTab('http://www.soeren-hentzschel.at');
}
});
widgets.Widget({
id: 'sozone',
label: 'Soccer-Zone',
contentURL: 'http://www.sozone.de/favicon.ico',
onClick: function() {
openTab('http://www.sozone.de/');
}
});
};
Das war es an dieser Stelle mit meiner Demo-Erweiterung. Ich hoffe, ich konnte ein paar der Grundlagen verständlich übermitteln und motivieren, sich intensiver mit dem Add-on SDK zu befassen. Ich für meinen Teil bin begeistert davon, wieviel man mit relativ einfachen Mitteln erreichen kann. Vor allem gegenüber der traditionellen Add-on-Erstellung für Firefox älter als Version 4.0 stellt das eine erhebliche Vereinfachung dar.
Nach diesen Begriffen suchten die Benutzer:
- firefox downloads add-on-bar
- e-mail in firefox schreiben
- firefox url an anwendung übergeben
- Thunderbird Erweiterungen entwickeln Tab öffnen
- addons mozilla programmieren tutorial
- firefox einstellungen erweitern
- firefox erweiterung schreiben
- addon widget builder
- mozilla firefox plugins programmieren
- onclick zwischenablage kopieren firefox
- extensions entwickeln für firefox
- firefox addon parameter an url hängen
- add on erstellen
- firefox erweiterung programmieren
- mozilla firefox addon erstellen
- mozilla firefox addon erstellen
- firefox adddons entwicklung
- firefox addon url aktuelles tab
- firefox addon entwickeln
- firefox addon entwickeln
- add on s für firefox schreiben
- add on s für firefox schreiben
- addons entwickeln
- addons entwickeln
- addons entwickeln
SEP












Hallo,
gibt es so was wie SelfHTML oder SelfPHP auch für die Widget-API bei Firefox?
Also eine Art Übersicht über alle möglichen Schlüsselwörter, die man verwendet kann.
Wo kann man zum Beispiel sehen, welche Ausrücke hinter “tabs” oder “URL” erlaubt sind?
Pragmatischer Hintergrund meiner Frage ist:
- wie lautet der Ausdruck um zu testen, ob gerade exakt 1 Tab geöffnet ist
- wie lautet der Ausdruck um zu testen, ob die URL des gerade aktiven Tab “www.beispiel.de” lautet
Hi,
die Dokumentation ist wie im Artikel verllinkt hier zu finden:
https://addons.mozilla.org/en-US/developers/docs/sdk/1.1/
Dort findest du eigentlich alles, was derzeit möglich ist.
Eine Möglichkeit, die oben genannten Fragen anzugehen, wäre vielleicht:
var tabs = require(‘tabs’);
exports.main = function() {
tabs.on(‘ready’, function(tab) {
if(tabs.length == 1)
console.log(‘The number of open tabs across all windows is 1′);
if(tab.url == ‘http://www.google.de/’)
console.log(‘The URL of the current tab is ‘ + tab.url);
});
};
ich hab im Mozilla Forum gefragt und mir wurde geholfen:
if (gBrowser.currentURI.spec == “chrome://speeddial/content/speeddial.xul” && gBrowser.browsers.length == 1)
{goQuitApplication();}
else
{gBrowser.removeCurrentTab();}
Jetzt ist FireGestures in Verbindung mit Speedial nochmal ein Stück besser