<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gaël Poupard</title>
    <description>The latest articles on DEV Community by Gaël Poupard (@ffoodd).</description>
    <link>https://dev.to/ffoodd</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1646198%2F288a3ef4-0256-42d6-a70e-2448fc6bd4c6.jpeg</url>
      <title>DEV Community: Gaël Poupard</title>
      <link>https://dev.to/ffoodd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ffoodd"/>
    <language>en</language>
    <item>
      <title>Les astuces derrière « l’Invasion du HTML mutant »</title>
      <dc:creator>Gaël Poupard</dc:creator>
      <pubDate>Tue, 03 Dec 2024 09:00:00 +0000</pubDate>
      <link>https://dev.to/onepoint/les-astuces-derriere-linvasion-du-html-mutant--1j8</link>
      <guid>https://dev.to/onepoint/les-astuces-derriere-linvasion-du-html-mutant--1j8</guid>
      <description>&lt;p&gt;Le 17 octobre dernier, j’animais au devFest Nantes un atelier intitulé « L’Invasion du HTML mutant ».&lt;/p&gt;

&lt;p&gt;Un atelier devant par définition impliquer les participants, j’ai fait le choix de créer un mini-jeu en guise de support. C’est &lt;a href="https://www.ffoodd.fr/devfest.2024/jeu/" rel="noopener noreferrer"&gt;un site statique disponible en ligne&lt;/a&gt;, &lt;a href="https://github.com/ffoodd/html-mutant" rel="noopener noreferrer"&gt;open-sourcé sur GitHub&lt;/a&gt; — pour que vous puissiez l’améliorer !&lt;/p&gt;

&lt;p&gt;Quand je dis statique, c’est statique : le dépôt a une unique dépendance, &lt;a href="https://github.com/lukejacksonn/servor" rel="noopener noreferrer"&gt;servor&lt;/a&gt;, chargée de fournir un serveur HTTP basique pour travailler en local  et servor n’a elle-même aucune dépendance. Le reste n’est que HTML, CSS et JavaScript.&lt;/p&gt;

&lt;p&gt;Ça m’a permis de revenir aux fondamentaux, considérablement gagner en efficience ; mais surtout… découvrir tout un tas de trucs et astuces !&lt;/p&gt;

&lt;h2&gt;
  
  
  La mécanique du jeu
&lt;/h2&gt;

&lt;p&gt;En démarrant le jeu, vous commencerez par personnaliser votre personnage. Le seul objectif de cette étape est de découvrir la structure visuelle d’un niveau, en vous permettant de vous impliquer personnellement dans le jeu. Les valeurs choisies seront appliquées dès que possible à tous les personnages du jeu, dans une sorte de représentation en miroir.&lt;/p&gt;

&lt;p&gt;Après avoir choisi votre personnage, un niveau d’entraînement vous familiarise avec la mécanique très simple du jeu : une portion de code à compléter et soumettre, exécutée en direct, qui affecte la zone envahie progressivement par des mutants ! Ce code est dans la plupart des niveaux les options passées à un &lt;code&gt;mutationObserver&lt;/code&gt;, mais parfois aussi dans la fonction de rappel.&lt;/p&gt;

&lt;p&gt;En cas d’échec comme en cas de réussite, une fenêtre modale vous informera. Parlons-en, de cette fenêtre modale !&lt;/p&gt;

&lt;h2&gt;
  
  
  Les particularités de &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;J’en parlais &lt;a href="https://www.paris-web.fr/2022/conferences/decouvrez-le-bon-html-et-economisez-du-js-et-du-css.php" rel="noopener noreferrer"&gt;en 2022 à Paris Web&lt;/a&gt; puis &lt;a href="https://devfest2022.gdgnantes.com/sessions/decouvrez_le_bon_html_et_economisez_du_js_et_du_css" rel="noopener noreferrer"&gt;au devFest Nantes&lt;/a&gt; dans mon sujet « &lt;a href="https://www.ffoodd.fr/devfest/#slide-1" rel="noopener noreferrer"&gt;Découvrez " le bon HTML " et économisez du JS et du CSS &lt;/a&gt;», &lt;a href="https://developer.mozilla.org/fr/docs/Web/HTML/Element/dialog" rel="noopener noreferrer"&gt;l’élément &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt;&lt;/a&gt; est extrêmement intéressant et devrait à terme supplanter toutes les implémentations de fenêtres modales dans les différentes bibliothèques de composants.&lt;/p&gt;

&lt;p&gt;Dans l’atelier, je m’en sers en plusieurs endroits :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;pour afficher les règles du jeu dans l’écran d’accueil ;&lt;/li&gt;
&lt;li&gt;pour interrompre un niveau, quand le nombre de mutants dépasse la centaine ;&lt;/li&gt;
&lt;li&gt;pour informer d’un échec lors d’une soumission de code qui ne fonctionne pas ;&lt;/li&gt;
&lt;li&gt;pour informer de la réussite, dans le cas contraire — et permettre de passer au niveau suivant.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Ouvrir la fenêtre
&lt;/h3&gt;

&lt;p&gt;La plupart sont ouvertes programmatiquement, en réaction à un événement. Rien de plus simple : il suffit de récupérer une référence à l’élément &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt; à l’aide de &lt;code&gt;querySelector()&lt;/code&gt; ou une référence à un identifiant via l’accès aux propriétés nommées, ou &lt;a href="https://html.spec.whatwg.org/multipage/nav-history-apis.html#named-access-on-the-window-object:html-elements-2" rel="noopener noreferrer"&gt;named properties access (en anglais)&lt;/a&gt;, et d’invoquer &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement/showModal" rel="noopener noreferrer"&gt;la méthode &lt;code&gt;showModal()&lt;/code&gt; (sur MDN, en anglais)&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dialog&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;showModal&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Sans JavaScript externe
&lt;/h4&gt;

&lt;p&gt;Une exception toutefois, pour éviter d’ajouter un écouteur d’événement inutile : la fenêtre des règles du jeu est invoquée grâce à un gestionnaire d’événement HTML &lt;code&gt;onclick&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt; &lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;"rules.showModal()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Règles du jeu&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dialog&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"rules"&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"dialog"&lt;/span&gt; &lt;span class="na"&gt;aria-label=&lt;/span&gt;&lt;span class="s"&gt;"Règles du jeu"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/dialog&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Aparté : la projection des identifiants HTML en objets globaux
&lt;/h5&gt;

&lt;p&gt;Dans cet exemple, j’invoque l’ouverture de la fenêtre modale avec &lt;code&gt;rules.showModal()&lt;/code&gt;, sans avoir défini la variable &lt;code&gt;rules&lt;/code&gt;. Comment est-ce possible ? En résumé, tout élément porteur d’un attribut &lt;code&gt;id&lt;/code&gt; devient mécaniquement une propriété globale de l’objet &lt;code&gt;window&lt;/code&gt;, et devient donc accessible directement par son nom. C’est spécifié sous le joli nom de &lt;a href="https://html.spec.whatwg.org/multipage/nav-history-apis.html#named-access-on-the-window-object" rel="noopener noreferrer"&gt;Named Access on Window Object (en anglais)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;C’est drôlement pratique, non ? Figurez-vous que c’est aussi un vecteur d’attaque méconnu faisant partie d’un groupe sobrement intitulé &lt;a href="https://domclob.xyz/" rel="noopener noreferrer"&gt;DOM clobbering (en anglais)&lt;/a&gt;. Je vous encourage à parcourir &lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/DOM_Clobbering_Prevention_Cheat_Sheet.html" rel="noopener noreferrer"&gt;les recommandations de l’OWASP pour mitiger le DOM clobbering (en anglais)&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Accessibilité
&lt;/h4&gt;

&lt;p&gt;La méthode &lt;code&gt;showModal()&lt;/code&gt; permet d’ouvrir une fenêtre modale, pas une simple boîte de dialogue — en respectant les exigences en matière d’accessibilité : la focus est mécaniquement piégé dedans, la fermeture est possible avec la touche Échap, etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  L’arrière-plan
&lt;/h3&gt;

&lt;p&gt;Une fois la fenêtre modale ouverte, on peut s’appliquer à la styler. Là où moult bibliothèques de composants imposent une &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; (voire plusieurs) pour servir d’arrière-plan à la fenêtre, la version native est livrée avec &lt;a href="https://developer.mozilla.org/fr/docs/Web/CSS/::backdrop" rel="noopener noreferrer"&gt;un pseudo-élément &lt;code&gt;::backdrop&lt;/code&gt;&lt;/a&gt; qui s’étend naturellement sur tout le viewport et est promue, avec la fenêtre modale, par-dessus le reste de la page dans ce qui est spécifié sous le nom de top layer.&lt;/p&gt;

&lt;p&gt;Vous n’avez plus qu’à lui appliquer une couleur, une opacité ou que sais-je encore. Dans le jeu, j’ai utilisé une propriété au nom évocateur de &lt;a href="https://developer.mozilla.org/fr/docs/Web/CSS/backdrop-filter" rel="noopener noreferrer"&gt;&lt;code&gt;backdrop-filter&lt;/code&gt;&lt;/a&gt; pour appliquer un effet de flou grisé sur l’arrière-plan.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;dialog&lt;/span&gt;&lt;span class="nd"&gt;::backdrop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;backdrop-filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grayscale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;blur&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;.25rem&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Les dimensions
&lt;/h3&gt;

&lt;p&gt;Ne maîtrisant pas le mode de consultation du jeu, j’ai utilisé un peu de CSS moderne pour la largeur de la fenêtre modale afin qu’elle ait une largeur fluide, mais avec des valeurs minimum et maximum.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;dialog&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;max-inline-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;clamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;50vw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;67.5rem&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La propriété  &lt;code&gt;max-inline-size&lt;/code&gt; est la &lt;a href="https://developer.mozilla.org/fr/docs/Web/CSS/CSS_logical_properties_and_values" rel="noopener noreferrer"&gt;propriété logique&lt;/a&gt; correspondant à &lt;code&gt;max-width&lt;/code&gt; dans le cas du Français. Et &lt;a href="https://developer.mozilla.org/fr/docs/Web/CSS/clamp" rel="noopener noreferrer"&gt;la fonction &lt;code&gt;clamp()&lt;/code&gt;&lt;/a&gt; est un petit bijou, dont j’abuse déjà copieusement dans &lt;a href="https://ffoodd.github.io/chaarts/pie-charts.html" rel="noopener noreferrer"&gt;chaarts (en anglais)&lt;/a&gt; pour obtenir un pseudo-booléen en CSS en fonction d’une valeur, comme expliqué &lt;a href="https://www.ffoodd.fr/devquest/#slide-27" rel="noopener noreferrer"&gt;slide 27 de ma conférence « Dessine-moi un graphique (en CSS) »&lt;/a&gt; donnée au &lt;a href="https://devfest2023.gdgnantes.com/sessions/dessine_moi_un_graphique__en_css_/" rel="noopener noreferrer"&gt;devFest Nantes 2023&lt;/a&gt;, &lt;a href="https://2024.touraine.tech/talk/ioc2x2nW4KV5zrt69ZQm" rel="noopener noreferrer"&gt;TNT #24&lt;/a&gt; et &lt;a href="https://www.devquest.fr/sessions/dessine-moi-un-graphique-en-CSS" rel="noopener noreferrer"&gt;DevQuest 2024&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fermer la fenêtre
&lt;/h3&gt;

&lt;p&gt;J’ai évoqué la capacité de fermer la modale avec la touche Échap, mais l’élément &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt; tire d’autres super-pouvoirs du fait d’être natif, et notamment son association avec un élément &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt;. C’est parfaitement naturel, puisqu’une fenêtre modale permet généralement de valider ou annuler une action associée à une saisie.&lt;/p&gt;

&lt;p&gt;C’est pourquoi la valeur &lt;a href="https://developer.mozilla.org/fr/docs/Web/HTML/Element/form#method" rel="noopener noreferrer"&gt;&lt;code&gt;dialog&lt;/code&gt; est ajoutée à la &lt;code&gt;method&lt;/code&gt;&lt;/a&gt; de soumission d’un formulaire. Elle ne correspond pas à une méthode HTTP comme &lt;code&gt;get&lt;/code&gt; ou &lt;code&gt;post&lt;/code&gt;, mais bien à un contexte HTML, et permet de fermer directement la fenêtre modale parente. L’utilisation est fort simple :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"fermer"&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"dialog"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Et, pour revenir à du HTML à l’ancienne : saviez-vous qu’un bouton à l’autre bout du DOM peut soumettre un formulaire ? Il suffit de lui indiquer le formulaire à soumettre :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;form=&lt;/span&gt;&lt;span class="s"&gt;"fermer"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Fermer la fenêtre&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Et voilà : c’est un bouton de type &lt;code&gt;submit&lt;/code&gt; qui soumettra le formulaire avec l’identifiant &lt;code&gt;fermer&lt;/code&gt;, qui lui-même fermera la fenêtre de dialogue. C’est beau, non ? Et &lt;a href="https://www.w3.org/TR/2006/WD-web-forms-2-20060821/#formAttribute" rel="noopener noreferrer"&gt;cet attribut date (au moins) de 2006, dans les spécifications W3C des Web Forms (en anglais)&lt;/a&gt; dont les premiers brouillons remontent à 2004..&lt;/p&gt;

&lt;h2&gt;
  
  
  Les émojis
&lt;/h2&gt;

&lt;p&gt;Pour cet atelier, j’avais besoin de méchants envahisseurs, et de décors. Clairement pas le temps de faire des illustrations à la main, ni les moyens d’acheter des visuels. Une quête sur les internets m’a appris que le type de visuels que je cherchais se nomme les top down tileset, ces petits décors et personnages généralement en 8-bit avec une perspective écrasée.&lt;/p&gt;

&lt;p&gt;À force de regarder des visuels en 8-bit, j’ai fini par faire le lien avec une vieille habitude dans mes supports de conférences : les émojis décoratifs en fin de titre. Bon sang, mais c’est bien sûr ! Des émojis !&lt;/p&gt;

&lt;p&gt;Les émojis sont formidables. Ce sont des points Unicode, purement textuels, et extrêmement nombreux désormais avec des pelletées de nouveautés dans chaque version d’Unicode. Il y a même des variantes, composées en séquence !&lt;/p&gt;

&lt;h3&gt;
  
  
  Les personnages
&lt;/h3&gt;

&lt;p&gt;Le meilleur exemple de séquence Unicode à mon avis sont les personnages : le neutre Personne 🧑 peut devenir un homme 👨 ou une femme 👩 en y ajoutant le point unicode du genre masculin ♂️ ou féminin ♀️, séparé par une jointure de largeur zéro (zero-width joiner, &lt;code&gt;‍&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Pour obtenir un pompier 👨‍🚒, on ajoute simplement un camion de pompier 🚒 à une personne 🧑 ! N’est-ce pas génial, franchement ? Et on peut évidemment y ajouter le genre et le teint.&lt;/p&gt;

&lt;h3&gt;
  
  
  La personnalisation
&lt;/h3&gt;

&lt;p&gt;Ainsi &lt;a href="https://www.ffoodd.fr/devfest.2024/jeu/0-0/index.html" rel="noopener noreferrer"&gt;le premier palier permet de personnaliser le genre et le teint du héros&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Le formulaire n’est composé que de deux groupes de bouton radio, chacun ayant une valeur correspondant au point Unicode concerné.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;fieldset&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;legend&amp;gt;&lt;/span&gt;Genre&lt;span class="nt"&gt;&amp;lt;/legend&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"radio"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"genre"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"feminin"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"♀️"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"feminin"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Féminin&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"radio"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"genre"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"masculin"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"♂️"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"masculin"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Masculin&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"radio"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"genre"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"neutre"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;checked&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"neutre"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Neutre&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/fieldset&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lors de la soumission, les deux valeurs sélectionnées sont poussées dans le &lt;code&gt;localStorage&lt;/code&gt; et ré-employées dès que possible dans la suite du jeu. Pour certains méchants, il suffit de concaténer le caractère du méchant avec les deux sélections : voilà comme un Mage 🧙 devient une Mage au teint sombre 🧙🏿‍♀️.&lt;/p&gt;

&lt;h3&gt;
  
  
  Les décors
&lt;/h3&gt;

&lt;p&gt;J’ai un peu lutté avec les décors, demandant même de l’aide à mon camarade Clément Étienne. Et finalement, je suis revenu aux émojis : certains ont un caractère paysager intéressant, il suffit de les agrandir un peu…&lt;/p&gt;

&lt;h3&gt;
  
  
  Les navigateurs
&lt;/h3&gt;

&lt;p&gt;Les navigateurs et systèmes d’exploitation ont leur propre livrée d’émojis, avec des supports disparates et des rendus variés. Pour palier cet écueil, j’ai opté pour une solution très simple technologiquement parlant : une typographie. Et à ce jeu-là, j’avais déjà ma préférée : &lt;a href="https://github.com/mozilla/twemoji-colr" rel="noopener noreferrer"&gt;la Twemoji-COLR par Mozilla (sur GitHub, en anglais)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Les utilisateurs de Mozilla ne verront pas grand chose de nouveau : elle est embarquée dans Firefox sous le nom de Twemoji Mozilla, ce qui permet de tenter d’utiliser la version locale en CSS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@font-face&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;font-display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;swap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;'Twemoji Mozilla'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;font-style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;normal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;400&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;'Twemoji Mozilla'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sx"&gt;url('/assets/fonts/Twemoji.woff2')&lt;/span&gt; &lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;'woff2'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Et le tour est joué : les utilisateurs de Firefox ne chargeront rien, et les autres téléchargeront une typographie pour afficher la même chose que Firefox. Choisissez mieux votre navigateur, la prochaine fois !&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs3v3djif1dd9oj0pdxg1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs3v3djif1dd9oj0pdxg1.png" title="Firefox indique bien « système » pour l’origine de la typographie." alt="Capture d’écran de l’inspecteur de Polices de Firefox, pour la Twemoji Mozilla." width="348" height="102"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  WebKit
&lt;/h4&gt;

&lt;p&gt;Comme souvent quand je prépare un sujet, je me suis heurté à quelques limites des navigateurs. En l’occurrence, WebKit, le moteur de Safari et Epiphany, a des problèmes avec les variantes de teinte de la Twemoji-COLR. J’ai pu ouvrir &lt;a href="https://bugs.webkit.org/show_bug.cgi?id=281739" rel="noopener noreferrer"&gt;un ticket sur leur Bugzilla (en anglais)&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  La coloration syntaxique sans JS
&lt;/h2&gt;

&lt;p&gt;Dans la mécanique du jeu, des portions de code sont affichées (pour faire un « code à trous ») et du code est saisi des éléments &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; et &lt;code&gt;&amp;lt;textarea&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Et pour lire et écrire du code, la coloration syntaxique est drôlement pratique et agréable ! Mais charger un script tel que &lt;a href="https://prismjs.com/" rel="noopener noreferrer"&gt;PrismJS (en anglais)&lt;/a&gt; ou &lt;a href="https://highlightjs.org/" rel="noopener noreferrer"&gt;highlight.js (en anglais)&lt;/a&gt; m’a toujours semblé démesuré pour la valeur ajoutée. Le bloc de code se retrouve charcuté dans le DOM, où des &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; avec des classes plus ou moins lisibles saucissonnent chaque portion de texte en fonction de son rôle syntaxique. C’est carrément indigeste.&lt;/p&gt;

&lt;p&gt;Mais au moment où je préparais cet atelier, Heikki Lotvonen a publié un article ahurissant : &lt;a href="https://blog.glyphdrawing.club/font-with-built-in-syntax-highlighting/" rel="noopener noreferrer"&gt;&lt;cite&gt;Font with Built-In Syntax Highlighting&lt;/cite&gt; (en anglais)&lt;/a&gt;. C’est à mon sens, une petite révolution : une typographie tirant parti des fonctionnalités OpenType et notamment la table COLR. Fini les tartines de &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt;, place à un code lisible et propre !&lt;/p&gt;

&lt;p&gt;Si les détails d’implémentation OpenType vous intéressent, je vous encourage à lire l’article. De mon côté, je me suis focalisé sur la personnalisation de la palette, rendues possibles en CSS avec &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@font-palette-values" rel="noopener noreferrer"&gt;&lt;code&gt;@font-palette-values&lt;/code&gt; (sur MDN, en anglais)&lt;/a&gt; et la propriété &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@font-palette-values/override-colors" rel="noopener noreferrer"&gt;&lt;code&gt;override-colors&lt;/code&gt; (sur MDN, en anglais)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Voilà ce que ça donne pour le jeu, dans lequel je profite de l’utilisation de propriétés personnalisées CSS pour la gestion des couleurs :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@font-palette-values&lt;/span&gt; &lt;span class="n"&gt;--syntaxHighlighter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;'FontWithASyntaxHighlighter'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;override-colors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--foreground&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="m"&gt;4&lt;/span&gt; &lt;span class="n"&gt;rebeccapurple&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--accent&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="m"&gt;7&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--muted&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Le rendu est pas mal, non ?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx8jrcutcry94naie3uux.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx8jrcutcry94naie3uux.png" alt="Bloc de code avec coloration syntaxique et champs de formulaires." width="480" height="158"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Et c’est de la pure amélioration progressive : si votre navigateur ne supporte pas la table COLR, la règle &lt;code&gt;@font-palette-values&lt;/code&gt; ou la propriété &lt;code&gt;override-colors&lt;/code&gt;, vous aurez juste du texte brut avec la monospace par défaut.&lt;/p&gt;

&lt;h2&gt;
  
  
  Les Space Invaders
&lt;/h2&gt;

&lt;p&gt;Le dernier point sur lequel je me suis beaucoup amusé, c’est le niveau des aliens. L’émoji alien monster 👾 ressemble beaucoup, beaucoup, beaucoup aux vaisseaux de Space Invaders. Pour un jeu d’invasion, ça tombe bien.&lt;/p&gt;

&lt;p&gt;J’ai donc voulu assumer la référence : arrière-plan noir, animation des envahisseurs qui défilent vers le bas, et… un compteur de score.&lt;/p&gt;

&lt;h3&gt;
  
  
  Les compteurs
&lt;/h3&gt;

&lt;p&gt;Pour ceux qui font du CSS depuis longtemps, vous avez peut-être déjà entendu parler des &lt;a href="https://developer.mozilla.org/fr/docs/Web/CSS/CSS_counter_styles/Using_CSS_counters" rel="noopener noreferrer"&gt;compteurs CSS&lt;/a&gt;. Notre score correspondra simplement au nombre d’aliens présents.&lt;/p&gt;

&lt;p&gt;Cependant, si notre compteur commence à &lt;code&gt;1&lt;/code&gt; et peut monter jusqu’à &lt;code&gt;100&lt;/code&gt; — et sachant que le jeu original disposait d’un compteur sur cinq chiffres — le rendu ne sera ni élégant ni une belle citation. Heureusement, &lt;a href="https://developer.mozilla.org/fr/docs/Web/CSS/@counter-style" rel="noopener noreferrer"&gt;CSS nous permet de personnaliser le style du compteur avec &lt;code&gt;@counter-style&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Pour obtenir un compteur sur cinq chiffres, affichant des &lt;code&gt;0&lt;/code&gt; avant la valeur du compteur, voici la déclaration utilisée :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@counter-style&lt;/span&gt; &lt;span class="n"&gt;invasion&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;system&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;numeric&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;symbols&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"0"&lt;/span&gt; &lt;span class="s1"&gt;"1"&lt;/span&gt; &lt;span class="s1"&gt;"2"&lt;/span&gt; &lt;span class="s1"&gt;"3"&lt;/span&gt; &lt;span class="s1"&gt;"4"&lt;/span&gt; &lt;span class="s1"&gt;"5"&lt;/span&gt; &lt;span class="s1"&gt;"6"&lt;/span&gt; &lt;span class="s1"&gt;"7"&lt;/span&gt; &lt;span class="s1"&gt;"8"&lt;/span&gt; &lt;span class="s1"&gt;"9"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;pad&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="s1"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;speak-as&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  WebKit (encore)
&lt;/h4&gt;

&lt;p&gt;Là aussi, WebKit est limité : les compteurs CSS ne sont pas incrémentés quand on ajoute des éléments au DOM. C’est &lt;a href="https://la-grange.net/karl/" rel="noopener noreferrer"&gt;Karl Dubost&lt;/a&gt; qui a ouvert &lt;a href="https://bugs.webkit.org/show_bug.cgi?id=281277" rel="noopener noreferrer"&gt;ce ticket sur Bugzilla (en anglais)&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Les couleurs
&lt;/h3&gt;

&lt;p&gt;Un autre point saillant pour citer visuellement Space Invaders, ce sont les couleurs vives. L’émoji utilisé vient avec une couleur qu’on ne peut pas surcharger, donc on va devoir l’altérer. Cette technique n’est pas récente, mais extrêmement utile : l’accumulation de &lt;a href="https://developer.mozilla.org/fr/docs/Web/CSS/filter" rel="noopener noreferrer"&gt;filtres CSS&lt;/a&gt; pour atteindre la bonne couleur.&lt;/p&gt;

&lt;p&gt;C’est un exercice compliqué, et je remercie Barrett Sonntag pour son &lt;a href="https://codepen.io/sosuke/pen/Pjoqqp" rel="noopener noreferrer"&gt;générateur de filtres pour convertir du noir vers un code héxadécimal (sur CodePen, en anglais)&lt;/a&gt;. La seule contrainte est de commencer par du noir ce qui se résout facilement en appliquant en premier &lt;code&gt;grayscale(100%) brightness(0%)&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;mu-tant&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"invaders"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;n&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grayscale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;brightness&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;invert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;15%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;sepia&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;90%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;saturate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5339%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;hue-rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;6deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;brightness&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;96%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;contrast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;127%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;mu-tant&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"invaders"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="nt"&gt;n&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grayscale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;brightness&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;invert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;66%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;sepia&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;82%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;saturate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;4488%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;hue-rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;88deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;brightness&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;117%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;contrast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;129%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;mu-tant&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"invaders"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;3&lt;/span&gt;&lt;span class="nt"&gt;n&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grayscale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;brightness&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;invert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;9%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;sepia&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;90%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;saturate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;7442%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;hue-rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;247deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;brightness&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;91%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;contrast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;149%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;mu-tant&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"invaders"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;4&lt;/span&gt;&lt;span class="nt"&gt;n&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grayscale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;brightness&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;invert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;91%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;sepia&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;27%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;saturate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1428%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;hue-rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;brightness&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;110%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;contrast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;104%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;C’est verbeux, mais ça fonctionne !&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgnk9abbong2i5xd7s3hj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgnk9abbong2i5xd7s3hj.png" title="Plutôt ressemblant, non ?" alt="Des lignes d’aliens aux couleurs vives sur un fond noir, et un score en haut à droite en monospace." width="480" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Les Web Components
&lt;/h2&gt;

&lt;p&gt;Et dire que je n’ai parlé que de HTML et CSS, pour le moment… Je ne m’étendrai pas autant, mais côté JavaScript, je me suis (un peu trop) amusé avec les Web Components. En résumé :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;mu-tant&amp;gt;&lt;/code&gt; est le composant qui affiche un mutant, et gère sa mutation : un changement d’attribut, de valeur d’attribut, de contenu, de descendance, etc. Le tout à intervalle irrégulier, et de façon désordonnée.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;code-runner&amp;gt;&lt;/code&gt; étend la fonctionnalité du formulaire pour normaliser les réponses et les envoyer au &lt;code&gt;&amp;lt;play-ground&amp;gt;&lt;/code&gt;. Pour le clin d’œil, l’événement qui permet de diffuser les réponses est intitulé &lt;code&gt;voightkampff&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;play-ground&amp;gt;&lt;/code&gt; est le composant le plus critique : il déclenche l’invasion, surveille l’événement &lt;code&gt;voightkampff&lt;/code&gt;, exécute le code soumis, et donne le verdict (en ouvrant la fenêtre modale appropriée).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dans tout ça, j’ai énormément joué avec les &lt;code&gt;mutationObserver&lt;/code&gt;, les intervalles et les minuteurs, les émojis, et la génération de valeurs aléatoires.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Si tout ce fatras vous rend curieux, je vous invite à visiter &lt;a href="https://github.com/ffoodd/html-mutant/tree/main" rel="noopener noreferrer"&gt;le dépôt du jeu sur GitHub&lt;/a&gt; et à en faire ce que vous voulez !&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9cmrg453f032qvl8ln59.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9cmrg453f032qvl8ln59.png" alt="Niveau 2-1 : le fantôme, dans lequel il faut configurer les options du mutationObserver pour enrayer l’invasion. Les fantômes apparaissent sur un décor nuageux, au milieu duquel émerge un pont ressemblant au Golden Gate, à San Francisco." width="480" height="276"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Et si vous vous lancez dans le jeu, je vous invite à consulter &lt;a href="https://www.ffoodd.fr/devfest.2024/#slide-1" rel="noopener noreferrer"&gt;les slides adossés au jeu&lt;/a&gt;. En avançant, vous verrez que chaque mutant a son slide. N’avancez pas trop vite, car le slide suivant donne la réponse…&lt;/p&gt;

&lt;p&gt;Faites chauffer votre inspecteur !&lt;/p&gt;




&lt;p&gt;Cet article fait partie du « Advent of Tech 2024 Onepoint », une série d’articles tech publiés par &lt;a href="https://dev.to/onepoint"&gt;Onepoint&lt;/a&gt; pour patienter jusqu’à Noël. &lt;br&gt;
Voir tous les articles du &lt;a href="https://dev.to/onepoint/advent-of-tech-2024-onepoint-le"&gt;Advent of Tech 2024&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>css</category>
      <category>a11y</category>
      <category>html</category>
      <category>adventoftech2024</category>
    </item>
    <item>
      <title>Mon épopée au devQuest</title>
      <dc:creator>Gaël Poupard</dc:creator>
      <pubDate>Wed, 19 Jun 2024 08:34:00 +0000</pubDate>
      <link>https://dev.to/onepoint/mon-epopee-au-devquest-53m7</link>
      <guid>https://dev.to/onepoint/mon-epopee-au-devquest-53m7</guid>
      <description>&lt;p&gt;&lt;strong&gt;La première édition du &lt;a href="https://www.devquest.fr/" rel="noopener noreferrer"&gt;devQuest&lt;/a&gt; avait lieu à Niort le 14 juin dernier. Et pour une première édition, c’était incroyablement réussi !&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Un nouveau joueur dans la cour des CFP, ça n’est pas si courant ! J’ai postulé par curiosité à cet événement, dont la page d’annonce était très attractive… Et j’étais retenu pour ma conférence « &lt;a href="https://www.devquest.fr/sessions/dessine-moi-un-graphique-en-CSS" rel="noopener noreferrer"&gt;Dessine-moi un graphique (en CSS)&lt;/a&gt; » !&lt;br&gt;
Accompagné de deux collègues nantaises, Céline Mérand et Charline Humeau — retenues avec leur &lt;em&gt;quickie&lt;/em&gt; « &lt;a href="https://www.devquest.fr/sessions/dedramatisons-l-accessibilite" rel="noopener noreferrer"&gt;Dédramatisons l’accessibilité&lt;/a&gt; » — nous sommes partis à l’aventure à Niort.&lt;/p&gt;

&lt;p&gt;Je vous raconte cette épopée ?&lt;/p&gt;




&lt;h2&gt;
  
  
  Le folklore du devQuest
&lt;/h2&gt;

&lt;p&gt;Le devQuest se tenait &lt;a href="https://www.vivre-a-niort.com/services-publics/les-equipements/parc-des-expositions/index.html" rel="noopener noreferrer"&gt;au Dôme du parc des expositions de Niort&lt;/a&gt;, un lieu agréable et enchanteur grâce à sa disposition circulaire. Trois salles étaient occupées :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;La forge, la plus grande salle.&lt;/li&gt;
&lt;li&gt;L’astrarium, la seconde salle de conférence — dans laquelle mes collègues et moi sommes intervenus.&lt;/li&gt;
&lt;li&gt;Et le laboratoire, qui accueillait les ateliers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vous l’aurez deviné avec le nom des salles : les organisateurs ont mis en place une ambiance festive et ludique très réussie !&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Des &lt;strong&gt;énigmes&lt;/strong&gt; à résoudre, sous forme de quiz accessibles via des QR codes disséminés sur les stands.&lt;/li&gt;
&lt;li&gt;Un &lt;strong&gt;décorum&lt;/strong&gt; léger, mais bien présent, pour donner le ton !&lt;/li&gt;
&lt;li&gt;Une musique d’&lt;strong&gt;ambiance à la taverne&lt;/strong&gt;, pour se sentir comme dans son RPG préféré.&lt;/li&gt;
&lt;li&gt;Des &lt;strong&gt;étendards&lt;/strong&gt; devQuest pour encadrer chaque scène, une coquetterie vraiment sympathique pour habiller le lieu.&lt;/li&gt;
&lt;li&gt;Des partenaires qui ont joué le jeu avec des stands ludiques et quelques &lt;em&gt;goodies&lt;/em&gt; qui sortent de l’ordinaire — et notamment un stand pour la boutique Sortilèges, avec quelques jeux proposés à l’essai !&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;J’ai également beaucoup apprécié l’ouverture de la journée, lancée par un générique digne d’un jeu vidéo et un maître du jeu pour nous présenter la guilde des organisateurs, de leurs partenaires et leur quête initiatique pour réussir cette première édition. Et les remerciements pour lancer la journée, ça met vraiment de bonne humeur !&lt;/p&gt;

&lt;h2&gt;
  
  
  Les récits de la tradition orale
&lt;/h2&gt;

&lt;p&gt;Deux &lt;em&gt;tracks&lt;/em&gt; de conférences et une d’ateliers : la journée était bien chargée et le choix parfois difficile !&lt;/p&gt;

&lt;p&gt;J’ai moi-même conté une histoire : &lt;a href="https://www.ffoodd.fr/devquest/" rel="noopener noreferrer"&gt;« Dessine-moi un graphique (en CSS) », que vous retrouverez chez moi&lt;/a&gt;. J’ai beaucoup apprécié l’aventure, et les retours sont plutôt positifs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0dcvdminxih9jzhjel7r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0dcvdminxih9jzhjel7r.png" alt="Détail des votes : Fun, 4 votes ; J’ai beaucoup appris : 21 votes ; Très intéressant : 28 votes ; Bon orateur : 19 votes ; Trop complexe : 2 votes." width="800" height="209"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;em&gt;Level up&lt;/em&gt; ta conf
&lt;/h3&gt;

&lt;p&gt;La &lt;em&gt;keynote&lt;/em&gt; d’ouverture était assurée par &lt;a href="https://jlandure.dev/" rel="noopener noreferrer"&gt;Julien Landuré&lt;/a&gt; et &lt;a href="https://www.linkedin.com/in/annabelle-koster/" rel="noopener noreferrer"&gt;Annabelle Koster&lt;/a&gt;, figures bien connues de la scène nantaise — entre autres choses pour leur implication dans le GDG de Nantes, qui organise chaque année le devFest.&lt;/p&gt;

&lt;p&gt;Les organisateurs du devQuest ont souligné dans leur introduction le soutien qu’ils ont reçu des organisateurs du devFest Nantes, et cette conférence montrait bien la valeur inestimable de l’expérience partagée : 12 ans d’existence, d’une première édition confidentielle et artisanale à un événement gigantesque rassemblant des milliers de personnes.&lt;/p&gt;

&lt;p&gt;Ce retour d’expérience d’une équipe d’organisateurs est vraiment enrichissant, et je le partagerai dès que possible à nos camarades organisateurs de l’Atlantique Day chez Onepoint à Nantes, mais aussi à mes copains organisateurs de Paris Web. On peut toujours s’améliorer !&lt;/p&gt;




&lt;h3&gt;
  
  
  Arrêtons de (dé)tester nos applications
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/luifr10" rel="noopener noreferrer"&gt;Louis Fredice Njako Molom&lt;/a&gt; et &lt;a href="https://github.com/stanlee974" rel="noopener noreferrer"&gt;Stanley Servical&lt;/a&gt; ont mené un atelier sur la validation de cas d’utilisation centrés utilisateurs, articulés autour de la solution &lt;a href="https://orange-opensource.github.io/uuv/" rel="noopener noreferrer"&gt;UUV&lt;/a&gt; qu’ils éditent au sein de l’organisation GitHub Orange OpenSource.&lt;/p&gt;

&lt;p&gt;Je n’ai pas pu assister à cet atelier — étant moi-même sur scène au même moment — mais ils ont déjà mené cet atelier au dernier Devoxx et j’ai pu découvrir la solution UUV récemment. Cet outil s’appuie sur les standards actuels du test (Cucumber, Cypress ou Playwright — au choix ! — et aXe) et permet de rédiger ses cas de tests en langage naturel.&lt;/p&gt;

&lt;p&gt;Des dictionnaires dédiés à certains aspects (notamment l’accessibilité) et un assistant (une application Electron) permettent à n’importe quel intervenant sur un projet de rédiger un cas de test. C’est la promesse (tenue) et je trouve ça assez incroyable.&lt;/p&gt;




&lt;h3&gt;
  
  
  Ne jouez plus solo
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.linkedin.com/in/julienlibert/" rel="noopener noreferrer"&gt;Julien Libert&lt;/a&gt; a découvert le &lt;em&gt;mob programming&lt;/em&gt; en conférence, et nous transmet dans une conférence son expérience après une année de pratique ! De la théorie à la pratique (avec son lot d’aménagements loin de la théorie), il nous raconte ce qui a fonctionné — ou non ! — et quelques anecdotes intéressantes sur la réalité du terrain.&lt;/p&gt;

&lt;p&gt;Mon passage préféré : l’utilisation du &lt;em&gt;mob programming&lt;/em&gt; en guise d’entretien technique lors des recrutements. Pas de problème à tiroir ou d’exercice en mode &lt;em&gt;fizz buzz&lt;/em&gt;, mais un problème sélectionné en amont par la candidate elle-même — qui a donc le temps de potasser — et la solution mise en œuvre est déroulée en binôme le jour de l’entretien.&lt;/p&gt;

&lt;p&gt;Je trouve énormément d’avantages à cette pratique !&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;em&gt;Chrome Devtools from zero to hero&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.linkedin.com/in/simonbelbeoch/" rel="noopener noreferrer"&gt;Simon Belbeoch&lt;/a&gt; nous conduit dans une quête annexe : dépasser le basique &lt;code&gt;console.log()&lt;/code&gt; en jouant dans les outils de développement.&lt;/p&gt;

&lt;p&gt;Des autres méthodes de l’objet &lt;code&gt;console&lt;/code&gt; — que j’ai découverte en créant des CLI en Node… —  aux outils de simulation de troubles visuels en passant par le &lt;code&gt;debugger;&lt;/code&gt;, nous avons vu du paysage et des couleurs !&lt;/p&gt;

&lt;p&gt;Le seul bémol que j’apporterai est de restreindre le sujet, dès le titre, à Chrome… alors que toutes ces fonctionnalités existent dans Firefox ou Safari.&lt;/p&gt;

&lt;p&gt;Et je préfère Firefox !&lt;/p&gt;




&lt;h3&gt;
  
  
  Dédramatisons l’accessibilité
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.linkedin.com/in/celine-merand/" rel="noopener noreferrer"&gt;Céline&lt;/a&gt; et &lt;a href="https://www.linkedin.com/in/charlinehumeau/" rel="noopener noreferrer"&gt;Charline&lt;/a&gt; ont pu rejouer leur conférence, qui brosse un portrait de l’accessibilité web  bien loin des clichés habituels : moche, compliqué, cher, etc. En vingt minutes, elles réussissent un véritable tour de force : sensibiliser au handicap, illustrer avec des situations concrètes, apporter des ressources théoriques et proposer des outils concrets pour mettre le pied à l’étrier.&lt;/p&gt;

&lt;p&gt;Et leur conférence sortait du lot : c’était la seule catégorisée UX / UI de toute la journée !&lt;/p&gt;




&lt;h2&gt;
  
  
  La récompense de la quête
&lt;/h2&gt;

&lt;p&gt;Une première édition est toujours un pari risqué.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Les spectateurs seront-ils au rendez-vous ?&lt;/strong&gt; Le plan initial visait 150 personnes, nous étions plus de 400 !&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;L’appel à sujets sera-t-il visible et fructueux ?&lt;/strong&gt; L’équipe a reçu plus de 160 propositions, la sélection s’est avérée rude !&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Les partenaires trouveront-ils un intérêt ?&lt;/strong&gt; Avec 19 partenaires présents, le moins qu’on puisse dire est que c’est un grand oui !&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Et surtout… va-t-on réussir à aller au bout de l’expédition ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;L’équipe du devQuest s’est entourée pour bénéficier d’expériences enrichissantes, et a su apporter beaucoup de personnalité à ce nouveau venu dans le circuit des conférences. Leur motivation et leurs convictions ont permis aux participants et orateurs de passer une excellente journée, distrayante, faite de rencontres et d’apprentissages.&lt;/p&gt;

&lt;p&gt;J’en repars en ayant glâné de nouvelles connaissances, découvert quelques personnes et passé un très bon moment.&lt;/p&gt;

&lt;p&gt;Bravo à l’équipe du devQuest, et merci à onepoint de nous permettre de partir en expédition pour des quêtes de ce genre !&lt;/p&gt;

</description>
      <category>devquest</category>
      <category>conferences</category>
      <category>talks</category>
    </item>
  </channel>
</rss>
