Question
how to preserve whitespaces within span-elements?
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>
<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>
