Forstwesen
Eine der größten Stärken der Mozilla-Plattform ist ihre einfache Erweiterbarkeit. Schon mit wenigen Zeilen XUL und Javascript lassen sich Anwendungen wie Mozilla und Firefox um eigene Funktionen erweitern.
- Karsten DĂĽsterloh
Standen im ersten Teil dieses Tutorials grundlegende Elemente wie label oder button im Vordergrund, die prinzipiell ohne lokale Dateirechte oder Ähnliches brauchbar sind, soll dieser Teil komplexere Aufgaben angehen. Ein moderater Schritt in diese Richtung ist die textbox als Standardeingabeelement. Durch das multiline-Attribut kann man eine mehrzeilige Darstellung erzwingen, die maximale Zeichenanzahl legt maxlength fest. Über das Ereignisattribut oninput kann die Anwendung schon während der Eingabe auf spezielle Zeichen et cetera reagieren, was bei einem gesetzten Attribut readonly="true" naturgemäß entfällt.
Eine einzeilige textbox mit dem Attributwert type="password" zeigt anstelle der eingegebenen Zeichen nur Sternchen an, das Attribut value liefert die wirkliche Eingabe. Setzt man hingegen type="autocomplete", bietet die textbox eine Liste mit früheren Eingaben mit denselben Anfangszeichen an; für Details sei hier auf die XUL-Referenzen in den „Online-Ressourcen“ verwiesen.
Online-Ressourcen
DOM-Inspector: Detailanzeige des erzeugten DOM eines Dokuments, von Mozilla-internen XUL-Dateien der Programmoberfläche eingeschlossen. In den meisten Mozilla- und Firefox-Versionen enthalten (www.mozilla.org/projects/inspector/ ). Für Thunderbird ist zur Zeit keine Version erhältlich.
Baumstrukturen mit tree darstellen
Wohl das komplexeste XUL-Element ist der tree, der mit seinen Unterelementen eine mehrspaltige Darstellung von Texten in geschachtelten Baumstrukturen erlaubt, beispielsweise von Verzeichnissen und in ihnen enthaltenen Dateien.
Wichtigstes direktes Kind eines tree ist treecols, das wiederum treecol-Elemente enthalten sollte, die die Spalten des Baumes definieren. Neben bekannten Attributen wie label (für den Spaltentitel) oder crop (Position der Auslassungsellipse in zu breiten Texten) kennt das treecol-Element weitere. Unter anderem erzeugt primary="true" die geschachtelte Baumstruktur mit Einrückungen, Linien und Aufklappgrafiken. (Um Schwierigkeiten bei Selektionen und sortierten Spalten zu vermeiden, sollte man treecol-Elemente grundsätzlich mit einer id definieren.) Neben Spaltentiteln dient in der Baumdarstellung ein spezielles Element zur Spaltenauswahl: Columnpicker. Wer das unterdrücken will, kann im tree das Attribut hidecolumnpicker="true" setzen.
Die darzustellenden Daten eines Baumes sind als treeitems rekursiv innerhalb des Elements treechildren notiert. Alle treeitems eines treechildren-Elements werden auf derselben Einrückungstiefe gezeichnet, können ihrerseits aber eigene Unterelemente innerhalb eines treechildren-Kindes anzeigen, die entsprechend tiefer eingerückt sind.
Jedes treeitem, gleichgültig auf welcher Tiefe, stellt eine Zeile im entstehenden Baum dar, ist jedoch nicht notwendigerweise direkt sichtbar. Das container-Attribut eines treeitem bestimmt darüber, ob die in seinem treechildren-Unterelement notierten Kind-treeitems überhaupt zugreifbar sind und die dazugehörige Aufklappgrafik angezeigt wird. Das open-Attribut befindet über die eigentliche Sichtbarkeit der Unterelemente, das Ausklappen des Astes.
Den Inhalt einer Baumzeile bezeichnet das treerow-Element. Selbst Kind eines treeitem, benötigt es für jede Spalte ein eigenes Unterelement mit den anzuzeigenden Daten: eine treecell mit einem label-Attribut.
Mit treeseparator steht eine spezielle Art von treeitem zur VerfĂĽgung, das lediglich eine Trennlinie mit optionalem label-Attribut in den Baum einfĂĽgt.
Neben den ĂĽblichen Ereignisattributen steht in einem tree insbesondere onselect zur VerfĂĽgung, womit die Anwendung auf die Wahl einer bestimmten Baumzeile reagieren kann. Vermittels des ĂĽbergebenen Event-Objekts sind die genauen treecell-Elemente des Klicks ermittelbar. Die Attributangabe seltype="single" erlaubt nur jeweils eine gleichzeitig selektierte Zeile, der Standardwert ist jedoch seltype="multiple".
Daten erst beim Laden erzeugen
Die wahre Stärke des tree-Elements liegt aber nicht in der Möglichkeit des manuellen Aufbaus, da dieser recht textlastig ist, wie Listing 1 zeigt. Außerdem ist eine Baumstruktur, deren Elemente insgesamt zum Zeitpunkt der Erstellung des Programmcodes bekannt sein müssen, meist wenig hilfreich.
Listing 1: Tree.xul
<?xml version="1.0"?>
<window
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="Tree">
<tree flex="1">
<treecols>
<treecol id="col1" label="Spalte 1" flex="1" primary="true"/>
<treecol id="col2" label="Spalte 2" flex="1"/>
</treecols>
<treechildren>
<treeitem container="true">
<treerow>
<treecell label="Text A1"/>
<treecell label="Text A2"/>
</treerow>
<treechildren>
<treeitem container="true" open="true">
<treerow>
<treecell label="Text B1"/>
<treecell label="Text B2"/>
</treerow>
<treechildren>
<treeitem>
<treerow>
<treecell label="Text C1"/>
<treecell label="Text C2"/>
</treerow>
</treeitem>
<treeseparator label="(Trennzeile)"/>
<treeitem>
<treerow>
<treecell label="Text C3"/>
<treecell label="Text C4"/>
</treerow>
</treeitem>
</treechildren>
</treeitem>
</treechildren>
</treeitem>
</treechildren>
</tree>
</window>
Zwar lassen sich XUL-Elemente wie herkömmliche DOM-Elemente mit Funktionen in Javascript erzeugen (var oTreeItem = document.createElement("treeitem") et cetera) und in die gewünschte Position im tree einfügen, dies ist jedoch nur für eine kleine Anzahl von Elementen hinreichend schnell.
Vielmehr kann ein solcher tree besonders einfach als „Datensenke“ für beliebige Datenquellen fungieren, indem man alle Funktionen und Variablen der nsITreeView-Schnittstelle in einem Javascript-Objekt (oder einer in C++ geschriebenen XPCOM-Komponente; das liegt aber außerhalb des Rahmens dieses Tutorials) nachbildet und die Verbindung zur Datenquelle selbst herstellt.
Eine solche selbstdefinierte Baumansicht erfordert im XUL-Dokument nur noch eine Rumpfangabe aus tree, treecols, treecol und treechildren, der eigentliche Baumaufbau findet in einem eigenen nsITreeView-Objekt innerhalb des script-Blocks statt. Die nsITreeView-Funktionen werden für sichtbare Elemente bei jedem Neuzeichnen des Fensters aufgerufen (ohne Neuladen), was in der Abbildung zu Listing 2 an der sich ändernden Uhrzeit zu erkennen ist.
Listing 2: TreeView.xul
<?xml version="1.0"?>
<window
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="TreeView" onload="InitView()">
<script type="application/x-javascript">
<![CDATA[
function InitView()
{
const koTreeView =
{
// 100 Zeilen im Baum
rowCount: 100,
getCellText: function(aiRow, aoColumn)
{
if (aoColumn.id == "RowCol")
// Zeilennummer
return "Zeile " + aiRow;
else
// aktuelles Datum und Uhrzeit
return (new Date).toLocaleString();
},
setTree: function(aoTreeBox)
{ // die zugehörige XUL-Box merken
this.treebox = aoTreeBox;
},
isContainer: function(aiRow)
{ // jedes 5. Zeile sei ein Blatt
return !!(aiRow % 5);
},
isSeparator: function(aiRow)
{ // jedes Blatt sei ein Trenner
return !(aiRow % 5);
},
getLevel: function(aiRow)
{ // Blätter auf tiefster Ebene
return (aiRow - 1) % 5;
},
getParentIndex: function(aiRow)
{ // unter vorhergehende hängen
return aiRow - 1;
},
hasNextSibling: function(aiRow, afterIndex)
{ // nur auf Ebene 0
return !((aiRow - 1) % 5);
},
// nicht selbst genutzte Funktionen
// der nsITreeView-Schnittstelle
// mĂĽssen dennoch vorhanden sein
getRowProperties: function(index, properties){},
getCellProperties: function(row, col, properties){},
getColumnProperties: function(col, properties) {},
isContainerOpen: function(index){return true},
isContainerEmpty: function(index){return false},
isSorted: function(){return false},
canDrop: function(index, orientation){return false},
drop: function(row, orientation){},
getImageSrc: function(row, col){return null},
getProgressMode: function(row, col){return 3},
getCellValue: function(row, col){return null},
toggleOpenState: function(index){},
cycleHeader: function(col){},
selectionChanged: function(){},
cycleCell: function(row, col){},
isEditable: function(row, col){return false},
setCellValue: function(row, col, value){},
setCellText: function(row, col, value){},
performAction: function(action){},
performActionOnRow: function(action, row){},
performActionOnCell: function(action, row, col){}
};
// eigene Baumansicht setzen
document.getElementById('treeview').view = koTreeView;
}
]]>
</script>
<tree id="treeview" flex="1">
<treecols>
<treecol id="RowCol" label="Zeile" flex="1" primary="true"/>
<treecol id="DateCol" label="Uhrzeit" flex="1"/>
</treecols>
<treechildren/>
</tree>
</window>
Vergleicht man mit dem DOM-Inspektor die DOM-Darstellung der beiden Baumversionen, stellt man fest, dass selbstdefinierte Baumansichten aus OptimierungsgrĂĽnden gar nicht erst XUL-Elemente erzeugen, sondern direkt auf der Bildschirmdarstellung operieren (sie erscheinen nicht in der Quelltextansicht). Unter diesem Blickwinkel leuchtet ein, dass die Darstellung XUL-basierter trees intern nur ĂĽber eine vordefinierte Baumansicht geschieht, die diese Elemente mehr oder weniger weit auswertet.
Dies hat unter anderem zur Konsequenz, dass ĂĽbliche CSS-Style-Anpassungen mit den Inhalten eines trees nicht funktionieren - die diesbezĂĽglichen Attribute und CSS-Regeln werden schlicht nicht beachtet.
XUL mit Stil-Erweiterungen
Die Mozilla-Plattform implementiert nicht nur fast vollständig die aktuelle Version 2.1 der Cascading Stylesheets, sondern außerdem weite Teile der W3C-Entwürfe zu CSS 3; zudem existieren eine Reihe interner CSS-Erweiterungen zur besseren Ausnutzung Mozilla-spezifischer Eigenheiten. Für XUL-Elemente definieren Mozilla-basierte Anwendungen eine Standardansicht, die der Nutzer per userChrome.css übersteuern kann (siehe „Online-Ressourcen“).
CSS-Stylesheets bindet man in XUL-Dokumente durch die XML-Direktive ?xml-stylesheet type="text/css“ href="MeinStyleSheet.css“? ein, wobei die Dateireferenz wiederum ein data:-URI sein kann (siehe den Anfang von Listing 3). Soll nun der Inhalt eines tree Stilanweisungen erhalten, stehen die üblichen CSS-Selektoren für XUL-Elemente unterhalb des obersten treechildren-Elements nicht zur Verfügung. Stattdessen muss man auf spezielle CSS-Pseudoelemente zurückgreifen, die zudem nicht alle CSS-Regeln akzeptieren:
- -moz-tree-cell (eine treecell; nimmt unter anderem background-color),
- -moz-tree-cell-text (label einer treecell; nimmt unter anderem color),
- -moz-tree-row (eine treerow; nimmt unter anderem background-color),
- -moz-tree-column (eine treecol; nimmt unter anderem border),
- -moz-tree-separator (ein treeseparator; nimmt unter anderem border) und andere.
Diese Regeln lassen sich durch sogenannte properties verfeinern, entweder durch Angabe eines Attributs properties an den XUL-Elementen oder durch Implementierung der entsprechenden nsITreeView-Funktionen getRowProperties, getCellProperties oder getColumnProperties.
Werte eines solchen properties enthält eine durch Leerzeichen getrennte Liste von Namen, die auf CSS-Ebene zur Verfügung steht. Neben einigen vordefinierten Werten wie open (Ast hat ausgeklappte Kinder), selected (treerow oder treecell ist selektiert), odd/even (ungerader/gerader Zeilenindex; kann das treechildren-Attribut alternatingbackground="true" aktivieren) und anderen sind selbstdefinierte Werte zulässig; Listing 3 zeigt ein einfaches Codebeispiel.
Listing 3: TreeStyle.xul
properties, die ein XUL-Element gesetzt haben muss, bevor eine CSS-Regel greift, stehen als kommagetrennte Liste in Klammern direkt hinter der CSS-Pseudoklasse.
<?xml version="1.0"?>
<?xml-stylesheet type="text/css"
href="data:text/css,
treechildren::-moz-tree-column(primary)
{ background-color: blue; }
treechildren::-moz-tree-row(rot, gelb)
{ background-color: red; }
treechildren::-moz-tree-cell
{ background-color: yellow; }
treechildren::-moz-tree-cell-text(gelb)
{ color: green; font-size: 120%; }
"?>
<window
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="TreeStyle">
<tree flex="1">
<treecols>
<treecol id="col1" label="Spalte 1" flex="1" primary="true"/>
<treecol id="col2" label="Spalte 2" flex="1"/>
</treecols>
<treechildren alternatingbackground="true">
<treeitem container="true" open="true">
<treerow>
<treecell label="Text A1" properties="gelb"/>
<treecell label="Text A2"/>
</treerow>
<treechildren>
<treeitem container="true" open="true">
<treerow properties="gelb rot">
<treecell label="Text B1"/>
<treecell label="Text B2" properties="gelb"/>
</treerow>
</treeitem>
</treechildren>
</treeitem>
</treechildren>
</tree>
</window>
RDF-Datenquelle fĂĽr XUL-Anwendungen
Die dritte Möglichkeit, ein tree-Element mit Daten zu versorgen, besteht in der Angabe einer RDF-Datenquelle, aus der Generierungsvorlagen (templates) die eigentlichen XUL-Elemente automatisch erzeugen. Der template-Mechanismus ist prinzipiell mit allen XUL-Elementen nutzbar, aber nur sinnvoll, wenn es darum geht, viele gleichartige effizient zu verarbeiten - wie eben in trees.
Anzuzeigende Daten müssen als RDF-Datenquelle vorliegen. Dies kann eine Datei im RDF-Format sein, aber auch per Javascript erzeugte Instanzen der nsIRDFDataSource-Schnittstelle - so genannte „In-Memory-Datenquellen“ - oder interne Datenquellen der Mozilla-Plattform wie die Lesezeichen oder die Browser-Historie. Die letzten beiden bedürfen allerdings erweiterter Zugriffsrechte auf den Mozilla-Kern, „Chrome-Rechte“ genannt, diese kommen erst in Teil 3 dieses Tutorials vor.
Im einfachsten Fall haben die Daten eine völlig gleichförmige Struktur, sie liegen in der Datenquelle als Unterelemente eines RDF-Containers vor und speichern ihre Werte unter denselben Prädikaten ab (siehe Listing 4).
Listing 4: TreeRDF.rdf
Die so genannte Chrome-Registry der Mozilla-Plattform ist nichts weiter als eine RDF-Datei (chrome.rdf), die Informationen ĂĽber alle installierten XUL-Pakete speichert; hier ein Auszug.
<?xml version="1.0"?>
<RDF:RDF xmlns:c="http://www.mozilla.org/rdf/chrome#"
xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<RDF:Seq RDF:about="urn:mozilla:package:root">
<RDF:li>
<RDF:Description RDF:about="urn:mozilla:package:global"
c:baseURL="jar:resource:/chrome/toolkit.jar!/content/global/"
c:locType="install"
c:displayName="Toolkit"
c:author="mozilla.org"
c:name="global"
c:localeVersion="1.7"
c:skinVersion="1.5" />
</RDF:li>
<RDF:li>
<RDF:Description RDF:about="urn:mozilla:package:inspector"
c:hasOverlays="true"
c:baseURL="jar:resource:/chrome/inspector.jar!/content/inspector/"
c:locType="install"
c:displayName="Document Inspector"
c:author="Joe Hewitt"
c:name="inspector"
c:localeVersion="1.7"
c:skinVersion="1.5" />
</RDF:li>
<RDF:li>
<RDF:Description RDF:about="urn:mozilla:package:mozapps"
c:baseURL="jar:resource:/chrome/toolkit.jar!/content/mozapps/"
c:locType="install"
c:displayName="Mozilla Application Support"
c:author="mozilla.org"
c:name="mozapps"
c:skinVersion="1.5"
c:localeVersion="1.7" />
</RDF:li>
</RDF:Seq>
</RDF:RDF>
Das XUL-Element, dessen Kinder der template-Mechanismus erzeugen soll, bekommt ĂĽber das Attribut datasources eine leerzeichengetrennte Liste der RDF-Datenquellen ĂĽbergeben, beispielsweise datasources="TreeRDF.rdf" oder datasources="rdf:null" fĂĽr skriptgesteuerte Datenquellen.
AuĂźerdem muss das Attribut ref vorhanden sein, das den RDF-Container bezeichnet, dessen Daten zur Anzeige kommen sollen; hier beispielsweise ref="urn:mozilla:package:root". Bei trees kann man ĂĽber den Attributwert flags="dont-build-content" zudem die Generierung der XUL-Kindelemente unterdrĂĽcken, da dies nur Zeit kostet und auf die Baumdarstellung keinen Einfluss hat.
Die zu erzeugenden XUL-Elemente werden als Kinder des template-Elements notiert, das wiederum ein direktes Kind des Elements mit dem datasources-Attribut sein muss. Allerdings beginnen Auswertung und Wiederholung erst bei dem Element, das den Attributwert uri="rdf:*" gesetzt hat: Jedes Element des referenzierten RDF-Containers wird samt seiner Kinder vervielfacht und erhält automatisch den Ressourcennamen als id-Attribut. Alle anderen XUL-Kinder des template-Elements landen nur einmalig in der Ausgabe.
Um an die eigentlichen Daten der Container-Elemente zu gelangen, steht eine spezielle Syntax zur Verfügung: Alle Attributwerte der generierten Elemente, die Zeichenketten der Form „rdf:uri#element“ enthalten, versuchen diese als RDF-Prädikate im Kontext des aktuellen Container-Elements zu interpretieren und durch den entsprechenden Wert zu ersetzen. Mehrere solche RDF-Referenzen lassen sich verwenden, müssen aber durch Leerzeichen oder Zirkumflexe („^“) voneinander getrennt sein. Listing 5 erzeugt aus den Daten von Listing 4 eine Baumdarstellung.
Listing 5: TreeRDF.xul
Für gleichförmige Ausgabedaten, wie sie Listing 4 enthält, reicht die einfache template-Form.
<?xml version="1.0"?>
<window
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="TreeRDF">
<tree id="treerdf" flex="1"
datasources="TreeRDF.rdf"
ref="urn:mozilla:package:root">
<treecols>
<treecol id="Name" label="Name" primary="true" flex="1"/>
</treecols>
<template>
<treechildren flex="1">
<treeitem uri="rdf:*">
<treerow>
<treecell label="rdf:http://www.mozilla.org/rdf/chrome#name"/>
</treerow>
</treeitem>
</treechildren>
</template>
</tree>
</window>
Listing 6: TreeRDFext.xul
Realisierung der in Listing 5 definierten Ausgabe durch eine Regel in der erweiterten Syntax.
<?xml version="1.0"?>
<window
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="TreeRDFext"
xmlns:c="http://www.mozilla.org/rdf/chrome#"
xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<tree id="treerdfext" flex="1"
datasources="TreeRDF.rdf"
ref="urn:mozilla:package:root">
<treecols>
<treecol id="Name" label="Name" primary="true" flex="1"/>
</treecols>
<template>
<rule>
<conditions>
<content uri="?uri"/>
<member container="?uri" child="?paket"/>
<triple subject="?paket"
predicate="http://www.mozilla.org/rdf/chrome#name"
object="?name"/>
</conditions>
<action>
<treechildren flex="1">
<treeitem uri="?paket">
<treerow>
<treecell label="?name"/>
</treerow>
</treeitem>
</treechildren>
</action>
</rule>
</template>
</tree>
</window>
Will man nicht unbedingt alle Elemente des RDF-Containers gleichermaßen ausgeben, reicht die oben vorgestellte Syntax nicht mehr aus. Auf der ersten Eskalationsstufe steht hier die einfache Variante des rule-Elements, das (falls notwendig, mehrfach) als Kind des template notiert wird und als Attribute RDF-Prädikat/Objekt-Paare erhält, die ein Container-Element erfüllen muss, um ausgegeben zu werden. (Die Prädikate property, instanceOf, id und parsetype sind jedoch reserviert und deshalb nicht verwendbar.)
UmschlieĂźt man das treechildren-Element in Listing 5 mit der Regel <rule c:author="mozilla.org"> ... </rule> (bei entsprechender Definition von xmlns:c="http://www.mozilla.org/rdf/chrome#" im Window-Element), werden nur noch die mozilla.org-Pakete ausgegeben. Vom syntaktischen Standpunkt entspricht Listing 5 einer rule ohne solche Attributbedingung.
Sind mehrere solcher einfachen rules angegeben, muss jede ein Element mit uri="rdf:*" definieren. Nur bis zur ersten passenden Regel wird getestet.
In dieser einfachen Fassung kennt das rule-Element noch die folgenden Attribute:
- type (testet den Typ des Container-Elements auf einen aus dem RDF-Namensraum),
- iscontainer (ist das Container-Element selbst ein solcher?),
- isempty (ist das Container-Element leer?) und
- parsetype (bei parsetype="Integer" werden die RDF-Objektwerte als Zahl ausgewertet).
Bei komplexen Anfragen führt diese einfache Syntax leider nicht zum Ziel, weswegen eine erweiterte Regelverallgemeinerung existiert, die den Gebrauch von Variablen erlaubt. In der erweiterten Syntax hat das rule-Element keine Attribute, aber drei optionale Kindelemente: conditions (Bedingungen, die diese Regel definieren), bindings (optionale, zusätzliche Variablendefinitionen) und action (welche Elemente in der Ausgabe erzeugt werden sollen).
Das conditions-Element kann wiederum ebenfalls drei Unterelemente aufnehmen. content dient im Wesentlichen mit seinem uri-Attribut zur Definition einer Variablen fĂĽr die aktuelle Position im RDF-Dickicht: content uri="?uri" definiert die Variable ?uri und weist ihr als Wert den durch das ref-Attribut des template-Elternknotens definierten RDF-Node zu. content muss das erste Kindelement sein und darf maximal einmal pro rule existieren.
Von den Elementen triple und member muss nur eins definiert sein. Jedes triple definiert eine Kante im RDF-Graph, es kennt die Attribute subject, predicate und object mit der in RDF üblichen Bedeutung. Die Attributwerte von subject und object können Variablen sein, bisher undefinierte initialisiert der Template-Mechanismus auf den entsprechenden Wert aus dem RDF-Graphen.
member ist eine Spezialfassung eines triple, es kennt lediglich die Attribute container und child und dient fĂĽr Kanten von RDF-Containern zu ihren enthaltenen Kindern. Eine rule erfasst nur Container-Elemente, die fĂĽr alle Angaben im conditions-Block gĂĽltige Werte liefern.
Mit dem binding-Element lassen sich weitere Variablen definieren, die Existenz einer entsprechenden Kante des RDF-Graphen ist aber keine Voraussetzung fĂĽr die Anwendung dieser rule. Die enthaltenen binding-Elemente haben exakt dieselbe Syntax wie triple.
Damit eine rule einen Sinn erfüllt, bedarf sie eines action-Elements, das die zu erzeugenden Ausgabeelemente enthält. Der uri-Wert des zu replizierenden XUL-Elements wird dabei in der Regel auf die Variable gesetzt, die ein Element des RDF-Containers referenziert. Alle definierten Variablen können auch als Ausgabewerte in den Attributwerten der action-Kindelemente dienen.
Im abschließenden dritten Teil dieses Tutorials ist das Tal der Theorie fast durchschritten, wenn potenzielle XULer endlich dem Extensionsbasteln freien Lauf lassen können.
Karsten DĂĽsterloh
ist Diplom-Mathematiker und Entwickler bei tal.de sowie Autor der Mozilla-Erweiterung Mnenhy.
| Weitere XUL-Elemente | |
| Nicht alle XUL-Elemente können in diesem Tutorial besprochen werden, es sind ihrer schlicht zu viele. Für diese sei auf die XUL-Referenzen im Kasten „Online-Ressourcen“ verwiesen. Ausgelassen wurden unter anderem: | |
| checkbox, radio | Auswahl einer Option aus mehreren (aber wenigen) |
| colorpicker | Spezialdialog zur Auswahl von Farben |
| deck | mehrere XUL-Seiten ĂĽbereinander, von denen nur eine sichtbar ist |
| dialog, page | spezielle Window-Elemente fĂĽr Dialoge und Einstellungsseiten |
| grid | eine Matrix mit Zeilen und Spalten, in denen wiederum XUL-Elemente liegen dĂĽrfen |
| groupbox | zieht einen Rahmen um die enthalten Elemente, die so optisch gruppiert werden |
| iframe, browser, editor | zeigen Dokumente innerhalb des aktuellen an |
| image | fĂĽgt Bilder in das XUL-Dokument ein |
| listbox | vereinfachtes tree-Element |
| menulist | so genannte „Dropdownbox“, die eine Auswahl über eine ausklappbare Liste anbietet |
| progressmeter | Fortschrittsbalken |
| separator, spacer | optische Trennelemente: Linie und Leerraum |
| splitter | Trennelement zwischen XUL-Boxen, das deren Größenänderung per Maus erlaubt |
| stack | mehrere XUL-Seiten ĂĽbereinander, die alle gleichzeitig sichtbar sind |
| statusbar | Statuszeile |
| tabbrowser | enthält mehrere über Karteireiter zugängliche XUL-Seiten |
| wizard | Eingabedialog mit mehreren Seiten |
iX-TRACT
- Mozilla-Anwendungen wie Firefox oder Thunderbird lassen sich durch XUL, die XML User Interface Language, erweitern.
- Elemente wie tree sowie die darunter angesiedelten treecols und treechildren et cetera erlauben die baumartige Darstellung von Daten, die in RDF vorliegen oder von einem Skript erzeugt werden können.
- Welche Daten der Browser anzeigt, kann man ĂĽber Regeln definieren.
Tutorialinhalt
- Teil I: Grundlegende Elemente wie window, button, menu und Attribute wie label et cetera.
- Teil II: Fortgeschrittene XUL-Elemente wie tree sowie Techniken wie Templates.
- Teil III: Mit XUL und Javascript Anwendungen wie Mozilla und Firefox um eigene Funktionen erweitern.
(hb)