Search code examples
htmlflashpropertiesformattingjsfl

How to get the HTML format string from a TextField in JSFL


How can I get access to the *.htmlText property of a TextField on the timeline? I'm looking for something that can return all the formatting information just like it does in ActionScript 3.0 at runtime.

Example:

<TEXTFORMAT LEADING="2">
    <P ALIGN="CENTER">
        <FONT FACE="Verdana"
              SIZE="64"
              COLOR="#FF0000"
              LETTERSPACING="0"
              KERNING="1">
            <B>This is a </B>
            <FONT COLOR="#000000">
                <B>bold</B>
                <FONT SIZE="33">
                    <B>example</B>
                </FONT>
            </FONT>
        </FONT>
    </P>
</TEXTFORMAT>

Solution

  • Had to write it up from scratch! So here it is:

    /*
    
      Usage:
        var labelHTML = HTMLUtils.convertToHTML( someLabel );
        trace("The HTML of the selected label in the IDE is:\n" + labelHTML);
    
    */
    
    var _TAG_TEMPLATE = "<$0$1>$2</$0>";
    
    HTMLUtils = {
    
        convertToHTML: function(pTextField) {
            var runs =  pTextField.textRuns,
                run, content, output,
                leading;
    
            this.rootNode = new HTMLElement("ROOT");
    
            for (var r=0, rLen=runs.length; r<rLen; r++) {
                run = runs[r];
                content = run.characters;
    
                this.convertAttrsToHTML(run.textAttrs, content);
            }
    
            this.currentTextFormat = null;
    
            return this.rootNode.toHTML(true);
        },
    
        convertAttrsToHTML: function(pTextAttrs, pContent) {
            var contentLines =  pContent.split("\r");
            var masterFontNode;
    
            if(!this.currentTextFormat) {
                masterFontNode = this.createNewTextFormat( pTextAttrs );
            } else {
                masterFontNode =    this.currentTextFormat.childAt(0,0);
            }
    
            var fontNode = new HTMLFont();
            fontNode.addNode( new HTMLText( pContent ) );
            this.assignFontAttributes( fontNode, pTextAttrs );
    
            masterFontNode.addNode( fontNode );
    
            //trace( pTextAttrs.toTrace() );
    
            this.currentTextFormat.attributes.leading = String(pTextAttrs.lineSpacing);
            this.currentTextFormat.children[0].attributes.align = String(pTextAttrs.alignment);
    
            if(contentLines.length>1) {
                this.currentTextFormat = null; //
            }
        },
    
        createNewTextFormat: function( pTextAttrs ) {
            this.currentTextFormat =    new HTMLElement("TEXTFORMAT");
            this.rootNode.addNode(this.currentTextFormat);
    
            var paragraph = new HTMLElement("P");
            this.currentTextFormat.addNode( paragraph );
    
            var fontNode =  new HTMLFont();
            paragraph.addNode( fontNode );
    
            this.assignFontAttributes( fontNode, pTextAttrs );
    
            return fontNode;
        },
    
        assignFontAttributes: function( pFontNode, pTextAttrs ) {
            pFontNode.attributes.face = String(pTextAttrs.face);
            pFontNode.attributes.size = String(pTextAttrs.size);
            pFontNode.attributes.letterSpacing = String(pTextAttrs.letterSpacing);
            pFontNode.attributes.color = String(pTextAttrs.fillColor);
            pFontNode.isBold =      pTextAttrs.bold;
            pFontNode.isItalic =    pTextAttrs.italic;
        }
    };
    
    
    HTMLElement =   Class.extend({
        init: function( pName ) {
            this.name = pName;
            this.children = [];
            this.parent = null;
            this.attributes =   {};
        },
    
        clone: function(pOnlyThis) {
            var theClone =  new HTMLElement( this.name );
            theClone.attributes = this.attributes.copy();
            return theClone;
        },
    
        addNode: function(pNode) {
            this.children.push(pNode);
            pNode.parent = this;
    
            return pNode;
        },
    
        childAt: function() {
            var current = this;
            for (var a=0, aLen=arguments.length; a<aLen; a++) {
                var index = arguments[a];
    
                current = current.children[index];
            }
    
            return current;
        },
    
        parentOfType: function(pName) {
            var currentNode =   this.parent;
            while(currentNode && currentNode.name!=pName) {
                currentNode = currentNode.parent;
            }
    
            return currentNode;
        },
    
        childrenHTML: function() {
            var theHTML =   "";
            var theChildren =   this.children,
                theChild;
    
            for (var c=0, cLen=theChildren.length; c<cLen; c++) {
                theChild =  theChildren[c];
                theHTML += theChild.toHTML();
            }
    
            return theHTML;
        },
    
        toHTML: function(pInnerOnly) {
            var theHTML =   this.childrenHTML();
    
            if(pInnerOnly) {
                return theHTML;
            }
    
            var theAttributes = [];
            var theAttrProperties = this.attributes.getProperties();
    
            for(var a=0, aLen=theAttrProperties.length; a<aLen; a++) {
                var attr =      theAttrProperties[a];
                var attrBIG =   attr.toUpperCase();
                var attrValue = this.attributes[attr];
                theAttributes.push(attrBIG + "=\"" + attrValue + "\"");
            }
    
            if(theAttributes.length==0) {
                theAttributes = "";
            } else {
                theAttributes = " " + theAttributes.join(" ");
            }
    
            return _TAG_TEMPLATE.inject(this.name, theAttributes, theHTML);
        }
    });
    
    HTMLFont = HTMLElement.extend({
        init: function() {
            this._super("FONT");
        },
        toHTML: function(pInnerOnly) {
            var parentFont = this.parentOfType("FONT");
            if(parentFont) {
                //Find differences in attributes:
                var parentAttrs =   parentFont.attributes;
                var myAttrs =       this.attributes;
    
                var theAttrProperties = myAttrs.getProperties();
                var differentAttrs =    [];
    
                for (var a=0, aLen=theAttrProperties.length; a<aLen; a++) {
                    var attr =          theAttrProperties[a];
                    var attrValue =     myAttrs[attr];
                    var parentValue =   parentAttrs[attr];
    
                    if(parentValue==null || parentValue==attrValue) {
                        continue;
                    }
    
                    differentAttrs.push( attr.toUpperCase() + "=\"" + attrValue + "\"");
                }
    
                var theHTML =   this.childrenHTML();
    
                if(this.isBold) { theHTML = "<B>" + theHTML + "</B>"; }
                if(this.isItalic) { theHTML =   "<I>" + theHTML + "</I>"; }
    
                if(differentAttrs.length==0) {
                    return theHTML;
                } else {
                    differentAttrs = " " + differentAttrs.join(" ");
                }
    
                return _TAG_TEMPLATE.inject(this.name, differentAttrs, theHTML);
            }
            return this._super(pInnerOnly);
        }
    });
    
    HTMLText =  HTMLElement.extend({
        init: function( pContent ) {
            this._super("TEXT");
            this._content = pContent;
        },
        toHTML: function() {
            return this._content;
        }
    });
    

    NOTE: For the sections that are defining Classes and extending them, you can obtain that functionality from this site: John Resig's Inheritance Script for JavaScript - based on Prototype. It's a great script to have at the core of any JavaScript based language, it simplifies OOP so much!