Apache Adobe Flex TutorialTutoriaux Adobe Flex & AIR en Français

8mai/0912

Flex Tips – Obtenir un texte HTML valide à partir du RichTextEditor (htmlText)

Le composant Flex RichTextEditor permet d'avoir un champ texte "riche", c'est-à-dire avec des options de formatage un peu comme celles qu'on trouve dans Word (gras, souligné, alignement, puces…). Ce composant peut-être très pratique pour laisser un utilisateur créer du contenu HTML facilement, sans qu'il ne sache comment écrire du HTML, pour un CMS par exemple ou une plate-forme de blog.

Le composant RichTextEditor (RTE) a une propriété "htmlText", qui permet d'assigner du texte HTML et une propriété "text" qui permet d'avoir le contenu brut, sans balises.

Si par exemple, vous écrivez dans votre RichTextEditor:

This is <b> Bold </ b> text.

Vous obtiendrez par la propriété "htmlText", quelque chose comme:

<TEXTFORMAT LEADING="2">
<P ALIGN="LEFT">
<FONT FACE="Verdana" SIZE="10" COLOR="#0B333C" LETTERSPACING="0" KERNING="0">
This is <b> Bold </b>text.
</FONT>
</P>
</TEXTFORMAT>

Comme vous le voyez, Flex rajoute beaucoup de code HTML non-nécessaire. De plus, ce code pseudo-html ne sera pas interprété par une page HTML classique (TEXTFORMAT n'est pas une balise HTML par exemple).

Dans notre cas, on veut que le contenu HTML inscrit par l'utilisateur soit directement utilisable pour une intégration dans du HTML. Certains ce sont posé la question, sur le blog Thanks Mister. La solution se trouve dans les Expressions Régulières AS3. Avant de passer aux choses sérieuses, voici quelques articles qui devraient vous aider à comprendre les RegExp:

Les Expressions Régulières permettent de trouver des chaînes dans des String, et aussi de faire des remplacement avec la méthode replace de String. C'est ce que l'on va utiliser pour convertir notre pseudo texte HTML. La bonne réponse est dans les commentaires, qui sont coupés car interprétés par le blog comme du HTML. Voici donc un petit résumé. Notez qu'il y a deux fonctions, une pour convertir le HTML en format acceptable par le RichTextEditor, et une autre pour convertir le texte issu du RichTextEditor en HTML valide (xHTML):

// convertir du xHTML en format compatible pour le RichTextEditor
public static function convertFromXHtml(str:String):String {
	var pattern:RegExp;
	pattern = /<p style="text-align:left">/g;
	str = str.replace(pattern, "<P ALIGN=\"LEFT\">");
	pattern = /<p style="text-align:right">/g;
	str = str.replace(pattern, "<P ALIGN=\"RIGHT\">");
	pattern = /<p style="text-align:justify">/g;
	str = str.replace(pattern, "<P ALIGN=\"JUSTIFY\">");
	pattern = /<\/p>/g;
	str = str.replace(pattern, "</P>");
	pattern = /<span style=\"(.*?)\">/g;
	str = str.replace(pattern, "<FONT $1>");
	pattern = /color:(.*?);/g;
	str = str.replace(pattern, "COLOR=\"$1\" ");
	pattern = /font-size:(.*?)px;/g;
	str = str.replace(pattern, "SIZE=\"$1\" ");
	pattern = /font-family:(.*?);/g;
	str = str.replace(pattern, "FACE=\"$1\" ");
	pattern = /text-align:(.*?);/g;
	str = str.replace(pattern, "ALIGN=\"$1\" ");
	pattern = /<\/span.*?>/g;
	str = str.replace(pattern, "</FONT>");
	pattern= /<\/li><li>/g;
	str = str.replace(pattern, "</LI><LI>");
	pattern= /<\/li><\/ul>/g;
	str = str.replace(pattern, "</LI>");
	pattern= /<ul><li>/g;
	str = str.replace(pattern, "<LI>");
	pattern = /<em>/g;
	str = str.replace(pattern, "<I>");
	pattern = /<\/em>/g;
	str = str.replace(pattern, "</I>");
	pattern = /<strong>/g;
	str = str.replace(pattern, "<B>");
	pattern = /<\/strong>/g;
	str = str.replace(pattern, "</B>");
	pattern = /<u>/g;
	str = str.replace(pattern, "<U>");
	pattern = /<\/u>/g;
	str = str.replace(pattern, "</U>");
	// Remove extra white space
	pattern = / /g;
	str = str.replace(pattern, " ");
	return str;
}
//convertir le texte issu du RichTextEditor en format xHTML valide
public static function convertToXHtml(str:String):String{
	var pattern:RegExp;
	pattern = /<TEXTFORMAT.*?>/g;
	str = str.replace(pattern, "");
	pattern = /<\/TEXTFORMAT.*?>/g;
	str = str.replace(pattern, "");
	pattern = /<P ALIGN="LEFT">/g;
	str = str.replace(pattern, "<p style=\"text-align:left\">");
	pattern = /<P ALIGN="RIGHT">/g;
	str = str.replace(pattern, "<p style=\"text-align:right\">");
	pattern = /<P ALIGN="JUSTIFY">/g;
	str = str.replace(pattern, "<p style=\"text-align:justify\">");
	pattern = /<\/P>/g;
	str = str.replace(pattern, "");
	pattern = /<FONT (.*?)>/g;
	str = str.replace(pattern, "<span style=\"$1\">");
	pattern = /COLOR=\"(.*?)\"/g;
	str = str.replace(pattern, "color:$1;");
	pattern = /SIZE=\"(.*?)\"/g;
	str = str.replace(pattern, "font-size:$1px;");
	pattern = /FACE=\"(.*?)\"/g;
	str = str.replace(pattern, "font-family:$1;");
	pattern = /ALIGN=\"(.*?)\"/g;
	str = str.replace(pattern, "text-align:$1;");
	pattern = /LETTERSPACING=\".*?\"/g;
	str = str.replace(pattern, "");
	pattern = /KERNING=\".*?\"/g;
	str = str.replace(pattern, "");
	pattern = /<\/FONT.*?>/g;
	str = str.replace(pattern, "</span>");
	pattern= /<\/LI><LI>/g;
	str = str.replace(pattern, "</li><li>");
	pattern= /<\/LI>/g;
	str = str.replace(pattern, "</li></ul>");
	pattern= /<LI>/g;
	str = str.replace(pattern, "<ul><li>");
	pattern = /<I>/g;
	str = str.replace(pattern, "<em>");
	pattern = /<\/I>/g;
	str = str.replace(pattern, "</em>");
	pattern = /<B>/g;
	str = str.replace(pattern, "<strong>");
	pattern = /<\/B>/g;
	str = str.replace(pattern, "</strong>");
	pattern = /<U>/g;
	str = str.replace(pattern, "<u>");
	pattern = /<\/U>/g;
	str = str.replace(pattern, "</u>");
	return str;
}

Voici donc les fonctions que vous pouvez placer par exemple dans une classe "Utils de votre application pour transformer votre texte à la volée. Certains ont même vu plus loin et ont crée un composant personnalisé basé sur le RichTextEditor auquel ils ont rajouté une propriété "xhtml" qui va prendre le"htmlText" et faire la conversion en interne. Voici un extrait de leur code:

package custom{
	import mx.controls.RichTextEditor;
	public class CustomRichTextEditor extends RichTextEditor{
		public function CustomRichTextEditor(){
		super()
		}
		public function get xhtml():String {
			return convertToXHtml(this.htmlText);
		}
		public function set xhtml(val:String):void {
			this.htmlText = convertFromXHtml(val);
		}
		public static function convertFromXHtml(str:String):String {
			// voir ci-dessus
		}
		public static function convertToXHtml(str:String):String{
			// voir ci-dessus
		}
	}
}

Application Flex utilisant ce composant (démonstration)

Articles similaires

Commentaires (12) Trackbacks (0)
  1. Salut Fabien,

    Encore une fois, un article super utile merci !
    Pour ma part, j'ai intégré les fonctions du pakage (get xhtml, set xhtml, convertFromXHtml, convertToXHtml) dans un composant personnalisé dont du explique le fonctionnement dans l'article "Afficher/masquer les barres d'outils d'un RichTextEditor avec RichTextEditorRemoveSubcontrols".

    Du coup, on obtient en même temps un composant personnalisé qui permet de gérer les boutons du controle + une gestion du code Xhtml..c'est du coup bien pratique

    ++

  2. Il me semble qu'il y a une erreur dans la fonction convertToXhtml : la balise fermante P est supprimé…

  3. excellent ! ca m'a bien rendu service merci !

    des fois on recupere des couleurs formatées comme ca : rgb:(127, 127, 127) et flash en veut pas, alors j'ai rajouté cette regexp pour les convertir dans le format #808080 :

    Actionscript:
    1. pattern = /rgb[(]([\d]{1,3})[, ]+([\d]{1,3})[, ]+([\d]{1,3})[)]/gi;
    2. str = str.replace(pattern, function regexpColorReplace(p_matched_substr:String, p_match_1:String, p_match_2:String, p_match_3:String, p_index:int, p_str:String):String { var n:Number= Number(p_match_1)*0x10000 + Number(p_match_2)*0x100 + Number(p_match_3); return "#" + n.toString(16); });

    j'ai aussi modifié cette regexp :

    Actionscript:
    1. pattern = /color:(.*?);/g;
    2. str = str.replace(pattern, "COLOR=\"$1\" ");

    par celle la :

    Actionscript:
    1. pattern = /color:[ ]*(.*?)[ ]*;/g;
    2. str = str.replace(pattern, "COLOR=\"$1\" ");

    pour prendre en compte les eventuels espaces

    a+

  4. Merci Matthieu pour ce code :)

    Fabien

  5. Une petite question : pourquoi dans "convertToXHtml", la fonction supprime toutes les fin de paragraphe ?
    pattern = //g;
    str = str.replace(pattern, "");

  6. Salut Arfany,

    je ne sais pas vraiment, il faut peut-être l'adapter selon le besoin.

    Fabien

  7. Bonjour,

    >je ne sais pas vraiment, il faut peut-être l'adapter selon le besoin

    C'est ce que j'ai fait.

    MXML:
    1. pattern = //g;
    2. str = str.replace(pattern, "");

  8. J'avais un souci sur la création de balise vide du type ou

    au final j'ai rajouté une fonction que j'appel apres la mise en forme avec convertToXHTML()

    voici le code

    Actionscript:
    1. pattern = //g;
    2.                 str = str.replace(pattern, "");
    3.                 pattern = //g;
    4.                 str = str.replace (pattern, "");

  9. Re,

    Les balise HTML ne fonctionne pas dans les commentaire :D

  10. oui, c'est la merde :P

    Fab

  11. Bonsoir,
    Je tente d'insérer du texte dans dans un RichTextEditor à la position du curseur. Cela fonctionne trés bien si j'utilise la propriété text mais impossible de faire la même chose avec htmlText.
    var ind:int = rteNotesAdmin.selection.beginIndex;
    rteNotesAdmin.text = rteNotesAdmin.text.substring(0, ind) + dateFrtxt + rteNotesAdmin.text.substring(ind, rteNotesAdmin.text.length);

    Avez-vous une idée pour résoudre cela?
    Merci par avance.

  12. Pas vraiment, le beginIndex doit bien être relative au text et pas au htmlText. Je n'ai pas de solution en stock pour contourner cela

    Fabien


Leave a comment

(required)

Aucun trackbacks pour l'instant