Skip to main content
Participating Frequently
April 19, 2011
Question

how to preserve whitespaces within span-elements?

  • April 19, 2011
  • 1 reply
  • 1613 views
I have a TextArea where user can enter text and modify  part of it to superscript, subscript, etc.
To make my point / explain my question, I have a  simplistic situation where the same text is displayed in RichText.
The issue I'm facing is that, as soon as you change some  text to superscript, subscript, etc, they become separate span-element and when  you do any xml processing on the updated text, the whitespace within  span-elements get stripped away. That means, you cannot have any spaces after a  superscript or a subscript!
So, when I type "H2SO4 is for sulfuric acid" in TextArea  and then convert '2' and '4' to subscript, in the RichText, space between the  chemical formula and 'is' goes away.
This happen as I convert string back to XML using the  following:
var xmlData:XML = new XML(stringData);
I've played with XML.ignoreWhitespace = false but that  doesn't solve the issue.
Any idea how I can preserve whitespaces within  span-elements?
I've spent half-a-day on this and could use some  help!
Thanks!

=======
<?xml version="1.0" encoding="utf-8"?>
<s:Application
    xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    width="500"
    >
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
    <s:layout>
        <s:VerticalLayout
            horizontalAlign="left"
            />
    </s:layout>
    <s:TextArea
        id="textInput"
        width="100%"
        fontFamily="Verdana"
        fontSize="14"
        textFlow="{textInputTextFlow}"
        change="textInputChangeHandler(event)"
        />
    <s:Button
        id="superscriptButton"
        label="superscript"
        click="superscriptButtonClickEventHandler(event)"
        />
    <s:RichText
        id="textDisplay"
        width="100%"
        fontFamily="Verdana"
        fontSize="14"
        textFlow="{textDisplayTextFlow}"
        />

    <fx:Script>
        <![CDATA[
            import flashx.textLayout.elements.TextFlow;
            import flashx.textLayout.formats.TextLayoutFormat;
            import flashx.textLayout.formats.WhiteSpaceCollapse;
            import flashx.textLayout.formats.TextAlign;
            import flashx.textLayout.formats.TextDecoration;
            import flashx.textLayout.formats.TextLayoutFormat;
            import flashx.textLayout.formats.BaselineShift;
            import flash.text.engine.Kerning;
            import spark.utils.TextFlowUtil;

            private var stringData:String;
           
            [Bindable]
            private var textDisplayTextFlow:TextFlow;
            [Bindable]
            private var textInputTextFlow:TextFlow;
           
            protected function textInputChangeHandler(event:Event):void {
                updateTextDisplay();
            }
           
            private function updateTextDisplay():void {
                // get text out of textflow
                var xmlData:XML = TextFlowUtil.export(textInput.textFlow);
                trace(xmlData);
               
                // I do some xml processing here
               
                // convert xml back to string to save in the database
                stringData = xmlData.toXMLString();
                trace(stringData);
               
                // save data in database
               
               
                // simulate getting data back from database
                getDataBackFromDB();
            }
           
            private function getDataBackFromDB():void {
                var xmlData:XML = new XML(stringData);
                textDisplayTextFlow =
                    TextFlowUtil.importFromXML(
                        xmlData,
                        flashx.textLayout.formats.WhiteSpaceCollapse.PRESERVE
                    );
               
            }
           
            private function superscriptButtonClickEventHandler(event:Event):void {
                // get the formating information of the selected text
                var textLayoutFormat:TextLayoutFormat =
                    textInput.getFormatOfRange(
                        null,
                        textInput.selectionAnchorPosition,
                        textInput.selectionActivePosition
                    );
               
                // change the format to superscript
                textLayoutFormat.baselineShift = flashx.textLayout.formats.BaselineShift.SUPERSCRIPT;
                textLayoutFormat.kerning = flash.text.engine.Kerning.ON;
               
                // apply the modified format to the selected text
                textInput.setFormatOfRange(
                    textLayoutFormat,
                    textInput.selectionAnchorPosition,
                    textInput.selectionActivePosition
                );
               
                // set focus to the text area
                textInput.setFocus();
               
                updateTextDisplay();
            }
                       
        ]]>
    </fx:Script>
</s:Application>

This topic has been closed for replies.

1 reply

Adobe Employee
April 19, 2011

The space missed in RichText, right? Maybe it's a flex bug or your mistake somewhere.

Please use pure TLF code as follows, which works for sure.

var textFlow:TextFlow = new TextFlow();
var p:ParagraphElement = new ParagraphElement();
var span:SpanElement = new SpanElement();
span.text = "H2SO4 is for sulfuric acid";

p.addChild(span);
textFlow.addChild(p);
           
textFlow.interactionManager = new EditManager(); //Maybe you don't need this line in flex
var textLayoutFormat:TextLayoutFormat = new TextLayoutFormat();
textLayoutFormat.baselineShift = flashx.textLayout.formats.BaselineShift.SUBSCRIPT;


(textFlow.interactionManager as IEditManager).applyFormat(textLayoutFormat,null,null, new SelectionState(textFlow,1,2));
(textFlow.interactionManager as IEditManager).applyFormat(textLayoutFormat,null,null, new SelectionState(textFlow,4,5));

DilipShahAuthor
Participating Frequently
April 19, 2011

Jin-Huang,

Thanks a lot for taking time out to find solution to my problem!

xml processing that I was doing to prepare input for

TextFlowUtil.importFromXML() function was removing all the whitespaces.

So, I switched to TextConverter.importToFlow(textInputData,

TextConverter.TEXT_LAYOUT_FORMAT), where textInputData is a String. Since

there is no xml processing, all the whitespaces are preserved!

Dilip

Adobe Employee
April 19, 2011

Flex buy in TLF source code, and create many new functions to call TLF functions.

Frankly speaking, I have no idea about how they call TLF exactly.

Thank you too.