Flex TextArea htmlText with stylesheet click bug
This bug is hard to describe, but easily reproduced with the bottom code. Just copy, paste, and compile+run in Flex 3 and you'll see the problem. Anyone know of a work around?
Edit: Here is a link to a running demo: http://shiinaringo.se/hosted/flex/textarea-bug/HtmlTextBug.html In the demo, the default color of TextArea is set to red.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="horizontal" applicationComplete="applicationComplete(event);">
<mx:Script>
<![CDATA[
import mx.events.FlexEvent;
private function applicationComplete(event:Event):void {
var styles:String = "a:hover { color: #6666ff; text-decoration: underline; } a { color: #0000ff; }";
var ss:StyleSheet = new StyleSheet();
ss.parseCSS(styles);
textGreenStylesheet.styleSheet = ss;
}
private function enteredText(event:FlexEvent):void {
textDefault.htmlText = event.currentTarget.text;
textGreen.htmlText = event.currentTarget.text;
textGreenStylesheet.htmlText = event.currentTarget.text;
}
]]>
</mx:Script>
<mx:VBox height="100%" width="400" horizontalAlign="center">
<mx:Panel width="250" height="200" layout="absolute" title="TextArea A. Default colored text">
<mx:TextArea id="textDefault" condenseWhite="true" width="100%" height="100%" x="0" y="0">
<mx:htmlText>
<![CDATA[
This text has the default text color of the TextArea control.
]]>
</mx:htmlText>
</mx:TextArea>
</mx:Panel>
<mx:Panel width="250" height="200" layout="absolute" title="TextArea B. Green text">
<mx:TextArea id="textGreen" condenseWhite="true" width="100%" height="100%" x="0" y="0" color="green">
<mx:htmlText>
<![CDATA[
This text has the text color set to green
]]>
</mx:htmlText>
</mx:TextArea>
</mx:Panel>
<mx:Panel width="250" height="200" layout="absolute" title="TextArea C. Green text + stylesheet">
<mx:TextArea id="textGreenStylesheet" condenseWhite="true" width="100%" height="100%" x="0" y="0" color="green">
<mx:htmlText>
<![CDATA[
This text has the text color set to green, and also uses a stylesheet to make <a href="http://example.com">links</a> blue and underlined when hovered.
]]>
</mx:htmlText>
</mx:TextArea>
</mx:Panel>
<mx:TextInput x="69" y="282" width="207" enter="enteredText(event);"/>
</mx:VBox>
<mx:VBox height="10开发者_Go百科0%" width="200">
<mx:Text width="166" text="We have three TextArea controls. The top uses default text color, the middle one uses defined green text color, the bottom one also uses green color, but also uses a stylesheet to define some custom coloring of A tags." height="232"/>
<mx:Text width="166" text="To reproduce the problem, first try to just enter new text in the input field in the bottom, and press enter. The text in the three boxes will update. Notice that the colors and other styles don't change in any of the three boxes. But when you click once inside textarea C, then enter new text in the input field and hit enter, you'll notice that the color and font is lost in textarea C. Bug?" height="232"/>
</mx:VBox>
</mx:Application>
Basically, StyleSheet
and TextFormat
doesn't go together in a flash textfield.
Following is my guestimate of what might be happening:
The color="green"
will become part of the defaultTextFormat of the internal TextField of the TextArea and will be applied to the text well before applicationComplete
is fired. You can verify this by tracing trace(textGreenStylesheet.htmlText);
in the application complete handler (before you set the stylesheet). Here is what I got:
<TEXTFORMAT LEADING="2"><P ALIGN="LEFT"><FONT FACE="Verdana" SIZE="10" COLOR="#008000" LETTERSPACING="0" KERNING="0">This text has the text color set to green, and also uses a stylesheet to make <A HREF="http://example.com" TARGET="">links</A> blue and underlined when hovered. </FONT></P></TEXTFORMAT>
Now when you apply the stylesheet, the color remains unchanged (green) as the stylesheet do not specify any color for the whole text.
When you click on the TextArea, I believe flex recalculates properties of it (may be click triggers an invalidation - I am not sure what's happening underneath). While doing this, compiler finds that a stylesheet has been applied and ignores the color="green"
attribute. Now, these new properties are applied only when the text/htmltext property is changed (later by hitting enter). So unless you click or somehow trigger an invalidation of textarea, it retains the default color specified before applying the stylesheet.
If you add .yellow{color:#ffff00;}
to the stylesheet and enclose some text in the third text area with <span class="yellow">some text</span>
tags, you can see that the enclosed text retains yellow color whether you click on it or not.
Here's what I'm doing to resolve this. It's a big hack, but it does work.
import flash.events.Event;
import flash.text.TextFormat;
import mx.controls.Text;
import flash.text.StyleSheet;
import mx.core.mx_internal;
import mx.events.FlexEvent;
public class SupText extends Text
{
use namespace mx_internal;
public var linkColor:String = "#355EBF";
private var format:TextFormat;
public function SupText()
{
super();
this.addEventListener(FlexEvent.CREATION_COMPLETE, function(e:Event):void { setStyleSheet(); });
}
override public function set htmlText(value:String):void {
if (format != null) {
//glorious hack for style problem
textField.styleSheet = null;
textField.defaultTextFormat = format;
setStyleSheet();
}
super.htmlText = value;
if (textField.defaultTextFormat.font != "Times New Roman") {
format = textField.defaultTextFormat;
}
}
public function setStyleSheet():void {
var ss:StyleSheet = textField.styleSheet;
if(textField.styleSheet == null){
textField.styleSheet = new StyleSheet();
}
textField.styleSheet.setStyle("sup", { display: "inline", fontFamily: "ArialSup", fontWeight:"normal"});
textField.styleSheet.setStyle("a:link", { textDecoration: "none", color: linkColor });
textField.styleSheet.setStyle("a:hover", { textDecoration: "underline" });
textField.styleSheet.setStyle("a:active", { textDecoration: "underline" });
}
}
}
Can you assign the text directly to the .text property?
private function enteredText(event:FlexEvent):void
{
textDefault.text = event.currentTarget.text;
textGreen.text = event.currentTarget.text;
textGreenStylesheet.text = event.currentTarget.text;
}
精彩评论