Mozilla Firefox Auch wenn der Firefox sicherlich nicht zu schnellsten Browsern gehört, so ist er jedoch für fast jeden der im Internet unterwegs ist - vor allem aufgrund seiner Extension-Architektur zu einem unverzichtbaren Stück Software avanciert. Eine eigene Firefox-Extension zu entwickeln ist gar nicht schwer - und in diesem kleinen Tutorial möchte ich das an einem kleinen Beispiel zeigen.

Wichtig ist ersteinmal, dass man weiss, dass eine solche Extension, die mit der Dateinamenerweiterung .xpi daherkommt lediglich ein ZIP-Archiv ist.

Für unser kleines Beispiel legen wir folgende Dateistruktur an:

install.rdf
chrome/helloworld.jar

Die Datei: “helloworld.jar” ist ebenfalls ein ZIP-Archiv - doch zu dem Inhalt später mehr.

Wichtig ist erstmal die Datei install.rdf. Es handelt sich dabei um ein XML-Dokument, das Firefox Instruktionen über das Plugin und seine Installation gibt.

< ?xml version="1.0"?>
<rdf xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
    <description about="urn:mozilla:install-manifest">
        <em :id>{3341e492-ec34-4d6f-ad1f-e4b38ccb73e5}</em>
        <em :name>Hallo Welt</em>
        <em :version>0.1</em>
        <em :description>Beispiel-Firefox-Extension</em>
        <em :creator>Juniperus</em>
        <em :homepageURL>http://guxx.de</em>
        <em :iconURL>chrome://helloworld/skin/helloworld.png</em>
        <em :aboutURL>chrome://helloworld/content/about.xul</em>
        <em :file>
            <description about="urn:mozilla:extension:file:helloworld.jar">
                <em :package>content/helloworld/</em>
                <em :skin>skin/classic/helloworld/</em>
            </description>
        </em>
        <em :targetApplication>
            <description>
                <em :id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em>
                <em :minVersion>0.7</em>
                <em :maxVersion>9.9</em>
            </description>
        </em>
    </description>
</rdf>

Die meisten Tags sollten selbsterklärend sein. Wichtig ist dass meine eindeutige ID für seine Extension vergibt. So eine ID kann man sich zum Beispiel Online erzeugen lassen. Die id in der targetApplication darf nicht geändert werden. Sie gibt an, dass die Extension für den Firefox gedacht ist. Allerdings kann man die Versionen auf denen die Extension funktionert eingrenzen.

Nun kommen wir aber zu den Inhalten der *.jar Datei. Wie man bereits in der install.rdf gesehen hat, erfolgt hier ein Zugriff auf “chrome://” das entspricht quasi dem Pfad innerhalb des *.jar Archivs. Dort werden dann die eigentlichen Daten und Programmteile der Extension abgelegt. Über die Information in der “aboutURL” kann man sehen, dass es in dem Archiv eine Datei mit dem Namen und Pfad “helloworld/content/about.xul” geben soll. Diese wird ausgeführt, wenn jemand versucht den About-Dialog der Extension aufzurufen.

Die Komplette Verzeichnisstruktur des *.jar Archivs sieht nun folgendermaßen aus:

content/
content/helloworld/
content/helloworld/about.xul
content/helloworld/contents.rdf
content/helloworld/helloworldOverlay.js
content/helloworld/helloworldOverlay.xul
skin/
skin/classic/
skin/classic/helloworld/
skin/classic/helloworld/contents.rdf
skin/classic/helloworld/helloworld.png
skin/classic/helloworld/helloworldb.png

content:

  • Wie bereits erwähnt handelt es sich bei der about.xul-Datei um das XUL-Dokument für das About-Dialogfeld.
  • contents.rdf ist das Manifest
  • helloworldOverlay.js beinhaltet die Javascript Funktionen der Extension
  • helloworldOverlay.xul beinhaltet die Interface-Definition für die Extension

skin:

  • contents.rdf ist auch hier das Manifest, dass den Inhalt des Verzeichnisses definiert.
  • helloworld.png und helloworldb.png sind einfache PNG-Bilder, die in diesem Fall als Logo in verschiedenen Größen für (z.B.) den About-Dialog benutzt werden.

Die Erweiterung

Das Manifest mit dem der Inhalt des jeweiligen Verzeichnisses beschrieben wird sieht folgendermaßen aus:

< ?xml version="1.0"?>
 
<rdf :RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
 
  </rdf><rdf :Seq RDF:about="urn:mozilla:package:root">
    <rdf :li RDF:resource="urn:mozilla:package:helloworld"/>
  </rdf>
 
  <rdf :Seq RDF:about="urn:mozilla:overlays">
    <rdf :li RDF:resource="chrome://browser/content/browser.xul"/>
    <rdf :li RDF:resource="chrome://navigator/content/navigator.xul"/>
  </rdf>
 
  <rdf :Seq RDF:about="chrome://browser/content/browser.xul">
    </rdf><rdf :li>chrome://helloworld/content/helloworldOverlay.xul</rdf>
 
 
  <rdf :Seq about="chrome://navigator/content/navigator.xul">
    </rdf><rdf :li>chrome://helloworld/content/helloworldOverlay.xul</rdf>
 
 
  <rdf :Description RDF:about="urn:mozilla:package:helloworld"
    chrome:displayName="Hallo Welt 0.1"
    chrome:author="Juniperus"
    chrome:authorURL="mailto:info@guxx.de"
    chrome:name="hallowelt"
    chrome:extension="true"
    chrome:description="Hello World-Applikation">
  </rdf>

bzw. für das Skin-Verzeichnis:

< ?xml version="1.0"?>
<rdf :RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
 
  </rdf><rdf :Seq about="urn:mozilla:skin:root">
    <rdf :li resource="urn:mozilla:skin:classic/1.0" />
  </rdf>
 
  <rdf :Description about="urn:mozilla:skin:classic/1.0">
    <chrome :packages>
      <rdf :Seq about="urn:mozilla:skin:classic/1.0:packages">
        <rdf :li resource="urn:mozilla:skin:classic/1.0:helloworld" />
      </rdf>
    </chrome>
  </rdf>

Das komplette User-Interface von Firefox ist in XUL und JavaScript entwickelt worden. XUL ist dabei ein XML-Dokument, das verschiedene Elemente, wie Buttons, Menüs, Toolbars usw. bietet. Die eigentlichen Funktionen werden dabei in JavaScript implementiert.

Ein Beispiel für ein XUL-Dokument ist hier unser About-Dialog.

< ?xml version="1.0" encoding="UTF-8"?>
< ?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window class="dialog"
        title="Hallo Welt"
        orient="vertical"
        autostretch="always"
        onload="sizeToContent()"
        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
<groupbox align="center" orient="horizontal">
<vbox>
  <text value="Hallo Welt" style="font-weight: bold; font-size: x-large;"/>
  <text value="Version. 0.1"/>
  <separator class="thin"/>
  <text value="Erstellt von:" style="font-weight: bold;"/>
  <text value="Juniperus" class="url"
        onclick="window.open('http://guxx.de/software'); window.close();"/>
  <separator class="thin"/>
    <text value="Homepage:" style="font-weight: bold;"/>
    <text value="http://guxx.de/"
          class="url"
        onclick="window.open('http://guxx.de/'); window.close();"/>
  <separator class="thin"/>
</vbox>
<spring flex="1"/>
<image src="chrome://helloworld/skin/helloworldb.png"/>
</groupbox>
 
  <hbox>
  <spacer flex="1"/>
   <button label="Close" oncommand="window.close();"/>
  </hbox>
</window>

Weitere Informationen über die Verwendung von XUL kann von der Seite xulplanet.com nachgelesen werden.

Um nun eigene Elemente und Funktionen zum Firefox hinzuzufügen werde sogenannte “XUL Overlays” erzeugt. Damit hat man die direkte Möglichkeit in das User Interface des Firefox einzugreifen - und neue Elemente hinzuzufügen oder zu manipulieren.

Das Dokument “helloworldOverlay.xul” definiert ein solches Overlay:

< ?xml version="1.0"?>
 
<overlay id="helloworldOverlay"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
<script type="application/x-javascript"
             src="chrome://helloworld/content/helloworldOverlay.js" />
 
<popup id="contentAreaContextMenu">
  <menuitem id="helloworld" label="Hallo Welt" accesskey="H"
  insertafter="context-stop" oncommand="hallowelt();"/>
</popup>
 
</overlay>

Damit wird ein Kontextmenüeintrag erzeugt, der nach dem Stop-Eintrag in das Menü eingefügt wird. Wenn dieser Menüeintrag vom User betätigt wird, dann wird die JavaScript-Funktion “hallowelt();” ausgeführt. Definiert wird diese in der Datei “helloworldOverlay.js”

function hallowelt()
{
        alert("Hallo Welt");
}

Lokalisierung

In der Regel möchte man mehrere Sprachversionen für eine Extension bereitstellen, ohne dafür wirklich für jede Sprache eine Extension anbieten zu wollen.

Wir erweitern dafür das “chrome” Archiv um das Verzeichnis “locale”.
Dort legen wird dann für jede Sprache, die wir unterstützen wollen ein Verzeichnis an. z.B. de-DE für deutsch - oder en-US für englisch.

In jedem verzeichnis wird dann eine Datei namens “overlay.dtd” angelegt, die folgendermaßen ausieht:

< !ENTITY  hello.about "About">
< !ENTITY  hello.text "Hello World">

für die englische und:

< !ENTITY  hello.about "Über">
< !ENTITY  hello.text "Hallo Welt">

für die deutsche Version.

in XUL kann dann über die Schreibweise &hello.about; auf die Übersetzungen zugegriffen werden.

Für das obige Beispiel würde dann:

<text value="&hello.text;" style="font-weight: bold; font-size: x-large;"/>

automatisch für die jeweils eingestellte Sprache den richtigen Wert werden zuweisen.

These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Technorati
  • MisterWong
  • del.icio.us
  • Digg
  • BlinkList
  • Furl