Pour développer en XUL, je me suis créer un répertoire de travail sur mon disque, et j'ai configuré une entrée chrome pour celui-ci comme indiqué dans la procédure décrite sur ce site. Pour appeler une application XUL, je devais alors saisir son nom en entier dans la barre d'adresse, comme par exemple chrome://test/content/essai1.xul. À moins de conserver ce lien en Marque-page, il me fallait le retaper à chaque fois et puis j'ai travaillé sur d'autres fichiers ensuite.
L'idée est donc de créer une simple application XUL permettant d'afficher la liste de tous les fichiers XUL du répertoire chrome en question (et qui correspond au répertoire de travail). Ce fichier doit porter le même nom que celui utilisé dans le fichier manifest pour l'enregistrement chrome (ici test), ce qui permet de l'ouvrir simplement par chrome://test/content (le navigateur complète alors par chrome://test/content/test.xul).
L'objectif est donc le suivant :
<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet href="[[chrome://global/skin/]]" type="text/css"?>
<window xmlns="[[http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul]]"
[[xmlns:html="http://www.w3.org/1999/xhtml]]"
onload = "peupler();"
>
<script>
<![CDATA[
var HTML_NS = "[[http://www.w3.org/1999/xhtml"]];
function decodeNSURI(uri) {
/* Cette fonction étend la convertion de la fonction javascript decodeURI */
uri = decodeURI(uri);
uri = uri.replace(/(%[0-9A-F][0-9A-F])/g,
function($0, $1) { return String.fromCharCode(eval('0x'+$1.substring(1))); });
return uri;
}
function basename(uri) {
uri = uri.substring(0, uri.lastIndexOf('/')+1);
return uri;
}
function peupler() {
var html_lst = document.getElementById('liste');
/* Récupération de l'adresse du présent document */
var ios = Components.classes["@mozilla.org/network/io-service;1"].
getService(Components.interfaces.nsIIOService);
var ch_ec = ios.newURI(document.location.href, null, null);
/* Convertion de son adresse chrome en adresse file:// */
var chs = Components.classes["@mozilla.org/chrome/chrome-registry;1"].
getService(Components.interfaces.nsIChromeRegistry)
var ch = chs.convertChromeURL(ch_ec);
/* Découpage et décodage du répertoire de travail */
var bn = decodeNSURI(basename(ch.path));
//bn peut avoir par exemple une forme "/home/.../test xul@user/"
var base_chrome = basename(document.location.href);
/* Accès au répertoire du système de fichiers */
var dir = Components.classes["@mozilla.org/file/local;1"].
createInstance(Components.interfaces.nsILocalFile);
dir.initWithPath( bn );
/* Lecture des fichiers du répertoire de travail */
var dlst = dir.directoryEntries;
while(dlst.hasMoreElements()) {
var file = dlst.getNext().QueryInterface(Components.interfaces.nsIFile);
if (file.isFile() && file.leafName.substring(file.leafName.lastIndexOf('.'))=='.xul') {
/* Création de la liste html */
var html_li = document.createElementNS(HTML_NS, 'li');
var html_a = document.createElementNS(HTML_NS, 'a');
html_a.href = base_chrome + file.leafName;
html_a.innerHTML = file.leafName;
html_li.appendChild(html_a);
html_lst.appendChild(html_li);
}
}
/***/
}
]]>
</script>
<[[html:p>Liste]] des fichiers du répertoire de développement :</[[html:p]]>
<[[html:hr]] />
<[[html:ul]] id="liste" />
</window>
Ce code peut être copié intégralement et utilisé. Il doit être placé dans votre répertoire de travail et dans un fichier xul portant le même nom que le nom de votre enregistrement content défini dans votre fichier manifest.
L'astuce de ce code est la convertion d'une adresse chrome://test/content/ en file:/<chemin>. La méthode de conversion convertChromeURL() renvoit un chemin dont les caractères sont tous échappés, y compris certains caractères spéciaux tel que @ (en %40). Or, il faudra faire une conversion inverse avant d'utiliser la méthode initWithPath()//, grâce à la fonction decodeNSURI().
Pour lire tous les fichiers d'un répertoire local, il faut utiliser la propriété directoryEntries d'un objet nsILocalFile correctement initialisé. Cette propriété ne retourne pas un tableau contenant la liste des fichiers d'un répertoire, mais un objet "énumératif". Les méthodes hasMoreElements() et getNext() permettent respectivement de vérifier la présence d'autres éléments de la liste enumérative et de passer à l'élément suivant de la liste. S'agissant d'un objet énumératif, son type n'est pas connu, et il doit être instancié par l'appel de QueryInterface(Components.interfaces.nsIFile) sur l'objet retourné par la fonction getNext() ; l'objet ainsi obtenu sera de type nsIFile avec toutes les propriétés et méthodes associées.
Le test final sert à vérifier qu'il s'agit bien d'un fichier portant la bonne extension xul, et à créer construire la liste html correspondante (l'utilisation du html ici importe peu).
Ce code est bien entendu simple pour ne pas surcharger l'article. Par exemple, si la liste des fichiers est trop importante, la fenêtre XUL ne l'affichera pas en entier.
Copyright © 2003-2013 association xulfr, 2013-2016 Laurent Jouanneau - Informations légales.
Mozilla® est une marque déposée de la fondation Mozilla.
Mozilla.org™, Firefox™, Thunderbird™, Mozilla Suite™ et XUL™
sont des marques de la fondation Mozilla.