TLF 2.0 Changes: SubParagraphGroupElements and typeName applied to TextFieldHTMLImporter and CSSFormatResolver

Changes made to the TLF 2.0 are being used to improve theTextFieldHTML importer. First note that this importer is intended for compatibility with the TextField.htmlText property. It’s not intended to be a general purpose HTML importer.

The SubParagraphGroupElement

In TLF 1.1 and earlier There was no equivalent of HTML’s nested spans. TLF 2.0 adds the SubPargraphGroupElement (in markup <g>). SubParagraphGroupElements can be a child of a ParagraphElement, LinkElement, TCYElement or another SubParagraphGroupElement. These are useful for creating nested text elements that share some formatting.

The FlowElement typeName property

All TLF elements now have a typeName property. This property is initialized to the string used when exporting TLF markup. This table shows the default class names and default typeNames for new instances of that class. Note that typeName is a read/write property and clients may manipulate it.

DivElement div
InlineGraphicElement img
LinkElement a
ListElement list
ListItemElement li
ParagraphElement p
SpanElement span
SubParagraphGroupElement g
TabElement tab
TextFlow TextFlow

Note that TLF always converts TabElement and BreakElement elements into the tab and newline character so normally they disappear from the TextFlow and are left off this table.

HTMLImporter Changes to Support Unknown Tags

The HTML importer now preserves unrecognized element tags, for example <foo>Text</foo>, by creating a TLF element and setting its typeName to be an element of that tag. The goal of this is to allow importing of HTML with custom tags and connecting a stylesheet with typename selectors that match through an IFormatResolver. When the importer encounters an unknown tag the rule it uses is if the unknown tag has one child element that child gets its typeName set to the unknown tag. If two or more elements are created than a <div> or a <g> as the parent of the children with its typeName set.

For example :

Import this HTML:
<foo>Text<foo>
to create TLFMarkup:
<p typeName=”foo”><span>Text</span></p>

Import this HTML:
<foo><p>Hello</p>World</foo>
to create TLFMarkup:
<div typeName=”foo”><p><span>Hello</span></p><p><span>World</span></p></div>

Import this HTML:
<p><foo><b>bold</b>normal</foo></p>
to create TLFMarkup::
<p><g typeName=”foo”><span fontWeight=”bold”>bold</span><span>normal</span></g></p>

Import this HTML:
<p><foo>asdf</foo></p>
to create TLFMarkup::
<p><span typeName=”foo”>asdf</span></p>

Warning: TLF’s HTMLExporter converts all tag names to uppercase. So typeName=”foo” exports to <FOO>. The TLF markup exporter preserves case as shown above.

SubPargraphGroupElement and the HTML Importer

Previously the importer was unable to preserve nested span elements with formatting. For example:
<font size=”18″><span>Normal <font color=”#0000ff”>BLUE</font> Normal</span></font>

In 1.0 this content created 3 spans with different formatting like this:
<p><span fontSize=”18″>Normal </span><span color=”#0000ff” fontSize=”18″>BLUE</span><span fontSize=”18″> Normal</span></p>

In 2.0 this content creates a group with three span elements:
<p><g fontSize=”18″ typeName=”span”><span>Normal </span><span color=”#0000ff”>BLUE</span><span> Normal</span></g></p>

This example becomes even more interesting if the <span> is changed to a <foo> and CSS formatting is connected.

typeName and CSSFormatResolver

This can all be used to improve the connection of CSS stylesheets to a TextFlow using the IFormatResolver interface. This was originally described in an older blog post.

I’ve updated the Flex based CSSFormatResolver example to leverage the typeName property as well as including a demonstration of a styled “foo” tag. It’s attached here. Note: You will have to adjust the library paths.

For those requesting a non-Flex version of CSSFormatResolver I attached a sample here. Note: You will have to adjust the library paths.

11 Responses to TLF 2.0 Changes: SubParagraphGroupElements and typeName applied to TextFieldHTMLImporter and CSSFormatResolver

  1. Colin says:

    I can’t compile your files, for the flash builder says the FlowElement does’t have the typeName property….

    • Richard Dermer says:

      You’ll need the latest TLF version from http://sourceforge.net/projects/tlf.adobe/files/ You can use this directly for the pure AS3 example – note I used an Embed metadata tag which does require Flex for mx.core.ByteArrayAsset. Make sure that there are no other textLayout.swcs in your build path. If you are using Flex 4.1 there is an earlier blog post about how to update Flex r.1 to work with TLF 2.0. If you are using Flex 4.5Hero beta this swc should drop in though I haven’t tried it.

  2. Peter says:

    I develop with Flash Professional CS5, not FLEX or Flash Builder. I have not found it stated plainly whether TLF 2.0 is something that works with Flash. Am I wasting my time on this with Flash? Will TLF 2.0 only work with FLEX?

  3. Alan Stearns says:

    TLF 2.0 will be included in the next version of Flash Professional.

    Until then you should be able to use the TLF 2.0 SWC in actionscript code in Flash Pro CS5 if you do not have any TLF-based text in your FLA – the two versions of TLF don’t mix.

  4. JP says:

    Hello,
    i’m just trying to test TLF 2.0 in flash CS5 but i have some problem (i have upgrade the textLayout.swc)
    If i create textflow issue from html tags like this :

    myHtml:XML=new XML(”);
    myTxtFlow=TextConverter.importToFlow(myHtml,TextConverter.TEXT_FIELD_HTML_FORMAT);
    myTLFTextField.textFlow=myTxtFlow

    but if i trace the tlfMarkup of myTLFTextField, it seems to ignore div “foo” and id…

    Is it a flash bug ?

    Thank’s a lot for your answer,

    JP

  5. JP says:

    Error in my previous message : the quote seems to bug in the message
    We have to read :
    myHTML:XML=new XML(“”)

    Thank’s,

    JP

    • Richard Dermer says:

      TLFTextField in Flash Pro CS5 is using TLF 1.1. The next version of Flash Pro will use TLF 2.0 in the TLFTextField implementation.

  6. JP says:

    Ok, thank’s.
    So, i have to use direct textflow actionscript (without TLTTextField) in order to use the 2.0 script ?
    But how can I see the render of my textflow without tlfMarkup property ?
    If i try myTextFlow.toString(), I have a compilation Error (in French sorry):

    1061 : Appel à la méthode toString peut-être non définie, via la référence de type static flashx.textLayout.elements:TextFlow.

    Thank’s,

    JP

  7. BP says:

    Hi,

    Ive downloaded the latest release and updated the library path ( in FDT), but I keep getting the flowElement typeName property error.

    Is there any workaround for this?

    Thanks,
    BP

  8. David says:

    Hi,

    I think there is a small typo in the CSSFormatResolver.as file included with the non-Flex version of the examples.

    In the “resolveUserFormat” method for the “flowElem.styleName” if statement, the code goes like this…

    foundStyle = _styleSheet.getStyle(“.”+flowElem.styleName);
    if (foundStyle)
    {
    foundStyle = foundStyle[userStyle];
    if (propStyle !== undefined)
    return propStyle;
    }

    I think it should be…
    foundStyle = _styleSheet.getStyle(“.”+flowElem.styleName);
    if (foundStyle)
    {
    propStyle = foundStyle[userStyle];
    if (propStyle !== undefined)
    return propStyle;
    }

    where ‘foundStyle’ has been changed to ‘propStyle’ right before the ‘if (propStyle !== undefined)’ statement