Showing posts with label html. Show all posts
Showing posts with label html. Show all posts

Wednesday, October 27, 2010

Displaying Html text in Labels

Displaying html content inside Flex labels is not as straight forward as it was in Flex 3 by simply setting the htmlText property. Here are the 3 Spark controls used for displaying text:
  • Label - lightweight plain text only
  • RichText - as the name says it provides support for rich text.
    Also allows html content to be imported (anchor tags <a> don't work)
  • RichEditableText - provides the same rich text support as the RichText control.
    Allows editing and anchor html tags work properly
Here is a list of the supported HTML tags: <div>, <p>, <a>, <span>, <img>, <br>.

As noted above, if you want to use anchor <a> tags, you must use a RichEditableText control. In this case you'd most likely want to also set the editable="false" property.
The anchor href property can be set to a relative path like
<a href="index.html">index</a>
Or an absolute one like
<a href="http://google.com" target="_blank">google</a>
Note that you can set the target property to control whether the link is opened in a new window or not.
If you want to listen for when the user clicks on an anchor it is possible, but involves a lot more work. Basically you import the html string into a TextFlow object. Then you iterate through all the child elements until you find the LinkElement (which represents the anchor tag), and then add a FlowElementMouseEvent.CLICK event listener.

Here is some sample code that I use to achieve this:
/**
 * Converts the html string (from the resources) into a TextFlow object
 * using the TextConverter class. Then it iterates through all the 
 * elements in the TextFlow until it finds a LinkElement, and adds a 
 * FlowElementMouseEvent.CLICK event handler to that Link Element.
 */
public static function addLinkClickHandler(html:String, 
        linkClickedHandler:Function):TextFlow {
  var textFlow:TextFlow = TextConverter.importToFlow(html, 
    TextConverter.TEXT_FIELD_HTML_FORMAT);
  var link:LinkElement = findLinkElement(textFlow);
  if (link != null) {
    link.addEventListener(FlowElementMouseEvent.CLICK, 
          linkClickedHandler, false0true);
  else {
    trace("Warning - couldn't find link tag in: " + html);
  }
  return textFlow;
}

/**
 * Finds the first LinkElement recursively and returns it.
 */
private static function findLinkElement(group:FlowGroupElement):LinkElement {
  var childGroups:Array = [];
  // First check all the child elements of the current group,
  // Also save any children that are FlowGroupElement
  for (var i:int = 0; i < group.numChildren; i++) {
    var element:FlowElement = group.getChildAt(i);
    if (element is LinkElement) {
      return (element as LinkElement);
    else if (element is FlowGroupElement) {
      childGroups.push(element);
    }
  }
  // Recursively check the child FlowGroupElements now
  for (i = 0; i < childGroups.length; i++) {
    var childGroup:FlowGroupElement = childGroups[i];
    var link:LinkElement = findLinkElement(childGroup);
    if (link != null) {
      return link;
    }
  }
  return null;
}

A simple control that I've created and use frequently is called HtmlLabel which extends the RichEditableText class to provide simple support for html text:
<?xml version="1.0" encoding="utf-8"?>
<s:RichEditableText xmlns:fx="http://ns.adobe.com/mxml/2009"
  xmlns:s="library://ns.adobe.com/flex/spark"
  xmlns:mx="library://ns.adobe.com/flex/mx"
  focusEnabled="false"
  selectable="false"
  editable="false">

  <fx:Script>
    <![CDATA[
      import flashx.textLayout.conversion.TextConverter;

      override public function set text(value:String):void {
        super.textFlow = TextConverter.importToFlow(value, 
          TextConverter.TEXT_FIELD_HTML_FORMAT);
      }
    ]]>
  </fx:Script>

</s:RichEditableText>

Wednesday, May 27, 2009

Blogger source code syntax highlighting

If you've read my last few blog posts you might have noticed that my code snippets now have syntax highlighting that looks similar to Flex Builder.

I've found many people asking how to get syntax highlighting to work on source code that is pasted into Blogger. Most solutions use CSS and Javascript to accomplish that with varying levels of success. I've chosen to go a different route and am using a parser to turn ActionScript text into html which I then paste right into a blog post (under "Edit Html").

I'm using a slightly modified version of this amazing free parser called Java2Html created by Markus Gebhard (GNU License). It is a Java Swing application (or Applet) that takes in input text and outputs html which you can easily copy and paste into a blog. The original version (which I believe is last updated in 2006) has three different style options - Eclipse, Kawa, and Monochrome. I've added a fourth option FlexBuilder that uses the default syntax highlighting styles found in ActionScript.

If you want to try out my version, I've posted the applet here: java2html

Here are some of the options you can use (in the panel on the right side):
  • Style - choose one of the 4 code styles (use FlexBuilder for ActionScript)
  • Line numbers - shows line numbers in the html
  • Table border - draws a 2 pixel gray border around the code block
  • Background color - if checked then a white background color is set on the code block
  • Include <html> and <body> tags - if false then the output html doesn't inclde the <html> and <body> tags, only the content.
  • Use <br> at the end of lines - if false then the html won't contain <br> tags
  • Include new lines ("\n") - if false then the html won't contain new line characters. Turn this off if you want to paste your code into Blogger since it treats new lines as breaks!
  • CSS Class - by default the code block is wrapped inside a <div class="java"> tag. This option configures the class="java" part.

  • Again I can't take much credit for this. All I've really done is add a few of the options mentioned above and changed the parser slightly to work with ActionScript keywords (such as function, var, etc).

    Here is an example of a very simple code snippet with and without styling:
    private function get string():String {
    var str:String = "String";
    return str;
    }
    private function get string():String {
        var str:String = "String";
        return str;

                

    One more thing, I haven't tested the various Target options, I only use the default "XHTML 1.0 Transitional (inlined fonts)".