Wednesday, February 21, 2007

Hacking htmlText in Flex 2

During the last fortnight I've needed to use htmlText with Flex 2. My needs were simple. But I still ran into lots of problems. As you probably know htmlText supports a subset of html elements (<p>,<a>, <b>, <i>, <u>, <img>, <br>, <font>). This short list can be enough for simple projects. But it's never as simple as it should be.


htmlText wrapping problem

For future reference I offer the following list of problems I encountered using htmlText. The Flex documentation notes that the img element is not fully support and many of the problems below relate to images. Still displaying images in htmlText is too useful to ignore and so image problems are included in this list. I don't have many solutions and the ones I offer are hacks. But sometimes it's helpful to be forewarned.



  • If you include more than one image and have text links within htmlText the links hit area is often too small. It is either a single pixel at the lower right edge of the text or a thin line below the text. The text itself doesn't act as a link. This problem may be cache related or relate to server response time as it may go away after frequent viewings.

  • Text links often extend well beyond the end of the word. Typically they run the width of the component. But if you create a space below the link (i.e. <p> </p><br/>) then the entire space will act as a link.

  • When using <font> within a list item to apply color to the text the color is inconsistently applied to the bullet. That is sometimes the bullet will be colored and sometimes it won't. This occurs infrequently and I can find no pattern to determine when it will occur.

  • If an image is the last element in the htmlText the component may incorrectly measure the scroll height of the component. Consequently the scroll bar may not appear even though the image extends beyond the components bottom edge. This typically occurs when the component without the image wouldn't need to scroll. You may be able to work around this by including some text after the image and coloring the text the same as the background (i.e. <p><font color='#FFFFFF'>...</font></p>).

  • If you want an image to occupy the entire width of the component you can try to force the text not wrap by setting a hspace value. But the component will always have a single character per line regardless of whether the characters are visible or not. Therefore it will appear that some characters are missing from the paragraph that follows the image. The workaround for this problem is the same as the previous problem. Except you need a character for each line the image requires.


Curious to hear any other htmlText problems you've found and even better any solutions you may have.

16 comments:

Tracy said...

Hi GeekGlue

I am also having TextArea htmlText trouble with the 'img' tag.

In my case I load html text into my textarea. I then edit the text & try to set a new htmlText value to the textarea, which results in the following exception:

rror #2025: The supplied DisplayObject must be a child of the caller.
at flash.text::TextField/set htmlText()

What I think is happening is that the player is struggling to delete the old image object, possibly because it isnt an explicit child of the textarea.

I don't have a work around for it, but found a brute force method by creating a whole new textarea. I haven't tried this yet:
http://www.actionscript.org/forums/showthread.php3?t=85011

Cheers
Tracy

geekglue said...

Hi Tracy. I had exactly the same problem and came up with exactly the same hack solution. How taunting it is to be able to render html so simply in Apollo and for it to be so difficult in the browser.

Ted said...

Yea i've been investigating this for a while.. What's extra curious is the flex UITextField ( which is a pretty thin wrapper around the flash TextField component ) doesn't produce this issue. Actually, it just now dawns on me: this bug only happens when the TextField is trying to auto-size ( you can also work around by explicitly setting the height of the text field if you know it ) -- and the flex UITextField does its own Flex-agical measuring stuff.

geekglue said...

Thanks for this input Ted. This raises quite a few interesting options to overcome these problems. A possible solution is to make a new component that extends UITextField or to extend TextField with an improved measuring engine. I think I will need to find some time to research this further.

vinay said...

I have been working with html text
for quite sometime without any sucess

whenever I use a image tag it will always appear in a new line

what should we do so that we have such a result
How are :) tell me

Work around will really be helpfull

geekglue said...

Hi Vinay,

you can get text to wrap images by including align settings within the img element. Exactly the same as if the image was within html. How well this works will depend on the space available and the image size. I've definitely had this working. The problems I've had relate more to multiple images and links. Good luck getting this working.

Anonymous said...

(ifrozen (at google))

Hey, my problem with htmlText is even more interesting... I'm dealing with <img&rt; tags too... but it's not just newline, its "top of each other"... I have alpha .5 or so on the TextArea using htmlText and want to have 4 pictures right near each other... The 1st pic is correct, the other 3 are being rendered to THE TOP OF EACH OTHER (I can see it because of alpha)...

do anyone know any solution for it?

geekglue said...

ifrozen,
that is a pretty crazy (and frustrating I'd imagine) outcome. Don't have any idea how to get round this. We were able to limit ourseleves to a single image. I assume it's in a TextArea because you need editability. If not you could try creating your own Text component based on Canvas and breaking the htmlText into an array of strings and images then laying them out dynamically. Pretty desperate approach but the only other option I can imagine is diving into the Text components and see if you can find the bug causing these weird options.

Gabriele said...

I've been fighting with the miscolored bullet problem (<LI><FONT color="#0000ff">foo</FONT></LI> in which the bullet gets sometimes colored as blue), and I think I've found a solution.
Before the LI tag is closed, add a single space character surround by a FONT tag with the bullet color, as in:
.....<FONT color="#000000"> </FONT></LI>

This seems to work for me!

geekglue said...

Gabriele,

how did you come up with such a crazy hack. It definitely would have saved me a few times. Thanks.

Niko said...

If I set the alpha property of a textarea, the alpha gets wrongly applied to any htmltext images also. How can I work around this?

geekglue said...

Hi Niko,

my understanding is that the htmlText includes any images within it. Hence an alpha value on the text area should effect the text and the image. I can't imagine there is an easy way around that.

Anonymous said...

Another bug rendering lists in Flash/Flex... Try with 72px fontsize for the text and the bullets overlap each list item. Solution?

abhishek said...

hello frnd,
i'm showing 2images with their text titles, but both titles are displaying in front of 1st image and then below it 2nd image is displaing,
is any suggetion to solve this?
abhishekchess1@gmail.com

geekglue said...

abhishek,

it is my experience that trying to display more than one image using htmlText will nearly always be a problem.

The only real solution is a comprehensive HTML component for Flex. I know there is a third-party component (or library) available for Flash. If your needs are fairly simple you could probably construct a simple HTML component that adds textfields and images seperately as required. But even this simple task can get complicated quickly when you require text wrapping around your image.

nephiw said...

I have discovered that you can perfectly imitate bulleted lists in flash CS3 using the block indent, the bullet character, and regular expressions. Except with the imitation, you can decorate your bullets, and have complete control of symbol and color.

The problems that I discovered was that you have to calculate the block indent as it is presented in pixels, which changes per font and display. Fortunately this can be done using the textfield.textWidth property. I have source code that can help anyone trying to fix the bullet coloring of dynamically created bulleted lists.