Mais pourquoi n’y avais-je pas pensé avant ? Pourquoi ?
3615 malife
Comme tout un chacun, j’ai un (en fait, deux…) compte Facebook. Ce n’est pas que j’y raconte énormément ma vie trépidante (au contraire, je parie que beaucoup de monde m’a “muté” tellement mes posts sont chiants en général !), mais surtout pour garder le contact avec mes amis (des vrais, des plus ou moins vrais, et puis un peu de famille aussi). Je pourrais très bien m’en passer, je sais très bien ce que fait Facebook de mes données personnelles, de mes interactions avec les uns et les autres (un #PJLRenseignement avant l’heure), mais n’empêche, je trouve Facebook pratique. Et j’avoue une flemme over 9000 pour ce qui est de passer des coups de fil pour prendre des nouvelles.
Le problème, c’est qu’à chaque fois que je vais sur la version web, j’ai droit à quantité de pubs plus ou moins bien ciblées : des milliers femmes célibataires en rut en bas de chez moi ? Tss, ça sent tellement l’attrape-couillon que je prends ça pour une insulte. Tant pis si c’est vrai, ça me gonfle, et me gonfler est une des pires idées qui soient.
Il y a quelques semaines, quand je me suis attelé à SponsoKilla, je me suis dit que ma prochaine victime serait Facebook. Et puis de l’eau a coulé sous les ponts, parfois par dessus même, le temps a passé, j’ai aussi un métier accessoirement, et… bon ok, assez de prétexte, j’avais la flemme de me pencher sur le sujet.
Ce n’est qu’après avoir mis le point final à ma série à succès sur WMI et PHP que cette histoire de pubs Facebook est revenue au premier plan. Pour être précis, c’était même dans le RER il y a quelques dizaines de minutes.
A peine arrivé, j’ai lancé Firefox, et suis allé sur Facebook, voir comment je pourrais m’y prendre. Et là, j’ai ris, mais j’ai ris, tellement c’était simple. Deux lignes. Oui, deux (2) lignes de code. Et encore, histoire de faire les choses proprement. Une seule aurait suffit, en réalité.
Extensions du domaine de la lutte
Comme vous avez peut-être remarqué sur des captures d’écrans dans d’autres articles, j’ai quelques extensions installées avec Firefox, et notamment GreaseMonkey, puisque c’est lui qui fait fonctionner SponsoKilla, NoScript (qui bloque l’exécution de JavaScript sur certaines pages et/ou domaines, bien pratique aussi), AdBlock Edge (un fork non-sponsorisé d’AdBlock Plus) et j’en passe.
Mais celle qui me sert le plus, notamment lorsque je programme pour moi ou au boulot, c’est Web Developper. C’est encore mieux qu’un couteau Suisse, c’est dire. Si vous programmez des sites ou applis Web ou juste par curiosité pour voir comment tout cela fonctionne, c’est l’extension qu’il vous faut.
Parmi ces nombreuses fonctionnalités géniales, celle qui me sert le plus est probablement Examiner l’élément. C’est simple, vous faites un clic droit sur l’endroit de la page qui vous intéresse (ça peut être du texte, une image, un formulaire, un div, n’importe quoi) et bim, Web Developper ouvre un panneau en pointant vers cet élément dans le code de la page, tout en respectant la hiérarchie du DOM (Document Object Model). Et ça, c’est top, croyez-moi.
|
Toi mon gaillard, il ne te reste pas longtemps à vivre… |
Ainsi, rien qu’en faisant un clic droit sur le bloc de pubs de Facebook, et avec un chouilla de logique tout de même, je savais comment me débarrasser de celles-ci.
Identification de la victime
A la différence de Twitter, Facebook a un contenu assez peu dynamique, et surtout les programmeurs ont eu l’excellente idée d’identifier la plupart des éléments, et en particulier les divs (qui sont en gros des blocs pouvant contenir tout et n’importe quoi). Un div (c’est le nom de la balise HTML) n’est pas forcément visible, même si son contenu l’est. Il peut avoir des bordures, un fond, et plein d’autres propriétés, ou pas. Mais quoiqu’il en soit, dans le DOM, le div est le parent de objets qu’il contient (s’il en contient, ce n’est pas toujours le cas) et auquel cas, ceux-ci peuvent hériter ses propriétés (ou avoir les leurs propres).
Comme je l’indiquais, Facebook identifie ses divs, c’est-à-dire que chaque div a une propriété id et donc un nom (théoriquement) unique. Je dis théoriquement car j’ai vu des sites où des objets ont le même id, c’est qui est une très mauvaise idée (et va à l’encontre des normes du W3C soit dit en passant).
L’avantage de ces id, c’est qu’en programmation, on va pouvoir cibler un objet particulier (et là vous avez compris qu’on allait cibler un div) grâce à cet id, justement. Et le langage roi pour accéder au DOM d’une page web n’est autre que JavaScript.
Si vous avez de bons yeux, vous pouvez voir sur la capture d’écran ci-dessus que je me suis focalisé sur un div dont l’id est tout simplement “rightCol”. C’est ma victime. Maintenant que je sais qui c’est, je vais pouvoir créer un nouveau script pour GreaseMonkey (et vous aussi).
L’arme du crime
Comme vous avez installé Greasemonkey depuis mon premier article sur ce blog, vous vous doutez qu’on va cliquer sur la flèche à droite de son icône, mais cette fois-ci, dans le menu déroulant, nous allons choisir Nouveau script.
Et la première chose que fait Greasemonkey, c’est de nous poser des questions embarrassantes : qu’est-ce que je mets là-dedans ? C’est quoi un espace de nom ? Inclus quoi ?
- Nom : bon ben, facile, on va appeler ça Faceblock, donc on tape Faceblock et on passe au champ suivant.
- Espace de nom : ah, là déjà, c’est plus vicieux… En fait, cet espace de nom va simplement servir à distinguer notre Faceblock d’un éventuel autre script Greasemonkey qui s’appellerait aussi Faceblock et qui aurait été écrit par un mandchou manchot exilé en Terre Adélie. Personnellement, j’ai mis l’adresse de ce blog, vous pouvez mettre l’adresse de votre site ou de votre profil Twitter, l’idée c’est que ça reste assez unique et surtout que vous ayez plus ou moins la maîtrise de cette unicité si je puis dire. Evitez de mettre votre adresse complète, email et téléphone inclus, ou votre numéro de CB, toutefois.
- Description : ben on va dire ce que fait notre Faceblock, donc notamment qu’il supprime les pubs ciblées de Facebook, tiens.
- Inclus (un par ligne) : et bien ici, on va indiquer à Greasemonkey sur quel(s) site(s) – à raison d’un par ligne – Faceblock doit être activé. J’ai donc mis https://www.facebook.com/. Vous pouvez très bien utiliser des jokers (le * notamment) pour être plus ou moins précis. Par exemple, si je mets https://*.facebook.com/*, Faceblock sera activé sur tous les sous-domaines de Facebook, quelque soit l’adresse après le .com.
- Exclus : le principe est le même que pour Inclus, cela indique à Greasemonkey sur quels sites/pages Faceblock ne doit PAS être activé (ici on ne met rien, puisque Faceblock cible spécifiquement Facebook).
Une fois que vous aurez cliqué sur OK, vous obtiendrez une fenêtre avec ça dedans :
// ==UserScript==
// @name Faceblock
// @namespace https://dedelateur.blogspot.com
// @description Vire les pubs ciblées de Facebook
// @include https://www.facebook.com/
// @version 1
// @grant none
// ==/UserScript==
Oui bon ce n’est pas très folichon à première vue, ce sont que des commentaires, et on retrouve en gros ce qu’on vient d’entrer dans le formulaire. Et puis des machins avec des @ devant, c’est quoi ça encore ?
Il s’agit d’un bloc de métadonnées qui va servir à indiquer deux-trois choses à Greasemonkey, comme le nom de votre script, la description, l’espace de nom, la version etc. Les trucs avec des @ devant sont appelés des clés.
Si vous regardez le code source de SponsoKilla, vous verrez le même bloc, avec quelques clés supplémentaires, que j’ai rajouté en l’écrivant. Je n’en parlerai pas dans cet article, car il faudrait entrer dans des détails du fonctionnement de Greasemonkey dans lesquels je risquerai de vous perdre. Vous êtes libre de modifier ce bloc, si Greasemonkey ne reconnaît pas une clé que vous aurez inventé, c’est simple, il l’ignorera.
Le problème des métadonnées, c’est que ça ne fait rien d’autre que de décrire quelque chose. Il manque le code qui va faire quelque chose, lui.
Et comme je l’ai annoncé dans le titre, il tient en deux lignes (les accolades, ça ne compte pas), que voici :
if(document.getElementById("rightCol"))
{
document.getElementById("rightCol").style.display="none";
}
Et oui, c’est tout. C’est le code source COMPLET de Faceblock. Vous collez ça à la suite du bloc de métadonnées, vous enregistrez le tout, vous allez sur Facebook et hop, plus de pub.
Comme je le disais, on aurait très bien pu mettre tout sur une ligne, mais pour des raisons de clarté et de pédagogie, c’est un peu plus pratique d’avoir séparé tout ça.
Autopsie
En pseudo-code, voici la traduction : Si l’élément dont l’id est “rightCol” existe dans le document, alors modifie la propriété display de cet élément pour qu’il ne soit plus affiché.
Décortiquons tout ça : le if veut dire si, bon ça c’est pas compliqué, on va donc tester une condition, jusque là, ça vaaaaa…
Vient document.getElementById(“rightCol”). On sait que notre élément (le fameux div qui correspond à la colonne de droite où se trouvent les pubs) s’appelle “rightCol”, puisqu’on l’a vu grâce à Web Developper. La méthode getElementById va permettre de fouiller le DOM et de trouver ce fameux “rightCol”. Et on applique la méthode à quoi ? Au document. Autrement dit, à la page web affichée par le navigateur.
Donc en gros, notre première ligne peut en réalité se traduire par “si tu trouves rightCol dans le document”. La réponse est très simple : soit c’est oui (et aura en retour le booléen True, vrai), soit c’est non (et auquel la réponse est False, faux). Or dans notre exemple, on ne s’embête même de savoir si c’est true ou false, car après le if (si) il y a un then (alors) implicite : “si tu trouves… alors”. Et de même, le else (sinon) est implicite. Tellement qu’on ne le précise même pas : si tu ne trouves pas rightCol, tu ne fais rien. Fin de l’histoire.
En réalité, la méthode getElementById retourne en interne (dans la tête de JavaScript si j’ose dire) une sorte de numéro d’objet, celui de rightCol en l’occurence. C’est bien pratique car ce numéro d’objet vous nous servir à la ligne suivante :
document.getElementById("rightCol").style.display="none";
On aurait très bien pu stocker ce numéro d’objet dans une variable, et s’en resservir, ce qui nous aurait donné un truc du genre :
var rightcol=document.getElementById("rightcol");
if(rightcol)
{
rightcol.style.display="none";
}
Mais bon, vu que qu’elle ne sert que deux fois et que le script s’arrête juste après, pourquoi faire compliqué…
Comme vous le savez, un objet a des propriétés, et même des sous-propriétés (ouhla j’entends hurler au loin). Je vulgarise à mort. Ici, on va jouer sur la propriété style de rightCol, et plus précisément sur la sous-propriété display (de style, pas directement de rightCol, sinon on aurait écrit document.getElementById(“rightCol”).display=”none” or ce n’est pas le cas et ce pour une excellente raison : rightCol n’a PAS de propriété display).
Cette propriété est spéciale, car elle ne peut prendre que quelques valeurs bien définies. Je ne vais pas citer toute la liste, les trois valeurs les plus fréquentes sont “block”, “none” ou encore “inline”. Je vais simplifier encore plus (amis puristes, détournez le regard) en disant qu’en gros, “block” et “inline” affichent un élément, et “none” ne l’affiche plus (il ne le détruit pas, l’objet est TOUJOURS dans le DOM, ce qui permet de le réafficher si besoin).
Version longue (et vaguement procédurale) de cette ligne de code : farfouille le document à la recherche de l’objet dont l’id est “rightCol” puis modifie la propriété display à none. Et au passage tu en profites pour avertir le moteur de rendu du navigateur pour qu’il n’affiche plus ce “rightCol” à l’écran et donc qu’il rafraîchisse tout ça. Ah et tu mettras le DOM à jour, tu seras chou. Merci, bisous.
Version courte (et vaguement orientée objet) : n’affiche plus “rightCol”.
Enterrement
C’est tout de même rigolo ces histoires de propriétés et de valeurs, notamment “block”, “inline” et même “none”… Comme une impression de déjà vu… Hmm… Bon sang mais c’est bien sûr : dans une feuille de style CSS !
Et oui jeune padawan, tout est lié en informatique. Le DOM, JavaScript, CSS, HTML… Mais nous verrons ça une prochaine fois ! En attendant, profitez-en pour améliorer Faceblock : plutôt que de ne plus afficher toute la colonne, pourquoi ne pas se contenter de retirer les pubs, en laissant par exemple les blocs d’invitations, de suggestions de groupes, ce genre de choses ? Pour ça, bonne chasse aux divs avec Web Developper !