TextField, htmlText et retours à la ligne
Par -Alexandre LEGOUT aka LAlex- le lundi, janvier 7 2008, 19:37 - AS3 / Flex2 - Lien permanent
Le nouvelle gestion des TextField avec AS3 est assez géniale je dirais: plus de propriété html, et une gestion commune entre le texte "classique" associé aux TextFormat et le texte HTML. Du coup, on peut manipuler indifféremment le HTML ou les TextFormat, la modification de l'un sera reportée sur l'autre, comme on peut le voir via le code suivant:
// Crée le champ texte
var tField:TextField = new TextField;
tField.text = "LAlex";
// Crée le format (couleur rouge)
var tFormat:TextFormat = new TextFormat();
tFormat.color = 0xFF0000;
// Applique sur les deux premiers caractères
tField.setTextFormat(tFormat, 0, 2);
// Affiche le resultat HTML de tout ca
trace(tField.htmlText);
<P ALIGN="LEFT"><FONT FACE="Times Roman" SIZE="12" COLOR="#FF0000" LETTERSPACING="0" KERNING="0">LA<FONT COLOR="#000000">lex</FONT></FONT></P>
Bon, aprés on va pas chipoter sur la cohérence du formatage HTML, évidemment il y a mieux, mais le tout est d'avoir notre correspondance TextFormat/HTML...
Bref, tout ceci étant fait, si on veut obtenir le copie conforme d'un texte dans un autre, il suffit alors de copier le htmlText du premier sur le second, sans se préoccuper des TextFormat? Eh bien pas forcément...
En effet, un petit bug (a mon avis, car j'ai du mal à expliquer la logique derrière ca) s'est glissé dans la gestion du HTML par les TextField. En effet, quelle que soit la valeur de la propriété condenseWhite (sensée faire le même travail qu'un navigateur HTML, à savoir ne pas afficher les espaces blancs consécutifs), un TextField va systématiquement zapper les paragraphes vides, alors que c'est ce qu'il utilise en interne pour faire des retours à la ligne! Bref, tous les retours à la ligne vont sauter quand on copie le htmlText... Par exemple, si j'ai mis trois retours à la ligne et un texte dans un TextField, les retours à la ligne seront en fait des paragraphes vides <p>:
var tField:TextField = new TextField;
tField.text = "\n\n\nLAlex";
trace(tField.htmlText);
<P ALIGN="LEFT"><FONT FACE="Times Roman" SIZE="12" COLOR="#000000" LETTERSPACING="0" KERNING="0"></FONT></P><P ALIGN="LEFT"><FONT FACE="Times Roman" SIZE="12" COLOR="#000000" LETTERSPACING="0" KERNING="0"></FONT></P><P ALIGN="LEFT"><FONT FACE="Times Roman" SIZE="12" COLOR="#000000" LETTERSPACING="0" KERNING="0"></FONT></P><P ALIGN="LEFT"><FONT FACE="Times Roman" SIZE="12" COLOR="#000000" LETTERSPACING="0" KERNING="0">LAlex</FONT></P>
Bon, OK. Et si maintenant on réaffecte cette valeur à htmlText et qu'on la relit? Voilà ce que ca donne:
var tField:TextField = new TextField;
tField.text = "\n\n\nLAlex";
var myHtmlText:String = tField.htmlText;
tField.text = "";
tField.htmlText = myHtmlText;
trace(tField.htmlText);
<P ALIGN="LEFT"><FONT FACE="Times Roman" SIZE="12" COLOR="#000000" LETTERSPACING="0" KERNING="0">LAlex</FONT></P>
(a noter que je remet le texte à zéro avant de le réattribuer, car sinon il ne fait aucun traitement: il doit exister en interne un traitement du type if (_odlHtmlText != _newHtmlText) {...}).
Comment parer ce problème? J'ai constaté qu'un "vrai" retour à la ligne entre deux paragraphes restaure le retour à la ligne dans le champ texte. Il suffit donc de rajouter un \n entre la fin d'un paragraphe et le suivant. Du coup, une petite regexp fait l'affaire:
var tField:TextField = new TextField;
tField.text = "\n\n\nLAlex";
var myHtmlText:String = tField.htmlText;
tField.text = "";
var reg : RegExp = new RegExp("</([Pp])><", "g");
tField.htmlText = myHtmlText.replace(reg, "</$1><");
trace(tField.htmlText);
<P ALIGN="LEFT"><FONT FACE="Times Roman" SIZE="12" COLOR="#000000" LETTERSPACING="0" KERNING="0"></FONT></P><P ALIGN="LEFT"><FONT FACE="Times Roman" SIZE="12" COLOR="#000000" LETTERSPACING="0" KERNING="0"></FONT></P><P ALIGN="LEFT"><FONT FACE="Times Roman" SIZE="12" COLOR="#000000" LETTERSPACING="0" KERNING="0"></FONT></P><P ALIGN="LEFT"><FONT FACE="Times Roman" SIZE="12" COLOR="#000000" LETTERSPACING="0" KERNING="0">LAlex</FONT></P>
Et voilà! ![]()
Commentaires
Et en précisant .multiline=true sur les 2 champs ?
J'ai résolu plein de problèmes un jour en trouvant cette astuce...
Salut Lalex !
Merci pour l'info ! c'est vraiment pratique tout ça !
Avec les styles en plus ca devient pas mal....
meme si à mon avis, on se cassera toujours autant la tete avec les typos !
++
Fil des commentaires de ce billet