ESTHÉTIQUE
SIMPLICITÉ
EFFICACITÉ

Aneartiste sur deviantartAneartiste sur twitter Aneartiste sur scoop-it

WYMIWYW Js-Editor

Un éditeur en Javascript

Il exite une pléthore d'éditeur fonctionnels et faciles à installer. Pour ne citer que les plus connus en open source: Moo­Edit­able, QuillJS, Trix, Trum­bowyg, CKEdit­or, Sum­mer­note, jHtml­Area... Néanmoins plusieurs raisons peuvent vous mener à développer votre propre éditeur. Le désir d'avoir plus de contrôle sur l'apparence et les fonctions du programme ; le besoin d'un éditeur spécifique destiné à un langage de balisage alternatif ; la volonté de se passer d'une bibliothèque jQuery approchant les 100ko, ou simplement pour le plaisir de tester ses propres capacités à mener une telle aventure. Per­son­nel­lement, c'est en cherchant une alternative fiable à l'ancienne instruction Javascript "do­cu­ment.exec­Com­mand" sup­primée des standards du Web et – bien qu'en­core partiellement supportée dans certains navigateurs – destinée à disparaitre, que je me suis lancé par jeu dans cette démarche. Dans un premier temps, j'avais experimenté rapidement le couple d'instruction "win­dow.get­Se­lec­tion() / get­Range­At(0)" dont l'ap­pli­ca­tion (au stade expérimental) m'a semblé plutôt capricieuse en fonction des navigateurs. En conséquence, je me suis finalement rabattu sur la propriété "event.target" qui peut être utilisée pour implémenter la délégation d'événements.

Aperçu de l'éditeur WYMIWYW,WYMIWYW EditWYMIWYW Edit

« Un bon éditeur, c'est un éditeur qui médite. »
—Philippe Geluck


What You Make Is What You Want

Il ne s'agit pas ici d'un programme pleinement fonctionnel mais d'une ébauche destinée à servir de base à un développement ultérieur plus poussé. L'apparence et la quantité des fonctions disponibles sont donc volontairement limitées et ciblent plutôt l'idée d'un environnement de tests qu'un cadre pleinement opérationnel. Si l'on se lance à partir de cette base, on aura un aperçu rapide du fonctionnement interne du systême et de la manière de le compléter suivant ses propres besoins. Visuellement, on aura deux fenètres, l'une pour la saisie, l'autre pour générer un aperçu. Une simple barre de menu tout à fait spartiate dominant l'ensemble.

En résumé, pour la partie HTML, cela donne :


<div id="cad1">
<input value="bouton menu 1" />
<input value="bouton menu 2" />
<input value="bouton menu 3" />
<input value="bouton menu 4" />
<input value="bouton menu 5..." />
<textarea id="editeur" ></textarea>
</div>
<div id="cad2">
<input type="button" value="Aperçu" />
<div id="resultat"></div>
</div>

et pour le css :


body {
position:relative;
}
#cad1, #cad2 {
display:block;
float:left;
width:49.5%;
}
#editeur, #resultat {
margin-top:10px;
border: 1px solid black;
padding: 5px;
overflow: auto;
}
#editeur {
margin:10px 5px;
height:600px;
width:96%;
display:block;
}
#resultat {
width:98%;
height:600px;
}

Détail du code éditeur,Capture d'écranCapture d'écran

« Le projet est le brouillon de l'avenir. Parfois, il faut à l'avenir des centaines de brouillons. »
—Jules Renard


Fonctionnement du javascript

La première chose à faire est de savoir si un fragment de chaîne a été sélectionné dans la fenêtre de l'éditeur, puis de déterminer sa position au cœur du texte. Concrètement on commence par disposer une écoute sur l'évènement "sélection" avec l'instruction "onSelect", puis on execute la fonction suivante pour récupérer les variables de l'élément texte sélectionné.


const contenu = document.querySelector('#editeur');
contenu.onselect = logSelection;
 
function logSelection(event)
{
const log = document.getElementById('log');
const selection = event.target.value.substring(event.target.selectionStart, event.target.selectionEnd);
startvalue=event.target.selectionStart;
endvalue=event.target.selectionEnd;
}

Il faut ensuite isoler la sélection dans une variable et lui appliquer les transformations demandées via les boutons du menu. Pour ce qui concerne la gestion des choix de formatage, on utilise l'instruction "replace" pour encadrer chaque sélection à l'aide des balises adéquates. On fera également intervenir un "prompt" lorsqu'une information complémentaire est nécessaire (intitulé d'un lien, source d'une image, emplacement d'une pièce jointe, etc.)

   
var texte = doc.substring(startvalue,endvalue);
if(texte!=='') {
switch (format) {
case 'bold':
var ntexte = '<strong>'+texte+'</strong>';
break;
case 'italic':
var ntexte = '<em>'+texte+'</em>';
break;
case 'underline':
var ntexte = '<u>'+texte+'</u>';
break;
case 'createLink':
argument = prompt("Quelle est l'adresse du lien ?");
var ntexte = '<a href=">'+argument+'">'+texte+'</a>';
break;
case 'insertImage':
argument = prompt("Où se trouve l'image ?");
var ntexte = '<img src="'+argument+'" alt="'+texte+'" />';
break;
case 'h1':
var ntexte = '<h1>'+texte+'</h1>';
break;
case 'h2':
var ntexte = '<h2>'+texte+'</h2>';
break;
case 'h3':
var ntexte = '<h3>'+texte+'</h3>';
break;
default: break;
}
}

L'étape finale consiste à réinsérer la partie modifié dans le texte original en conservant l'intégrité de son environnement. Pour appliquer les modifications, on découpe le texte affiché dans la fenêtre en trois partie distinctes. celle qui précède la sélection et celle qui la suit, la sélection proprement dite étant remplacée par la version nouvellement formatée et l'on recharge l'ensemble après réinitialisation du cadre.


part1 = doc.substring(0, startvalue);
part2 = doc.substring(endvalue, doc.length);
document.getElementById('editeur').innerHTML = "";
document.getElementById('editeur').value = part1+ntexte+part2;

Sans entrer dans les détails, je pense qu'on a ci-dessus un aperçu correct de la démarche. La meilleure manière de comprendre le code et d'expérimenter soi-même diffèrentes solutions en intégrant des modifications ponctuelles. La version fonctionnelle de la démo est à télécharger ici. Elle se compose de trois fichiers : javascript, css, et html pour un poids total de 4,5ko. Ébauche imparfaite évidemment, mais ultra-minimale et pleinement configurable.

publié le 12/12/2021, à 18h32 par Frédéric Schäfer

Précédentsuivant