Textflow losing spaces during export->XML->String->XML->import operation
Hi all,
I have a perplexing problem that probably has a very simple solution. We have a workflow in which a TextFlow is edited by the user, possibly introducing new spans with different formatting (e.g. bold). At the end of the edit operation, the TextFlow is exported to XML and stored, possibly in a file. So far, so good. Then later on the file is read back in, and the TextFlow regenerated by importing the XML string. The problem is that the imported TextFlow loses leading and trailing spaces on spans. I have put together a toy example below with two TextFlows. The first just tries to import an XML with leading and trailing spaces on one of the spans.
The second imports a single span, and then attaches an edit manager which responds to the CTRL key by putting the selected span in bold, however I have mimiced our workflow in this operation, so the TextFlow is exported, converted to a string, converted back to XML and imported to a new TextFlow. You can see that any leading or trailing spaces on the selected span are eaten up.
I have tried every combination of XML.ignoreWhitespace=true and WhiteSpaceCollapse.PRESERVE attributes I can think of, and I either get no change or (in the case of XML.ignoreWhitespace) a whole lot of unwanted line breaks inserted.
Any suggestions gratefully received!
Darryl.
--> TLFSpanProblem.mxml <----
<?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" minWidth="955" minHeight="600"
creationComplete="init(event)">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<fx:XML id="tfxml" format="e4x" xmlns="">
<TextFlow color="#000088" fontFamily="Times New Roman" fontSize="24.48" fontStyle="normal" fontWeight="normal" renderingMode="cff" textAlign="left" verticalAlign="top" whiteSpaceCollapse="preserve" version="2.0.0" xmlns="http://ns.adobe.com/textLayout/2008">
<p>
<span fontSize="24.48">Contents ui</span>
<span fontSize="24.48" fontWeight="bold"> magna velit consequat, lobortis iriure autem augue </span>
<span fontSize="24.48">duis exerci blandit esse laoreet ex eros, adipiscing aliquip, ut, vel eum. Vero consectetuer dolor feugait dolore lobortis delenit nibh eu, te et in, dolore.</span>
</p>
</TextFlow>
</fx:XML>
<fx:XML id="tfxml2" format="e4x" xmlns="">
<TextFlow color="#000088" fontFamily="Times New Roman" fontSize="24.48" fontStyle="normal" fontWeight="normal" renderingMode="cff" textAlign="left" verticalAlign="top" whiteSpaceCollapse="preserve" version="2.0.0" xmlns="http://ns.adobe.com/textLayout/2008">
<p>
<span fontSize="24.48">Contents ui magna velit consequat, lobortis iriure autem augue duis exerci blandit esse laoreet ex eros, adipiscing aliquip, ut, vel eum. Vero consectetuer dolor feugait dolore lobortis delenit nibh eu, te et in, dolore.</span>
</p>
</TextFlow>
</fx:XML>
</fx:Declarations>
<fx:Script>
<![CDATA[
import flashx.textLayout.container.ContainerController;
import flashx.textLayout.elements.TextFlow;
import flashx.textLayout.formats.WhiteSpaceCollapse;
import mx.events.FlexEvent;
import spark.utils.TextFlowUtil;
protected function init(event:FlexEvent):void
{
// first textflow
// XML.ignoreWhitespace = false;
var tf:TextFlow = TextFlowUtil.importFromXML(this.tfxml,WhiteSpaceCollapse.PRESERVE);
var cc:ContainerController = new ContainerController(this.cont,this.width,this.height/2);
tf.flowComposer.addController(cc);
tf.flowComposer.updateAllControllers();
// second textflow
tf = TextFlowUtil.importFromXML(this.tfxml2,WhiteSpaceCollapse.PRESERVE);
cc = new ContainerController(this.cont2,this.width,this.height/2);
tf.flowComposer.addController(cc);
tf.flowComposer.updateAllControllers();
tf.interactionManager = new MyEditManager();
this.textGroup.setFocus();
}
]]>
</fx:Script>
<s:VGroup id="textGroup" x="0" y="0" width="100%" height="100%">
<s:SpriteVisualElement height="50%" id="cont"/>
<s:SpriteVisualElement height="50%" id="cont2"/>
</s:VGroup>
</s:Application>
--> MyEditManager.as <--
package
{
import flash.events.KeyboardEvent;
import flash.text.engine.FontWeight;
import flashx.textLayout.container.ContainerController;
import flashx.textLayout.edit.EditManager;
import flashx.textLayout.elements.TextFlow;
import flashx.textLayout.formats.TextLayoutFormat;
import flashx.textLayout.formats.WhiteSpaceCollapse;
import flashx.undo.IUndoManager;
import spark.utils.TextFlowUtil;
public class MyEditManager extends EditManager
{
public function MyEditManager(undoManager:IUndoManager=null)
{
super(undoManager);
}
override public function keyDownHandler(event:KeyboardEvent):void {
// want to override some keyboard events here
if ( event.ctrlKey ) {
if ( this.isRangeSelection() ) {
var charStyle:TextLayoutFormat = new TextLayoutFormat();
charStyle.fontWeight = FontWeight.BOLD;
charStyle.whiteSpaceCollapse = WhiteSpaceCollapse.PRESERVE;
this.applyLeafFormat(charStyle);
resetTextFlow();
}
event.stopPropagation();
}
}
private function resetTextFlow():void {
// XML.ignoreWhitespace = false; this introduces unwanted line breaks!
var str:String = TextFlowUtil.export(this.textFlow).toXMLString();
var tfx:XML = new XML(str);
var tf:TextFlow = TextFlowUtil.importFromXML(tfx,WhiteSpaceCollapse.PRESERVE);
for ( var i:int=this.textFlow.flowComposer.numControllers-1; i >= 0; i-- ) {
var cc:ContainerController = this.textFlow.flowComposer.getControllerAt(i);
this.textFlow.flowComposer.removeControllerAt(i);
tf.flowComposer.addControllerAt(cc,0);
}
tf.flowComposer.updateAllControllers();
this.textFlow = tf;
}
}
}
