Greasemonkey est une extension Ă Mozilla Firefox qui permet de dĂ©finir des Javascript personnels qui ne sont appliquĂ©s quâĂ certains sites. Cela permet de les personnaliser Ă nos besoins.
Jâai donc eu lâidĂ©e dâutiliser et tester ce plugin pour faciliter lâutilisation dâun site que je consulte rĂ©guliĂšrement, Ă savoir LinuxFR. En effet, les commentaires des articles sont prĂ©sentĂ©s sous forme dâune arborescence. Si la premiĂšre branche dâun commentaire est assez facile Ă suivre, il est plus ardu de rattacher les commentaires suivants Ă celui auquel ils rĂ©pondent.
Nom de code : PAPA
Je vais donc essayer de construire un script pour Greasemonkey qui va me permettre Ă partir de nâimporte quel commentaire de retrouver facilement celui auquel il se rattache. Son pĂšre. Ce projet sâappellera donc provisoirement PAPA en attendant dâavoir plus dâinspiration.
Références
Pour commencer, voici quelques url qui peuvent ĂȘtre utiles pour faire des user scripts avec Greasemonkey :
– « Writing User Scripts », explication rapide sur la crĂ©ation de scripts Greasemonkey,
– « Gecko DOM Reference »
– Une liste de User scripts alimentĂ©e par un wiki,
– Le site UserScripts qui veut proposer un outil plus poussĂ© pour catĂ©goriser les diffĂ©rents scripts.
– Une prĂ©sentation en français sur le site du Journal du net dans la section dĂ©veloppeurs.
Ă noter : Les utilisateurs dâInternet Explorer peuvent aussi utiliser les user scripts Ă lâaide de lâextension turnabout. La version 8 du navigateur Opera semble aussi pourvoir supporter les scripts utilisateurs.
à noter encore : Utiliser GreaseMonkey peut causer quelques soucis avec les pages utilisant déjà du javascript, voir ce témoignage [1].
Principes
Une fois la page dâun article de LinuxFR chargĂ©e, le script va sâĂ©xĂ©cuter. Il va ainsi parcourir lâarbre DOM de cette page et modifier le bloc contenant le titre de chaque commentaire en ajoutant un lien “Masquer“. Ceci ne sera fait que pour les commentaires qui ne sont pas le premier fils dâun commentaire de niveau supĂ©rieur [2]. Quand on cliquera sur ce lien, tous les commentaires prĂ©cĂ©dents de mĂȘme niveau seront masquĂ©s. On pourra donc facilement accĂ©der au commentaire pĂšre pour suivre le fil de discussion.
Donc en images, voici ce que cela donne. On lit le fil dâun commentaire et on arrive au bout dâune branche. Le commentaire suivant est donc une rĂ©ponse Ă un texte qui apparait bien plus haut dans lâarborescence. Il nâest pas toujours facile Ă retrouver, surtout dans un arbre Ă trolls.
En cliquant sur le lien Masquer que lâon apercoit en bas de la page je vais me retrouver positionnĂ© sur le commentaire pĂšre – pour ainsi savoir sur quoi porte la rĂ©ponse suivante – et les Ă©lĂ©ments intermĂ©diaires seront masquĂ©s, comme ceci :
En cliquant sur Afficher on revient Ă la normal.
Installation du user script PAPA
Si vous voulez lâutiliser, il suffit dâinstaller lâextension Greasemonkey, de redĂ©marrer Mozilla Firefox [3] et de “cliquer droit” sur ce lien. Dans le menu contextuelle qui apparait, il faut choisir « Install User Script ».
Le code du script
Ci-dessous le code du script que jâai rĂ©alisĂ©.
// ==UserScript== // @name LinuxFR papa // @namespace /papa // @description [en] : This user script adds action links to each comment in comments tree // of Linuxfr.org website in order to improve navigability. With this // script you are able to find easily the parent of a comment and // hide (or display) a part of this tree. // // [fr] : Ce "user script" ajoute des liens actifs Ă chaque commentaire dans // l'arbre des commentaires du site Linuxfr.org dans le but d'amĂ©liorer l'expĂ©rience // de navigation. Avec ce script vous ĂȘtes capable de trouver facilement le pĂšre d'un // commentaire et de cacher (ou d'afficher) une partie de cet arbre. // @include http://linuxfr.org/* // @exclude http://linuxfr.org/my/ // ==/UserScript== // Notes: // version 0.4 - 02/12/2005 - correction suite a modification dans le code html de LinuxFR : Le script ne // s'exĂ©cutait plus. Apparement il y a eu des changements dans les pages, et le // onload ne s'exĂ©cutait pas, donc le script ne pouvait pas se dĂ©rouler. J'ai donc // supprimer l'attachement du script Ă onload. // version 0.3 - 17/08/2005 - ajout licence GPL // - modification de la description // - ajout d'une traduction en anglais // // version 0.2 - 05/06/2005 - quand on clique sur "Masquer" on est positionnĂ© sur le commentaire parent // - un seul lien "Masquer" ou "Afficher" est visible. En fonction de ce qui est // possible pour un commentaire, soit l'un soit l'autre est visible. // // version 0.1 - 04/06/2005 - premiere version. // // auteur : Bruno ARLIGUY // // licence : GPL license - http://www.gnu.org/copyleft/gpl.html (function() { //Listener positionnĂ© sur chaque lien "Masquer" quand on le "clique". // On va masquer le lien "Masquer", afficher le lien "Afficher" et ensuite // parcourir tous les commentaires prĂ©cĂ©dents (ie previousSibling) et les masquer // // param e : l'Ă©vĂšnement reçu par l'objet auquel est associĂ© ce listener function hideSibling(e) { //masquer le lien "masquer" e.target.style.display = 'none'; //afficher le lien "afficher" e.target.nextSibling.style.display = 'block'; //masquer les commentaires prĂ©cĂ©dents var currentComment = e.target.parentNode.parentNode.parentNode.parentNode; if (currentComment) { for (var sibling = currentComment.previousSibling; sibling.nodeName == 'UL'; sibling = sibling.previousSibling) { sibling.style.display = 'none'; } } } //Listener positionnĂ© sur chaque lien "Afficher" quand on le "clique". // On va masquer le lien "Afficher", afficher le lien "Masquer" et ensuite // parcourir tous les commentaires prĂ©cĂ©dents (ie previousSibling) et les afficher // // Attention : ceci va re-afficher tous les commentaires prĂ©cĂ©dents de mĂȘme niveau, // mĂȘme si ils n'ont pas Ă©tĂ© cachĂ©s en activant le lien "cacher" correspondant au lien // "afficher" actuellement actif. Il faut donc repositionner les liens "Afficher" et "Masquer" // de ces commentaires, car certains pourraient ĂȘtre innapropriĂ©s. // // param e : l'Ă©vĂšnement reçu par l'objet auquel est associĂ© ce listener function showSibling(e) { //masquer le lien "afficher" e.target.style.display = 'none'; //afficher le lien "masquer" e.target.previousSibling.style.display = 'block'; //afficher les commentaires prĂ©cĂ©dents var currentComment = e.target.parentNode.parentNode.parentNode.parentNode; var papaBlock = null; if (currentComment) { for (var sibling = currentComment.previousSibling; sibling.nodeName == 'UL'; sibling = sibling.previousSibling) { sibling.style.display = 'block'; papaBlock = document.evaluate("./li/h1/div", sibling, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; if (papaBlock != null) { papaBlock.childNodes[0].style.display = 'block'; papaBlock.childNodes[1].style.display = 'none'; } } } } //Construit un block (div) qui contient les liens "Masquer" et "Afficher" pour l'UL passĂ© en paramĂštre. // // param ul : un objet qui doit reprĂ©senter un UL correspondant Ă // un commentaire (ie rĂ©pond au xpath //ul[@class='commentsul']) function getPapaBlock(ul) { var namedLink = ul.firstChild.childNodes[1]; var parentLink = ul.parentNode.childNodes[1]; var id = namedLink.name; var div = document.createElement("div"); var aHide = document.createElement("a"); var aShow = document.createElement("a"); // div.setAttribute("id", "pn" + namedLink.name); div.setAttribute("class", "pn"); div.setAttribute("style", "float: right;"); //Faire pointer le lien masquant sur le commentaire parent. aHide.setAttribute("href", "#" + parentLink.name); aHide.setAttribute("id", "hide" + namedLink.name); aHide.setAttribute("class", "pn"); aHide.addEventListener("click", hideSibling, false); aShow.setAttribute("href", "#" + namedLink.name); aShow.setAttribute("id", "show" + namedLink.name); aShow.setAttribute("class", "pn"); aShow.setAttribute("style", "display: none"); aShow.addEventListener("click", showSibling, false); div.appendChild(aHide); div.appendChild(aShow); aHide.appendChild(document.createTextNode("- Masquer")); aShow.appendChild(document.createTextNode("+ Afficher")); return div; } try { // RecupĂ©rer tous les UL de classe "commentsul". Pour chacun, ajouter un bloc dans sa barre de titre. // Ce bloc contiendra deux liens : "Masquer" et "Afficher". Chaque lien appellera un script // qui appliquera l'action correspondante (masquer ou afficher) sur tous les "previousSibling" du // commentaire associĂ©. Le lien en lui mĂȘme consistera Ă appeler la mĂȘme page en la positionnant sur : // - le lien nommĂ© correspondant au commentaire parent si l'utilisateur a cliquĂ© sur "Masquer" // - le lien nommĂ© correspondant au commentaire si l'utilisateur a cliquĂ© sur "Afficher". // les liens nommĂ©s sont ceux de la forme <a name="580185"></a> et qui sont les "childNodes[1]" de chaque //ul[@class='commentsul']. var elements = document.evaluate("//ul[@class='commentsul']", document, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null); var uls = new Array(); var ul = null; //tranferer les Ă©lĂ©ments trouvĂ©s dans un tableau. for (var i = 0; ul = elements.iterateNext(); i++) { uls[i] = ul; } var before = null; var previous = null; for (var i = 0; i < uls.length; i++) { previous = uls[i].previousSibling; while (previous.nodeName == "#text") { previous = previous.previousSibling; } if (previous.nodeName == "UL") { //Selectionner le premier H1 Ă partir du premier enfant de cet UL. J'utilise une expression xPath car // apparement le Html de LinuxFR a tendance Ă Ă©voluer. Donc un accĂ©s relatif comme avant (avec des numĂ©ros // d'index dans les enfants, par exemple uls[i].firstChild.childNodes[5]) rendait le code trop dĂ©pendant des // modifications du code. before = document.evaluate("./h1", uls[i].firstChild, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.firstChild; before.parentNode.insertBefore(getPapaBlock(uls[i]), before); } } } catch (ex) { GM_log(ex); } })();
[1] Ce nâest pas un avis nĂ©gatif sur lâutilisation de GreaseMonkey, juste quâil faut faire attention Ă ce que lâon fait avec [2] dĂ©solĂ©, je nâai pas rĂ©ussi Ă expliquer ceci plus simplement [3] Oui oui, il faut arrĂȘter FireFox - toutes les instances lancĂ©es sous le mĂȘme profil - et le relancer