CodeMirror, l'éditeur de contenu ultime...

Depuis mes débuts sous Drupal (ça commence à dater un peu ;-), je cherche l'arme ultime pour éditer des contenus. Idéalement j'aurais préférer rédiger mes articles en directement HTML, mais faire cela dans un pauvre TextArea n'est pas une activité des plus joyeuses. Alors j'ai essayé les fameux éditeurs visuels (aka wysiwyg comme TinyMCE, FCKEditor, etc.) mais ces usines à gaz sont bien trop lourdes à mon goût et le code produit aussi vilain qu'ingérable. J'en ai eu tellement marre que j'en étais finalement rendu à utiliser ce bon vieux gedit, puis plus tard une combinaison entre gedit et WebDav (c'est d'ailleurs uniquement pour cela que j'avais bidouillé ce module). C'est la solution que j'ai utilisé pendant quelques années. Il y bien un bref épisode avec markitup mais rédiger des articles en HTML, sans colorisation revient peu ou prou à se passer d'éditeur.

Et puis ce matin, sans trop y croire, j'ai encore tenté une recherche chez l'ami googueule pour un html javascript editor highlighting, et cette fois, je suis tombé sur une "nouveauté", le projet codemirror...

Le projet codemirror

CodeMirror est un éditeur non-wysiwyg permettant de travailler directement sur le code source d'un document comme MarkItUp. Mais à la différence de ce dernier, il ne se contente pas d'ajouter des fonctionnalités sur un simple TextArea, mais, comme TinyMCE, implémente un éditeur visuel complet qui le remplace, avec comme premier impact, la colorisation syntaxique.

Voilà donc enfin un éditeur de code HTML écrit en javascript qui est à la fois léger, performant, capable de coloriser en temps réel des documents complexes (CSS et JS embarqué dans du HTML, code PHP, etc.), autorisant la correction orthographique (un must me concernant ;-), et fournissant des aides à la rédactions basiques mais efficaces (principalement une auto-indentation du code source, la correspondance sur les balises ouvrantes/fermantes, fonction de sauvegarde par Ctrl-S, etc.). L'outil serait presque parfait s'il intégrait la possibilité de définir des raccourcis clavier pour accélérer certains balisages (gras, ancres, liens, etc.). Mais je gage qu'il ne doit pas être très sorcier de le faire évoluer dans ce sens, l'essentiel étant déjà là.

Intégration à wysiwyg

La mise en oeuvre dans Drupal est loin d'être compliquée grâce au très bon module wysiwyg. Bien évidement, codemirror ne fait pas parti de ce que ce module fournit en standard, mais ajouter de nouveaux éditeurs est terriblement simple. Cela commence par le téléchargement de codemirror et son installation dans le dossier sites/all/libraries/codemirror de sorte à ce que l'on ai bien les dossiers css, js, calés juste en dessous.

Ensuite, je me suis simplement basé sur le code source fournit pour l'éditeur markitup. J'ai donc dupliqué editors/markitup.inc en editors/codemirror.inc, rechercher/remplacer markitup par codemirror puis à modifier un peu le fichier de sorte à le faire causer avec codemirror. Cela a principalement consisté à remplacer la fonction wysiwyg_codemirror_editor par le code suivant :

/**
* Plugin implementation of hook_editor().
*/

function wysiwyg_codemirror_editor() {    
$editor['codemirror'] = array(
'title' => 'codemirror',
'vendor url' => 'http://marijn.haverbeke.nl/codemirror/',
'download url' => 'http://github.com/marijnh/CodeMirror',
'library path' => wysiwyg_get_path('codemirror'),
'libraries' => array(
'' => array(
'title' => 'Source',
'files' => array('js/codemirror.js'),
),
),
'version callback' => 'wysiwyg_codemirror_version',
'themes callback' => 'wysiwyg_codemirror_themes',
'settings callback' => 'wysiwyg_codemirror_settings',
'plugin callback' => 'wysiwyg_codemirror_plugins',
'versions' => array(
'1.0' => array(
'js files' => array('codemirror.js'),
'css files' => array('codemirror.css'),
),
),
);
return $editor;
}
fonction wysiwyg_codemirror_editor

Le code se comprend facilement lorsqu'il est lu après la page de documentation de codemirror.

La version 1.0 est fausse, j'ai fait cela vite, vous pouvez bien évidement améliorer cela. Dans la même veine de "vite fait mal fait", la seconde fonction modifié dans le fichier :

function wysiwyg_codemirror_version($editor) {
return "1.0"; // ben voyons... :)
}
modification (sale) de la fonction wysiwyg_codemirror_version

Enfin, une version toute aussi minimaliste de wysiwyg_codemirror_settings pour fournir au code javascript le chemin vers la librairie codemirror :

function wysiwyg_codemirror_settings($editor, $config, $theme) {
$settings = array(
'root' => base_path() . $editor['library path'] . '/',
);

return $settings;
}
modification de la fonction wysiwyg_codemirror_settings

Il y aurait sûrement pas mal de chose à changer mais en l'état, ça fonctionne. Deuxième étape, créer le fichier editors/js/codemirror.js sur le même principe que le précédent : en dupliquant markitup.js et en cherchant/remplaçant par codemirror. Ensuite il ne reste plus qu'à fournir le code d'attachement qui va bien :

Drupal.wysiwyg.editor.attach.codemirror = function(context, params, settings) {
var editor = CodeMirror.fromTextArea(params.field, {
path: settings.root+"js/",
parserfile: ["parsexml.js", "parsecss.js", "tokenizejavascript.js", "parsejavascript.js", "parsehtmlmixed.js"],
stylesheet: [settings.root+"css/xmlcolors.css",settings.root+"css/csscolors.css",settings.root+"css/jscolors.css",settings.root+"css/main.css"],
continuousScanning: 500,
autoMatchParens:true,
lineNumbers: true,
indentUnit:2,
tabMode: "spaces",
reindentOnLoad: true,
height: "350px",
});

};

/**
* Detach a single or all editors.
*/
Drupal.wysiwyg.editor.detach.codemirror = function(context, params) {
};

})(jQuery);
fichier codemirror.js

Vous noterez l'absence de code de détachement qu'il me reste à écrire... Il n'y a maintenant plus qu'à ajouter une petit feuille de style pour la route dans editors/css/codemirror.css histoire d'améliorer un peu le visuel :

.CodeMirror-line-numbers {
width: 2.2em;
color: #aaa;
background-color: #eee;
text-align: right;
padding-right: .3em;
font-size: 10pt;
font-family: monospace;
padding-top: .4em;
}

.editbox {
border:1px solid #CCC;
}
fichier codemirror.css

Et voilà, vous pouvez maintenant activer le nouvel éditeur dans le paramétrage de wysiwyg pour apprécier le résultat.

Conclusion

Histoire de bien valider le concept, cet article a été entièrement écrit avec codemirror et force est d'avouer que toutes les fonctionnalités annoncées sont bien au rendez-vous. Tout d'abord c'est rapide, tant à l'initialisation (pas d'effet moches au lancement comme TinyMCE ou CKEditor), qu'à l'usage (pas de texte à la traîne de vos doigts). L'auto-indentation (placement automatique du curseur à la bonne position lorsque l'on ouvre une balise) et la correspondance des balises marche elles aussi très bien. Le projet est assez jeune (l'historique démarre en 2009, et nous en sommes à la 0.67), mais est plus que prometteur, en espérant qu'arrive les raccourcis clavier, et pourquoi pas, l'auto-complètement des balises.

En attendant, égoïstement, j'ai enfin trouvé mon éditeur sans compromis :)

Vus : 1217
Publié par arNuméral : 54