OpenClassrooms

Colorer son code dans un textarea avec JavaScript Online

OpenClassrooms
En Ligne

Prix sur demande
Ou préférez-vous appeler directement le centre?

Infos importantes

Typologie Formation
Méthodologie En ligne
  • Formation
  • En ligne
Description

Nous vous proposons des cours ouverts pour se former autrement, pour devenir acteur de votre vie. Nous vous aidons à prendre votre envol, mais ça ne s'arrête pas là. Notre volonté est de vous accompagner tout au long de votre vie, dans votre parcours professionnel.Grâce à cette formation vous pourrez acquérir les connaissances nécessaires qui vous permettrons d’ajouter des compétences à votre profil et obtenir de solides aptitude qui vous offriront de nombreuses opportunités professionnelles.

Questions / Réponses

Pose une question et d'autres utilisateurs vous répondrons

Qui voulez-vous pour répondre à votre question ?

On publiera seulement ton nom et prénom et ta question

Programme

Introduction du cours Concept de base

En créant une partie administration d'un site, il arrive que l'on veuille directement modifier le code de la page directement depuis le site Internet. Ce genre de système est assez facile à réaliser à l'aide de PHP et mySQL (ou autre) et un formulaire donnant accès au script à l'aide d'une balise "textarea".

Cependant, pour des codes relativement longs, la lisibilité est loin d'être optimale (personnellement à partir de 20 lignes, ça se complexifie). Pour remédier à ce problème, il est tentant de directement mettre de la mise en page dans le champ du formulaire, mais cela modifierait le contenu.

La solution que je propose ici part d'une idée simple : rendre le texte de la balise "textarea"  transparent, créer une balise miroir derrière la balise de code et y dupliquer le texte de la première balise. Ce sera lors de cette troisième étape que le code pourra être coloré.

Prérequis

Avant de s'attaquer au cours en tant que tel, il est important de s'être déjà familiarisé avec JavaScript. Je recommande donc la lecture des trois premiers chapitres du tutoriel de Thunderseb et Nesk : Dynamisez vos sites web avec Javascript !

De la même façon, il est recommandé d'avoir des bases en HTML et CSS. Le tutoriel de M@teo21 est parfait pour cela : Apprenez à créer votre site web avec HTML5 et CSS3

Certaines idées ont été aussi reprises de l’article (en anglais) de A list Apart : Expanding Text Areas Made Elegant par Neil Jenkins.

Mise en place des deux cadres superposés : HTML et CSSUn tout petit peu de HTML

La première étape est de bien définir les balises :   

  • La balise textarea au premier plan qui sera appelée balise code, ou simplement code

  • La balise miroir en arrière-plan   

  • Une balise globale

Cette dernière servira comme point d'accroche de base des deux balises précédentes.

Ce qui donne, par exemple, le script suivant :

<div class="global"> <textarea class="col_code" id="code"></textarea> <div class="col_code" id="mirror"></div> </div>

Pour le moment, le script n'est pas encore trop complexe.

Mise en place du CSS

Cette étape est un tout petit peu plus complexe : Il faut veiller à garder exactement la même présentation entre le code et le cadre miroir.

Voici donc un moyen pour y arriver (la description viendra après) :

.global { position:relative; } .col_code { position : absolute; font-family : Consolas,Monaco,"Lucida Console","Liberation Mono","DejaVu Sans Mono","Bitstream Vera Sans Mono","Courier New", monospace; font-size : 12pt; word-break : break-all; word-wrap : break-word; white-space : pre-wrap; border-width: 2px; border-style: groove; margin : 0px; padding : 0px; width : 400px; height : 400px; } textarea.col_code { z-index : 1; color : rgba(0,0,0,0.3); background-color: transparent; overflow : scroll; } div.col_code { z-index : 0; color : black; background-color: white; overflow : hidden; }

Premièrement, le cadre global est en position relative, afin de donner un point de référence aux deux autres cadres (en position absolue). Cette position absolue permet de les placer l'un au-dessus de l'autre à l'aide de la propriété z-index .

Il faut faire attention à ce que le code et le cadre miroir aient la même police, soient de la même taille, que l'on conserve les espaces multiples (white-space: pre-warp; ) et que le passage à la ligne des mots de fasse de façon similaire (ligne 11 et 12).

On peut aussi remarquer que le texte du code n'est pas entièrement transparent, afin de s'assurer du bon alignement du texte entre les deux cadres. De plus, il n'est pas aisé d'introduire un curseur indiquant la zone de sélection du code.

Synchronisation dynamique des cadres : JavaScriptDescendre le cadre miroir en synchronisation avec le cadre code

Pour descendre le cadre miroir, il faudra modifier les propriétés scrollTop   et scrollLeft   de celui-ci à chaque fois que l'on descend dans le code.

Heureusement, un événement JavaScript prend cette propriété en compte : l'événement scroll . Il reste donc à ajouter une fonction JavaScript qui s'occupe de tout ça :

function setMirrorScroll() { document.getElementById('mirror').scrollTop = document.getElementById('code').scrollTop; document.getElementById('mirror').scrollLeft = document.getElementById('code').scrollLeft; }

Il existe plusieurs moyens de rajouter un événement JavaScript, mais afin de garder notre script le plus léger possible, il sera inclus directement dans le code HTML de la page qui, une fois modifié, donne :

<div class="global"> <textarea class="col_code" id="code" onscroll="setMirrorScroll();"></textarea> <div class="col_code" id="mirror"></div> </div>Redimensionner le cadre miroir

Cette partie demande un peu plus de subtilité quant à la prise en charge des événements. En effet, il n'existe pas d'événement JavaScript prenant en charge le redimensionnement d'un cadre. Néanmoins, redimensionner le cadre du code nécessite l'utilisation de la souris, et prend effet lorsque celle-ci est relâchée.

L'événement utilisé sera mouseup  associé au cadre du code. La taille de celui-ci sera récupérée à l'aide de ses propriétés clientWidth  et clientHeight  et ainsi modifier le height   et width   du CSS du cadre miroir.

La fonction JavaScript sera donc :

function setMirrorSize() { var textarea_elem = document.getElementById('code'); var textarea_width = textarea_elem.clientWidth; var textarea_height = textarea_elem.clientHeight; var background_elem = document.getElementById('mirror'); background_elem.style.width = textarea_width +"px"; background_elem.style.height = textarea_height+"px"; }

Et le code HTML devient :

<div class="global"> <textarea class="col_code" id="code" onscroll="setMirrorScroll();" onmouseup="setMirrorSize();"></textarea> <div class="col_code" id="mirror"></div> </div>

Voilà maintenant deux cadres parfaitement synchronisés !

Il ne reste donc plus qu'à s'attaquer à la mise en couleur du contenu du cadre code dans le cadre miroir...

Copie et coloration du code : JavaScriptCopie du code

La première chose à prendre en compte est de se demander quand transférer le code d'un cadre à l'autre. Il serait tentant de le faire de façon récursive toutes les 500 ms par exemple, mais cette méthode fort lourde est loin d'être optimale. Il existe cependant une alternative.

Celle-ci est l'utilisation d'un événement plus spécifique : l'événement input. Celui-ci s'enclenche lorsque l'on envoie une entée vers le champ (par exemple un caractère tapé sur le clavier). Cependant, cet événement n'est pas compatible avec certains vieux navigateurs tels qu’Internet Explorer 6, 7 et 8. Une méthode pour que ceux-ci soient compatibles sera expliquée à la fin de ce tutoriel.

Le code HTML devient alors :

<div class="global"> <textarea class="col_code" id="code" onscroll="setMirrorScroll();" onmouseup="setMirrorSize();" oninput="refreshMirrorCode();"></textarea> <div class="col_code" id="mirror"></div> </div>

La fonction JavaScript pour transférer le code du cadre code vers le cadre miroir est quand à elle :

function refreshMirrorCode() { var script_in = document.getElementById('code').value; var script_out = script_in; document.getElementById('mirror').innerHTML = script_out; }

Cependant, il persiste un problème : le code du cadre mirroir en arrière-plan ne passe pas à la ligne !

Pour y remédier, nous allons utiliser les expressions régulières de JavaScript afin que les passages à la ligne dans le cadre code soient remplacés par la balise HTML de passage à la ligne <br />  dans le cadre miroir.

De plus lorsque l'un descend tout en bas dans la balise code, il y a un décalage entre le cadre de code et le cadre miroir. Pour y remédier, un passage à la ligne est ajouté à la fin du second cadre.

Finalement, lorsque l'on inscrit du code HTML dans le dans le cadre du code, celui-ci est interprété dans le cadre miroir, if faut donc remplacer certains caractères spéciaux par leur équivalent de caractère spécial HTML afin d'éviter ce problème.

Pour y arriver, nous allons donc rajouter les quelques expressions régulières suivant :

function refreshMirrorCode() { var script_in = document.getElementById('code').value; script_in = script_in.replace(/&/g, '&amp;'); script_in = script_in.replace(/\//g, '&#47;'); script_in = script_in.replace(/</g, '&lt;'); script_in = script_in.replace(/>/g, '&gt;'); script_in = script_in.replace(/"/g, '&quot;'); script_in = script_in.replace(/'/g, '&apos;'); var script_out = script_in.replace(/(?:\r\n|\r|\n)/g, '<br />'); document.getElementById('mirror').innerHTML = script_out + '<br />'; }

Et voilà ! La balise mirroir recrée à l'identique la balise code !

Même si ce n'est pas encore fort impressionnant, nous verrons dans la section suivante comment ajouter des couleurs à votre joli code.

Coloration du code

Voilà le moment tant attendu: mettre le code en couleur.

Le principe est simple : rajouter à la manière d'un BBcode un ensemble d'expressions régulières permettant la mise en couleur de certains éléments. L'exemple qui suit est un exemple simple mettant en couleur du code HTML : les balises en vert, les guillemets en rouge, les chiffres en jaune et les commentaires en gris. Mais cela peut facilement être modifié à l’envie. Que ce soit pour le choix des couleurs ou pour mettre en couleur un autre langage (comme le JavaScript par exemple...).

function refreshMirrorCode() { var script_in = document.getElementById('code').value; script_in = script_in.replace(/&/g, '&amp;'); script_in = script_in.replace(/\//g, '&#47;'); script_in = script_in.replace(/</g, '&lt;'); script_in = script_in.replace(/>/g, '&gt;'); script_in = script_in.replace(/"/g, '&quot;'); script_in = script_in.replace(/'/g, '&apos;'); script_in = script_in.replace(/(&lt;[a-zA-Z](.*?)&gt;)/g, '<span style="color:green;">$1</span>'); // balises en vert script_in = script_in.replace(/(&lt;&#47;[a-zA-Z](.*?)&gt;)/g, '<span style="color:green;">$1</span>'); // balises en vert script_in = script_in.replace(/(&lt;!--(.+?)--&gt;)/g, '<span style="color:lightgrey;">$1</span>'); // commentaires en gris script_in = script_in.replace(/(&quot;(.+?)&quot;)/g, '<span style="color:red;">$1</span>'); // guillements en rouge var script_out = script_in.replace(/(?:\r\n|\r|\n)/g, '<br />'); document.getElementById('mirror').innerHTML = script_out + '<br />'; }

Voilà qui est fait !

Récapitulatif

Avant de terminer, voici un petit récapitulatif du code HTML, CSS et JavaScript complet :

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Tutoriel : Mise en couleur du code d'une balise "texarea" grâce à Javascript</title> <style> .global { position:relative; } .col_code { position : absolute; font-family : Consolas,Monaco,"Lucida Console","Liberation Mono","DejaVu Sans Mono","Bitstream Vera Sans Mono","Courier New", monospace; font-size : 12pt; word-break : break-all; word-wrap : break-word; white-space : pre-wrap; border-width: 2px; border-style: groove; margin : 0px; padding : 0px; width : 400px; height : 400px; } textarea.col_code { z-index : 1; color : rgba(0,0,0,0.3); background-color: transparent; overflow : scroll; } div.col_code { z-index : 0; color : black; background-color: white; overflow : hidden; } </style> </head> <body> <div class="global"> <textarea class="col_code" id="code" onscroll="setMirrorScroll();" onmouseup="setMirrorSize();" oninput="refreshMirrorCode();"></textarea> <div class="col_code" id="mirror"></div> </div> <script type="text/javascript"> function setMirrorScroll() { document.getElementById('mirror').scrollTop = document.getElementById('code').scrollTop; document.getElementById('mirror').scrollLeft = document.getElementById('code').scrollLeft; } function setMirrorSize() { var textarea_elem = document.getElementById('code'); var textarea_width = textarea_elem.clientWidth; var textarea_height = textarea_elem.clientHeight; var background_elem = document.getElementById('mirror'); background_elem.style.width = textarea_width +"px"; background_elem.style.height = textarea_height+"px"; } function refreshMirrorCode() { var script_in = document.getElementById('code').value; script_in = script_in.replace(/&/g, '&amp;'); script_in = script_in.replace(/\//g, '&#47;'); script_in = script_in.replace(/</g, '&lt;'); script_in = script_in.replace(/>/g, '&gt;'); script_in = script_in.replace(/"/g, '&quot;'); script_in = script_in.replace(/'/g, '&apos;'); script_in = script_in.replace(/(&lt;[a-zA-Z](.*?)&gt;)/g, '<span style="color:green;">$1</span>'); // balises en vert script_in = script_in.replace(/(&lt;&#47;[a-zA-Z](.*?)&gt;)/g, '<span style="color:green;">$1</span>'); // balises en vert script_in = script_in.replace(/(&lt;!--(.+?)--&gt;)/g, '<span style="color:lightgrey;">$1</span>'); // commentaires en gris script_in = script_in.replace(/(&quot;(.+?)&quot;)/g, '<span style="color:red;">$1</span>'); // guillements en rouge var script_out = script_in.replace(/(?:\r\n|\r|\n)/g, '<br />'); document.getElementById('mirror').innerHTML = script_out + '<br />'; } </script> </body> </html>Pour aller plus loin...

Il est possible de faire de nombreuses améliorations de cette mise en couleur, par exemple :   


Comparer pour mieux choisir:
En voir plus