{"id":21,"date":"2005-05-29T22:29:12","date_gmt":"2005-05-29T21:29:12","guid":{"rendered":"https:\/\/arliguy.net\/2005\/05\/29\/greasemonkey-et-chaque-site-devient-mien\/"},"modified":"2008-02-20T22:49:02","modified_gmt":"2008-02-20T21:49:02","slug":"greasemonkey-et-chaque-site-devient-mien","status":"publish","type":"post","link":"https:\/\/arliguy.net\/2005\/05\/29\/greasemonkey-et-chaque-site-devient-mien\/","title":{"rendered":"Greasemonkey et chaque site devient mien"},"content":{"rendered":"

Greasemonkey<\/a> est une extension \u00e0 Mozilla Firefox<\/a> qui permet de d\u00e9finir des Javascript<\/a> personnels qui ne sont appliqu\u00e9s qu\u2019\u00e0 certains sites. Cela permet de les personnaliser \u00e0 nos besoins.
\nJ\u2019ai donc eu l\u2019id\u00e9e d\u2019utiliser et tester ce plugin pour faciliter l\u2019utilisation d\u2019un site que je consulte r\u00e9guli\u00e8rement, \u00e0 savoir
LinuxFR<\/a>. En effet, les commentaires des articles sont pr\u00e9sent\u00e9s sous forme d\u2019une arborescence. Si la premi\u00e8re branche d\u2019un commentaire est assez facile \u00e0 suivre, il est plus ardu de rattacher les commentaires suivants \u00e0 celui auquel ils r\u00e9pondent.<\/p>\n

Nom de code : PAPA<\/h2>\n

Je vais donc essayer de construire un script pour Greasemonkey<\/a> qui va me permettre \u00e0 partir de n\u2019importe quel commentaire de retrouver facilement celui auquel il se rattache. Son p\u00e8re. Ce projet s\u2019appellera donc provisoirement PAPA en attendant d\u2019avoir plus d\u2019inspiration.<\/p>\n

R\u00e9f\u00e9rences<\/h2>\n

Pour commencer, voici quelques url qui peuvent \u00eatre utiles pour faire des user scripts avec Greasemonkey :
\n–\u00a0 \u00ab
Writing User Scripts<\/a> \u00bb, explication rapide sur la cr\u00e9ation de scripts Greasemonkey,
\n–\u00a0 \u00ab
Gecko DOM Reference<\/a> \u00bb
\n–\u00a0
Une liste de User scripts<\/em><\/a> aliment\u00e9e par un wiki,
\n–\u00a0 Le site
UserScripts<\/a> qui veut proposer un outil plus pouss\u00e9 pour cat\u00e9goriser les diff\u00e9rents scripts.
\n–\u00a0
Une pr\u00e9sentation en fran\u00e7ais<\/a> sur le site du Journal du net dans la section d\u00e9veloppeurs.
\n\u00c0 noter :<\/u> Les utilisateurs d\u2019Internet Explorer peuvent aussi utiliser les user scripts \u00e0 l\u2019aide de l\u2019extension
turnabout<\/a>. La version 8 du navigateur Opera<\/a> semble aussi pourvoir supporter les scripts utilisateurs<\/a>.
\n\u00c0 noter encore :<\/em> Utiliser GreaseMonkey peut causer quelques soucis avec les pages utilisant d\u00e9j\u00e0 du javascript,
voir ce t\u00e9moignage <\/a>[1].<\/p>\n

Principes<\/h2>\n

Une fois la page d\u2019un article de LinuxFR<\/a> charg\u00e9e, le script va s\u2019\u00e9x\u00e9cuter. Il va ainsi parcourir l\u2019arbre DOM de cette page et modifier le bloc contenant le titre de chaque commentaire en ajoutant un lien “Masquer<\/em>“. Ceci ne sera fait que pour les commentaires qui ne sont pas le premier fils d\u2019un commentaire de niveau sup\u00e9rieur [2]. Quand on cliquera sur ce lien, tous les commentaires pr\u00e9c\u00e9dents de m\u00eame niveau seront masqu\u00e9s. On pourra donc facilement acc\u00e9der au commentaire p\u00e8re pour suivre le fil de discussion.
\nDonc en images, voici ce que cela donne. On lit le fil d\u2019un commentaire et on arrive au bout d\u2019une branche. Le commentaire suivant est donc une r\u00e9ponse \u00e0 un texte qui apparait bien plus haut dans l\u2019arborescence. Il n\u2019est pas toujours facile \u00e0 retrouver, surtout dans un arbre \u00e0 trolls.<\/p>\n

\"Avant<\/a><\/p>\n

En cliquant sur le lien Masquer<\/em> que l\u2019on apercoit en bas de la page je vais me retrouver positionn\u00e9 sur le commentaire p\u00e8re – pour ainsi savoir sur quoi porte la r\u00e9ponse suivante – et les \u00e9l\u00e9ments interm\u00e9diaires seront masqu\u00e9s, comme ceci :<\/p>\n

\"Apr\u00e9s<\/a><\/p>\n

En cliquant sur Afficher<\/em> on revient \u00e0 la normal.<\/p>\n

Installation du user script PAPA<\/h2>\n

Si vous voulez l\u2019utiliser, il suffit d\u2019installer l\u2019extension Greasemonkey<\/a>, de red\u00e9marrer<\/strong> Mozilla Firefox <\/a>[3] et de “cliquer droit” sur ce lien<\/a>. Dans le menu contextuelle qui apparait, il faut choisir \u00ab Install User Script<\/em> \u00bb.<\/p>\n

\"Menu<\/a><\/p>\n

Le code du script<\/h2>\n

Ci-dessous le code du script que j\u2019ai r\u00e9alis\u00e9.<\/p>\n

\/\/ ==UserScript==\r\n\/\/ @name          LinuxFR papa\r\n\/\/ @namespace     https:\/\/arliguy.net\/papa\r\n\/\/ @description          [en] : This user script adds action links to each comment in comments tree\r\n\/\/                of Linuxfr.org website in order to improve navigability. With this\r\n\/\/                script you are able to find easily the parent of a comment and\r\n\/\/                hide (or display) a part of this tree.\r\n\/\/\r\n\/\/                [fr] : Ce \"user script\" ajoute des liens actifs \u00e0 chaque commentaire dans\r\n\/\/                l'arbre des commentaires du site Linuxfr.org dans le but d'am\u00e9liorer l'exp\u00e9rience\r\n\/\/                de navigation. Avec ce script vous \u00eates capable de trouver facilement le p\u00e8re d'un\r\n\/\/                commentaire et de cacher (ou d'afficher) une partie de cet arbre.\r\n\/\/ @include       http:\/\/linuxfr.org\/*\r\n\/\/ @exclude       http:\/\/linuxfr.org\/my\/\r\n\/\/ ==\/UserScript==\r\n\/\/ Notes:\r\n\/\/   version 0.4 - 02\/12\/2005 - correction suite a modification dans le code html de LinuxFR : Le script ne\r\n\/\/                              s'ex\u00e9cutait plus. Apparement il y a eu des changements dans les pages, et le\r\n\/\/                              onload ne s'ex\u00e9cutait pas, donc le script ne pouvait pas se d\u00e9rouler. J'ai donc\r\n\/\/                              supprimer l'attachement du script \u00e0 onload.\r\n\/\/   version 0.3 - 17\/08\/2005 - ajout licence GPL\r\n\/\/                            - modification de la description\r\n\/\/                            - ajout d'une traduction en anglais\r\n\/\/\r\n\/\/   version 0.2 - 05\/06\/2005 - quand on clique sur \"Masquer\" on est positionn\u00e9 sur le commentaire parent\r\n\/\/                            - un seul lien \"Masquer\" ou \"Afficher\" est visible. En fonction de ce qui est\r\n\/\/                              possible pour un commentaire, soit l'un soit l'autre est visible.\r\n\/\/\r\n\/\/   version 0.1 - 04\/06\/2005 - premiere version.\r\n\/\/\r\n\/\/   auteur  : Bruno ARLIGUY\r\n\/\/\r\n\/\/   licence : GPL license - http:\/\/www.gnu.org\/copyleft\/gpl.html\r\n\r\n(function()\r\n{\r\n        \/\/Listener positionn\u00e9 sur chaque lien \"Masquer\" quand on le \"clique\".\r\n        \/\/ On va masquer le lien \"Masquer\", afficher le lien \"Afficher\" et ensuite\r\n        \/\/ parcourir tous les commentaires pr\u00e9c\u00e9dents (ie previousSibling) et les masquer\r\n        \/\/\r\n        \/\/ param e : l'\u00e9v\u00e8nement re\u00e7u par l'objet auquel est associ\u00e9 ce listener\r\n        function hideSibling(e)\r\n        {\r\n                \/\/masquer le lien \"masquer\"\r\n                e.target.style.display = 'none';\r\n                \/\/afficher le lien \"afficher\"\r\n                e.target.nextSibling.style.display = 'block';\r\n                \/\/masquer les commentaires pr\u00e9c\u00e9dents\r\n                var currentComment = e.target.parentNode.parentNode.parentNode.parentNode;\r\n                if (currentComment)\r\n                {\r\n                        for (var sibling = currentComment.previousSibling; sibling.nodeName == 'UL'; sibling = sibling.previousSibling)\r\n                        {\r\n                                sibling.style.display = 'none';\r\n                        }\r\n                }\r\n        }\r\n\r\n        \/\/Listener positionn\u00e9 sur chaque lien \"Afficher\" quand on le \"clique\".\r\n        \/\/ On va masquer le lien \"Afficher\", afficher le lien \"Masquer\" et ensuite\r\n        \/\/ parcourir tous les commentaires pr\u00e9c\u00e9dents (ie previousSibling) et les afficher\r\n        \/\/\r\n        \/\/ Attention : ceci va re-afficher tous les commentaires pr\u00e9c\u00e9dents de m\u00eame niveau,\r\n        \/\/ m\u00eame si ils n'ont pas \u00e9t\u00e9 cach\u00e9s en activant le lien \"cacher\" correspondant au lien\r\n        \/\/ \"afficher\" actuellement actif. Il faut donc repositionner les liens \"Afficher\" et \"Masquer\"\r\n        \/\/ de ces commentaires, car certains pourraient \u00eatre innapropri\u00e9s.\r\n        \/\/\r\n        \/\/ param e : l'\u00e9v\u00e8nement re\u00e7u par l'objet auquel est associ\u00e9 ce listener\r\n        function showSibling(e)\r\n        {\r\n                \/\/masquer le lien \"afficher\"\r\n                e.target.style.display = 'none';\r\n                \/\/afficher le lien \"masquer\"\r\n                e.target.previousSibling.style.display = 'block';\r\n                \/\/afficher les commentaires pr\u00e9c\u00e9dents\r\n                var currentComment = e.target.parentNode.parentNode.parentNode.parentNode;\r\n                var papaBlock      = null;\r\n                if (currentComment)\r\n                {\r\n                        for (var sibling = currentComment.previousSibling; sibling.nodeName == 'UL'; sibling = sibling.previousSibling)\r\n                        {\r\n                                sibling.style.display = 'block';\r\n                                papaBlock = document.evaluate(\".\/li\/h1\/div\", sibling, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;\r\n                                if (papaBlock != null)\r\n                                {\r\n                                        papaBlock.childNodes[0].style.display = 'block';\r\n                                        papaBlock.childNodes[1].style.display = 'none';\r\n                                }\r\n                        }\r\n                }\r\n        }\r\n\r\n        \/\/Construit un block (div) qui contient les liens \"Masquer\" et \"Afficher\" pour l'UL pass\u00e9 en param\u00e8tre.\r\n        \/\/\r\n        \/\/ param ul : un objet qui doit repr\u00e9senter un UL correspondant \u00e0\r\n        \/\/            un commentaire (ie r\u00e9pond au xpath \/\/ul[@class='commentsul'])\r\n        function getPapaBlock(ul)\r\n        {\r\n                var namedLink  = ul.firstChild.childNodes[1];\r\n                var parentLink = ul.parentNode.childNodes[1];\r\n                var id         = namedLink.name;\r\n                var div        = document.createElement(\"div\");\r\n                var aHide      = document.createElement(\"a\");\r\n                var aShow      = document.createElement(\"a\");\r\n\r\n                \/\/\r\n                div.setAttribute(\"id\", \"pn\" + namedLink.name);\r\n                div.setAttribute(\"class\", \"pn\");\r\n                div.setAttribute(\"style\", \"float: right;\");\r\n\r\n                \/\/Faire pointer le lien masquant sur le commentaire parent.\r\n                aHide.setAttribute(\"href\", \"#\" + parentLink.name);\r\n                aHide.setAttribute(\"id\", \"hide\" + namedLink.name);\r\n                aHide.setAttribute(\"class\", \"pn\");\r\n                aHide.addEventListener(\"click\", hideSibling, false);\r\n\r\n                aShow.setAttribute(\"href\", \"#\" + namedLink.name);\r\n                aShow.setAttribute(\"id\", \"show\" + namedLink.name);\r\n                aShow.setAttribute(\"class\", \"pn\");\r\n                aShow.setAttribute(\"style\", \"display: none\");\r\n                aShow.addEventListener(\"click\", showSibling, false);\r\n\r\n                div.appendChild(aHide);\r\n                div.appendChild(aShow);\r\n\r\n                aHide.appendChild(document.createTextNode(\"- Masquer\"));\r\n                aShow.appendChild(document.createTextNode(\"+ Afficher\"));\r\n\r\n                return div;\r\n        }\r\n\r\n                try\r\n                {\r\n                        \/\/ Recup\u00e9rer tous les UL de classe \"commentsul\". Pour chacun, ajouter un bloc dans sa barre de titre.\r\n                        \/\/ Ce bloc contiendra deux liens : \"Masquer\" et \"Afficher\". Chaque lien appellera un script\r\n                        \/\/ qui appliquera l'action correspondante (masquer ou afficher) sur tous les \"previousSibling\" du\r\n                        \/\/ commentaire associ\u00e9. Le lien en lui m\u00eame consistera \u00e0 appeler la m\u00eame page en la positionnant sur :\r\n                        \/\/    - le lien nomm\u00e9 correspondant au commentaire parent si l'utilisateur a cliqu\u00e9 sur \"Masquer\"\r\n                        \/\/    - le lien nomm\u00e9 correspondant au commentaire si l'utilisateur a cliqu\u00e9 sur \"Afficher\".\r\n                        \/\/ les liens nomm\u00e9s sont ceux de la forme <a name=\"580185\"><\/a> et qui sont les \"childNodes[1]\" de chaque \/\/ul[@class='commentsul'].\r\n                        var elements = document.evaluate(\"\/\/ul[@class='commentsul']\", document, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);\r\n                        var uls = new Array();\r\n                        var ul  = null;\r\n                        \/\/tranferer les \u00e9l\u00e9ments trouv\u00e9s dans un tableau.\r\n                        for (var i = 0; ul = elements.iterateNext(); i++)\r\n                        {\r\n                                uls[i] = ul;\r\n                        }\r\n\r\n                        var before = null;\r\n                        var previous = null;\r\n                        for (var i = 0; i < uls.length; i++)\r\n                        {\r\n                                previous = uls[i].previousSibling;\r\n                                while (previous.nodeName == \"#text\")\r\n                                {\r\n                                        previous = previous.previousSibling;\r\n                                }\r\n\r\n                                if (previous.nodeName == \"UL\")\r\n                                {\r\n                                        \/\/Selectionner le premier H1 \u00e0 partir du premier enfant de cet UL. J'utilise une expression xPath car\r\n                                        \/\/ apparement le Html de LinuxFR a tendance \u00e0 \u00e9voluer. Donc un acc\u00e9s relatif comme avant (avec des num\u00e9ros\r\n                                        \/\/ d'index dans les enfants, par exemple uls[i].firstChild.childNodes[5]) rendait le code trop d\u00e9pendant des\r\n                                        \/\/ modifications du code.\r\n                                        before = document.evaluate(\".\/h1\", uls[i].firstChild, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.firstChild;\r\n                                        before.parentNode.insertBefore(getPapaBlock(uls[i]), before);\r\n                                }\r\n                        }\r\n                }\r\n                catch (ex)\r\n                {\r\n                        GM_log(ex);\r\n                }\r\n})();<\/pre>\n
[1] Ce n\u2019est pas un avis n\u00e9gatif sur l\u2019utilisation de GreaseMonkey, juste qu\u2019il faut faire attention \u00e0 ce que l\u2019on fait avec\r\n[2] d\u00e9sol\u00e9, je n\u2019ai pas r\u00e9ussi \u00e0 expliquer ceci plus simplement\r\n[3] Oui oui, il faut arr\u00eater FireFox - toutes les instances lanc\u00e9es sous le m\u00eame profil - et le relancer<\/pre>\n","protected":false},"excerpt":{"rendered":"

Greasemonkey est une extension \u00e0 Mozilla Firefox qui permet de d\u00e9finir des Javascript personnels qui ne sont appliqu\u00e9s qu\u2019\u00e0 certains sites. Cela permet de les personnaliser \u00e0 nos besoins. J\u2019ai donc eu l\u2019id\u00e9e d\u2019utiliser et tester ce plugin pour faciliter l\u2019utilisation d\u2019un site que je consulte r\u00e9guli\u00e8rement, \u00e0 savoir LinuxFR. En effet, les commentaires des … Continuer la lecture de Greasemonkey et chaque site devient mien<\/span> →<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[13],"tags":[24,25],"_links":{"self":[{"href":"https:\/\/arliguy.net\/wp-json\/wp\/v2\/posts\/21"}],"collection":[{"href":"https:\/\/arliguy.net\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/arliguy.net\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/arliguy.net\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/arliguy.net\/wp-json\/wp\/v2\/comments?post=21"}],"version-history":[{"count":0,"href":"https:\/\/arliguy.net\/wp-json\/wp\/v2\/posts\/21\/revisions"}],"wp:attachment":[{"href":"https:\/\/arliguy.net\/wp-json\/wp\/v2\/media?parent=21"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/arliguy.net\/wp-json\/wp\/v2\/categories?post=21"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/arliguy.net\/wp-json\/wp\/v2\/tags?post=21"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}