Retirer le formatage Word dans un éditeur de texte formaté à l'aide de JavaScript

La plupart des CMS disposent d'un éditeur de texte WYSISYG permettant d'éditer du texte formatté. Ceux-ci ont des avantages et des défauts parfois gênants. Un des soucis récurrents est l'importation de texte formatté depuis des logiciels comme Word ou OpenOffice qui créent du code HTML qui est la plupart du temps indésirable car il va se superposer à la feuille de style. Certains éditeurs permettent d'importer du texte non formatté, mais parfois il faut pouvoir le faire "à la main".

Si vous développez votre éditeur ou voulez adapter des éditeurs existants, il peut être utile de gérer soi-même le formatage du texte à l'intérieur de l'éditeur. Les morceaux de code qui suivent proviennent du forum IPS Community et de Stack Overflow, mais je trouvais utile de les rassembler pour répondre à la problématique de pouvoir sélectionner du texte dans un élément contenteditable, retirer le formatage et remplacer ce texte.

1. Retirer le formatage d'une chaîne de caractères

De multiples solutions existent sur Internet pour retirer le formatage HTML d'une chaîne de caractère, je vous présente celle-ci qui fonctionne très bien. Elle permet de retirer les balises inutiles, mais conserve le formatage de base comme le gras ou l'italique (ces balises peuvent être retirées avec la commande: document.execCommand("removeFormat", false, null); plus d'information sur execCommand).

// removes MS Office generated guff
function cleanHTML(input) {
  // 1. remove line breaks / Mso classes
  var stringStripper = /(\n|\r| class=(")?Mso[a-zA-Z]+(")?)/g; 
  var output = input.replace(stringStripper, ' ');
  // 2. strip Word generated HTML comments
  var commentSripper = new RegExp('<!--(.*?)-->','g');
  var output = output.replace(commentSripper, '');
  var tagStripper = new RegExp('<(/)*(meta|link|span|\\?xml:|st1:|o:|font)(.*?)>','gi');
  // 3. remove tags leave content if any
  output = output.replace(tagStripper, '');
  // 4. Remove everything in between and including tags '<style(.)style(.)>'
  var badTags = ['style', 'script','applet','embed','noframes','noscript'];
  
  for (var i=0; i< badTags.length; i++) {
    tagStripper = new RegExp('<'+badTags[i]+'.*?'+badTags[i]+'(.*?)>', 'gi');
    output = output.replace(tagStripper, '');
  }
  // 5. remove attributes ' style="..."'
  var badAttributes = ['style', 'start'];
  for (var i=0; i< badAttributes.length; i++) {
    var attributeStripper = new RegExp(' ' + badAttributes[i] + '="(.*?)"','gi');
    output = output.replace(attributeStripper, '');
  }
  return output;
}

2. Récupérer le texte sélectionné dans un élément contenteditable

Pour enlever le formatage d'un texte, Il faut d'abord pouvoir sélectionner du texte dans un élement ayant la classe contenteditable et récupérer la chaîne de caractères associée. Une fois cette chaîne obtenue, on peut enlever le formatage (avec la fonction précédente par exemple) et remplacer la sélection par le nouveau texte.

function getSelectionHtml() {
    var html = "";
    if (typeof window.getSelection != "undefined") {
        var sel = window.getSelection();
        if (sel.rangeCount) {
            var container = document.createElement("div");
            for (var i = 0, len = sel.rangeCount; i < len; ++i) {
                container.appendChild(sel.getRangeAt(i).cloneContents());
            }
            html = container.innerHTML;
        }
    } else if (typeof document.selection != "undefined") {
        if (document.selection.type == "Text") {
            html = document.selection.createRange().htmlText;
        }
    }
   replaceSelectionWithHtml(cleanHTML(html));
}

3. Remplacer la sélection par une nouvelle chaîne

Une fois le texte sélectionné dans l'éditeur on le remplace par un nouveau texte, dans le cas de figure qui nous intéresse par du texte non formatté.

function replaceSelectionWithHtml(html) {
    var range, html;
    if (window.getSelection && window.getSelection().getRangeAt) {
        range = window.getSelection().getRangeAt(0);
        range.deleteContents();
        var div = document.createElement("div");
        div.innerHTML = html;
        var frag = document.createDocumentFragment(), child;
        while ( (child = div.firstChild) ) {
            frag.appendChild(child);
        }
        range.insertNode(frag);
    } else if (document.selection && document.selection.createRange) {
        range = document.selection.createRange();
        html = (node.nodeType == 3) ? node.data : node.outerHTML;
        range.pasteHTML(html);
    }
}
Cette page appartient aux catégories suivantes: actualités , Code , JavaScript.

Commentaires

Ajoutez un commentaire

5103
Petits fours servis