Envoyé par : syl
Date : 09/08/2006 13:03
Bonjour,
Je recherche une fonction me retournant la liste de l'intégralité des balises xul d'un document XUL à partir d'un noeud donné. J'ai bien essayer de faire un parcours récursif de mon document via le DOM, mais j'ai quand même des difficultés. Je souhaiterais aussi appliquer un filtre sur cette liste pour ne récupérer que les noeuds qui ont tel ou tel attribut ou nom...
Quelqu'un a surement du déja faire un truc dans le genre... ?
Si vous avez une solution
Merci
Envoyé par : thefab
Date : 09/08/2006 14:57
TreeWalker permet de faire ça, y compris filter.
Envoyé par : syl
Date : 09/08/2006 16:22
Merci, je m'en vais de ce pas essayer de décortiquer cela.
Envoyé par : papy
Date : 10/08/2006 10:03
Bonjour,
je suis très intéressé par les TreeWalker mais je n'ai pas encore eu le temps de me pencher la dessus. Serait-il possible de poster un petit exemple qui en montre rapidement le fonctionnement ?
Cela pourrait également être intéressant de faire un petit article la dessus dans le Wiki.
Envoyé par : syl
Date : 11/08/2006 12:07
Voilà, j'ai du nouveau concernant le parcours du DOM. J'ai réussi à utiliser un treeWalker et ça marche bien. Par contre je n'ai pas compris comment implémenter la fonction de filtrage intégrée (NodeFilter). Voici mon code qui parcourt itérativement un arbre à partir d'une racine donnée :
function aaRAZRecherche() { var nodes = Components.classes["@mozilla.org/xul/xul-document;1"].createInstance(); if (nodes) { nodes.QueryInterface(Components.interfaces.nsIDOMDocumentTraversal); var tw = nodes.createTreeWalker(document.getElementById("aaModRecherche").firstChild, NodeFilter.SHOW_ALL, null, true); function childlist(tw, children) { var currentNode = tw.currentNode; for (var child = tw.firstChild(); child != null; child = tw.nextSibling()) { alert (child.nodeName); childlist(tw, children); } tw.currentNode = currentNode ; } var children =tw.firstChild; childlist(tw, children); } }
Maintenant, je souhaite me servir de la fonction nodeFilter, je rajoute donc ma fonction personnalisée dans le script précédent :
function acceptNode(n) { if (n.localName =="hbox") { return FILTER_ACCEPT } else { return FILTER_SKIP } }
Et je modifie ma definition du TreeWalker :
var tw = nodes.createTreeWalker(document.getElementById("aaModRecherche").firstChild, NodeFilter.acceptNode(???), null, true);
Bon je ne comprend pas quoi mettre en argument à la place des ???. Je serais bien tenté par un truc du genre currentNode mais ça ne marche pas.
Est-ce que quelqu'un peut m'expliquer le fonctionnement de ce filtre et surtout les arguments à utiliser ?
Merci
Syl
Envoyé par : thefab
Date : 11/08/2006 17:59
Pour créer l'objet TreeWalker tu n'es pas obligé de caster (nsIDOMDocumentTraversal)
document.createTreeWalker()
fonctionne parfaitement.
Pour créer ton propre filtre tu dois implémenter NodeFilter, ce qui signifie que ton objet filtre doit avoir les méthode de NodeFilter, acceptNode() en l'occurence. Ton filtre as donc cette aspect:
var filtre = { acceptNode: function(n) { if (n.localName == "hbox") return FILTER_ACCEPT; return FILTER_SKIP; } };
Quand aux paramètres c'est: la racine, quels type de noeuds, le filtre et est-ce qu'il faut remplacer les entités, donc:
var elements = document.createTreeWalker(document, NodeFilter.SHOW_ELEMENT, filtre, false);
Fabrice
Envoyé par : syl
Date : 11/08/2006 18:49
Un grand merci theFab. je débute en XUL et c'est pas évident.
Ca marche bien, j'ai juste remplacé les constantes par leur valeur numérique, car sans cela j'avais une exception.
Tant que j'y suis, tu me dis que je ne suis pas obliger de "caster" (terme un peu obscurs pour moi) avec l'appel au composant "nsIDOMDocumentTraversal". Car je suppose qu'il doit déjà être appelé ?
Comment savoir si tel ou tel interface est disponible ? car moi j'aurais plutot tendance à tout "caster" et si c'est pas nécessaire, je m'en passerais bien !
Merci encore et puis je voulais ajouter que pour moi ce forum est un formidable outil et je pense que c'est aussi le cas pour les xuliens novices ou un peu moins
Envoyé par : thefab
Date : 12/08/2006 11:01
j'ai juste remplacé les constantes par leur valeur numérique, car sans cela j'avais une exception
Ah ben oui j'ai effacer quelque chose, oups désolé: dans le filtre il faut remplacer FILTER_ACCEPT et FILTER_SKIP par NodeFilter.FILTER_ACCEPT et NodeFilter.FILTER_SKIP respectivement, sinon c'est sur exception...
"caster" (terme un peu obscurs pour moi)
Caster veut dire en gros "convertir en". Un objet pouvant implémenter plusieurs interfaces, caster permet de convertir un objet vers un autre type (nsIDOMDocumentTraversal par exemple), mais c'est juste ce que tu as fait: la plupart du temps il faut caster.
Comment savoir si tel ou tel interface est disponible ?
Sur la page Outils il y a CView qui permet ça.
Envoyé par : papy
Date : 15/08/2006 15:41
Une petite question en retard : est ce que c'est beaucoup plus efficace d'utiliser un TreeWalker plutot que de recreer soit même ses propres fonctions qui parcours le DOM ? Si les TreeWalker sont implémentés en natif je serais tenté de répondre oui mais je n'ai pas trouvé beaucoup de documentation sur le sujet.
Et une petite dernière pour la route au cas ou il y ai des spécialistes dans la salle, est-il possible de choisir le mode de parcours (en profondeur / en largeur) ?
Envoyé par : syl
Date : 15/08/2006 16:58
Bon je suis pas spécialiste, mais tu peux utiliser un NodeIterator, qui te permet de parcourir ton document sans tenir compte de l'arborescence, il te renvois simplement une liste de noeud que tu parcours à l'aide d'un "nextNode". Est-ce plus efficace je ne sais pas ?
Pour le sens largeur/longueur, modifier la fonction de parcours (childlist()) ne me semble pas trop difficile...
Envoyé par : papy
Date : 15/08/2006 17:08
Merci pour le NodeIterator, et désolé pour la question sur le parcours, je n'avais pas prêter attention à cette fonction dans ton code, ou en tout cas pas assez ;)
Envoyé par : syl
Date : 15/08/2006 18:11
De rien Papy. Cette fonction semble plus adapté à mes besoins et tu peux apparament la parcourir avec une simple boucle while sur nextNode();
Par contre, je ne sais pas si tu as reussi à te servir de NodeIterator Parce que moi, l'appel à cette interface me provoque une Exception alors que ca fonctionne tres bien avec Treewalker et ce sont 2 fonctions tres proche !!?? . Je travaille dans le chrome sous FireFox 1.5.0.4 L'exception est du type (NOT_IMPLEMENTED). Si quelqu'un à une explication ça m'arrangerait bien.
Merci
Envoyé par : papy
Date : 15/08/2006 21:41
Ca correspond bien à ce que j'ai pu lire sur le net (dans la ref de http://developer.mozilla.org si je me rapelle bien) : il n'existe pas d'implementation de NodeIterator actuellement. En tout cas ca correspondrait bien à ton exception NOT_IMPLEMENTED
Envoyé par : thefab
Date : 16/08/2006 07:30
Effectivement NodeIterator n'est pas implémenté pour l'instant, d'ailleurs intérroger l'implémentation DOM:
document.implementation.hasFeature("Traversal", "2.0")
Retourne faux. La différence entre TreeWalker et NodeIterator c'est que TreeWalker garde la structure hiérarchique des noeuds alors que NodeIterator offre une vue à plat.
parcourir avec une simple boucle while sur nextNode();
C'est possible aussi avec TreeWalker:
var elements = document.createTreeWalker(...); while (elements.nextNode()) { // Faire quelque chose avec elements.currentNode; }
Fabrice
Envoyé par : syl
Date : 16/08/2006 09:36
Merci pour les eclaircissements.
C'est dommage que nodeIterator ne soit pas implémenté car la structure arborescente de treeWalker implique une limitation :
Si l'élément X correspond au filtre du treewalker alors que son ancetre ne correspond pas, on ne peut récupérer cet élément X avec un simple WHile sur nextNode , mais c'est pas bien génant. Pour ma part, j'ai enlevé le nodeFilter du treeWalker et je réalise un filtrage dans la boucle while au niveau du traitement de currentNode.
Bon, je profite de ce message pour un souci de template décrit dans le forum "Template et RDF" - Template fonctionnant partiellement si quelqu'un avait une idée... :)
Et j'en profite encore pour faire une petite proposition que je décris aussi dans le forum "Divers, vos projets, le site, les outils" Je suis sur la région lyonnaise et il me semblerait intéressant de se regrouper occasionnellement, entre XUliens, de manière informelle autour d'une table, bière, ou repas pour parler XUL... si des personnes sont intéressées.. http://xulfr.org/forums/list.php?2
Merci
Il n'est plus possible de poster des messages dans ce forum.
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.