You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ha...@apache.org on 2017/03/16 13:37:49 UTC
[29/42] flex-asjs git commit: And here’s TLF…
http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/ImportExportConfiguration.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/ImportExportConfiguration.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/ImportExportConfiguration.as
new file mode 100644
index 0000000..84d328c
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/ImportExportConfiguration.as
@@ -0,0 +1,125 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.conversion
+{
+
+ import org.apache.flex.textLayout.debug.assert;
+ import org.apache.flex.textLayout.formats.WhiteSpaceCollapse;
+
+
+
+ /**
+ * Configure for import/export of standard components.
+ * Configures the import/export package so it can export all the standard FlowElements.
+ *
+ * @see org.apache.flex.textLayout.elements.Configuration
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ */
+ public class ImportExportConfiguration
+ {
+ /**
+ * array of FlowElementInfo objects (key = name, value = FlowElementInfo)
+ * */
+ public var flowElementInfoList:Object = {};
+ public var flowElementClassList:Object= {};
+ public var classToNameMap:Object = {};
+
+ /**
+ * Whitespace collapse export setting
+ * @default WhiteSpaceCollapse.PRESERVE
+ **/
+ public var whiteSpaceCollapse:String = WhiteSpaceCollapse.PRESERVE;
+
+ /**
+ * Constructor.
+ *
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ */
+ public function ImportExportConfiguration()
+ {
+ }
+
+ /**
+ * Add a parser for a new FlowElement type. This allows FlowElements to be added from outside the main system,
+ * and still have the main system be able to import them from XML.
+ *
+ * @param name the name of the FlowElement class, as it appear in the XML
+ * @param flowClass the class of the FlowElement
+ * @param parser function fpr importing the XML into a FlowElement
+ * @param exporter function for exporting a FlowElement into XML
+ * @private
+ */
+ public function addIEInfo(name:String, flowClass:Class, parser:Function, exporter:Function):void
+ {
+ var info:FlowElementInfo = new FlowElementInfo(flowClass, parser, exporter);
+ if (name)
+ {
+ CONFIG::debug { assert (lookup(name) == null, "FlowElementInfo already exists");}
+ flowElementInfoList[name] = info;
+ }
+ if (flowClass)
+ {
+ CONFIG::debug { assert (lookupByClass(info.flowClassName) == null, "FlowElementInfo already exists");}
+ flowElementClassList[info.flowClassName] = info;
+ }
+ if (name && flowClass)
+ classToNameMap[info.flowClassName] = name;
+ }
+
+ /**
+ * Return the information being held about the FlowElement, as a FlowElementInfo.
+ *
+ * @param name the name of the FlowElement class, as it appears in the XML
+ * @return FlowElementInfo the information being held, as it was supplied to addParseInfo
+ * @private
+ */
+ public function lookup(name:String):FlowElementInfo
+ {
+ return flowElementInfoList[name];
+ }
+
+ /**
+ * Return the element name for the class
+ *
+ * @param classToMatch fully qualified class name of the FlowElement
+ * @return name export name to use for class
+ * @private
+ */
+ public function lookupName(classToMatch:String):String
+ {
+ return classToNameMap[classToMatch];
+ }
+
+ /**
+ * Return the information being held about the FlowElement, as a FlowElementInfo.
+ *
+ * @param classToMatch fully qualified class name of the FlowElement
+ * @return FlowElementInfo the information being held, as it was supplied to addParseInfo
+ * @private
+ */
+ public function lookupByClass(classToMatch:String):FlowElementInfo
+ {
+ return flowElementClassList[classToMatch];
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/PlainTextExporter.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/PlainTextExporter.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/PlainTextExporter.as
new file mode 100644
index 0000000..a746cfd
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/PlainTextExporter.as
@@ -0,0 +1,142 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.conversion
+{
+ import org.apache.flex.textLayout.elements.IFlowLeafElement;
+ import org.apache.flex.textLayout.elements.IParagraphElement;
+ import org.apache.flex.textLayout.elements.ITextFlow;
+
+
+
+
+ /**
+ * Export converter for plain text format. This class provides an alternative to
+ * the <code>TextConverter.export()</code> static method for exporting plain text.
+ * The PlainTextExporter class's <code>export()</code> method results in the
+ * same output string as the <code>TextConverter.export()</code> static method
+ * if the two properties of the PlainTextExporter class, the <code>PARAGRAPH_SEPARATOR_PROPERTY</code>
+ * and the <code>STRIP_DISCRETIONARY_HYPHENS_PROPERTY</code> properties, contain their
+ * default values of <code>"\n"</code> and <code>true</code>, respectively.
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ */
+ public class PlainTextExporter extends ConverterBase implements IPlainTextExporter
+ {
+ private var _stripDiscretionaryHyphens:Boolean;
+ private var _paragraphSeparator:String;
+
+ static private var _discretionaryHyphen:String = String.fromCharCode(0x00AD);
+
+
+
+ /**
+ * Constructor
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ */
+
+ public function PlainTextExporter()
+ {
+ _stripDiscretionaryHyphens = true;
+ _paragraphSeparator = "\n";
+ }
+
+ /** @copy IPlainTextExporter#stripDiscretionaryHyphens
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0-
+ */
+ public function get stripDiscretionaryHyphens():Boolean
+ { return _stripDiscretionaryHyphens; }
+ public function set stripDiscretionaryHyphens(value:Boolean):void
+ { _stripDiscretionaryHyphens = value; }
+
+ /** @copy IPlainTextExporter#paragraphSeparator
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ */
+ public function get paragraphSeparator():String
+ { return _paragraphSeparator; }
+ public function set paragraphSeparator(value:String):void
+ { _paragraphSeparator = value; }
+
+ /** @copy ITextExporter#export()
+ */
+ public function export(source:ITextFlow, conversionType:String):Object
+ {
+ clear();
+ if (conversionType == ConversionType.STRING_TYPE)
+ return exportToString(source);
+ return null;
+ }
+
+ /** Export text content as a string
+ * @param source the text to export
+ * @return String the exported content
+ *
+ * @private
+ */
+ protected function exportToString(source:ITextFlow):String
+ {
+ var rslt:String = "";
+ var leaf:IFlowLeafElement = source.getFirstLeaf();
+
+ while (leaf)
+ {
+ var p:IParagraphElement = leaf.getParagraph();
+ while (true)
+ {
+ var curString:String = leaf.text;
+
+ //split out discretionary hyphen and put string back together
+ if (_stripDiscretionaryHyphens)
+ {
+ var temparray:Array = curString.split(_discretionaryHyphen);
+ curString = temparray.join("");
+ }
+
+ rslt += curString;
+ var nextLeaf:IFlowLeafElement = leaf.getNextLeaf(p);
+ if (!nextLeaf)
+ break; // end of para
+
+ leaf = nextLeaf;
+ }
+
+ leaf = leaf.getNextLeaf();
+ if (leaf) // not the last para
+ rslt += _paragraphSeparator;
+ }
+
+ if (useClipboardAnnotations)
+ {
+ // Append a final paragraph separator if the last paragraph is not marked as a partial element
+ var lastPara:IParagraphElement = source.getLastLeaf().getParagraph();
+ if (lastPara.getStyle(ConversionConstants.MERGE_TO_NEXT_ON_PASTE) != "true")
+ rslt += _paragraphSeparator;
+
+ }
+ return rslt;
+ }
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/PlainTextImporter.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/PlainTextImporter.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/PlainTextImporter.as
new file mode 100644
index 0000000..b98c43d
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/PlainTextImporter.as
@@ -0,0 +1,116 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.conversion {
+ import org.apache.flex.textLayout.factory.TLFFactory;
+ import org.apache.flex.textLayout.elements.IFlowLeafElement;
+ import org.apache.flex.textLayout.elements.IConfiguration;
+ import org.apache.flex.textLayout.elements.IParagraphElement;
+ import org.apache.flex.textLayout.elements.ISpanElement;
+ import org.apache.flex.textLayout.elements.TextFlow;
+ import org.apache.flex.textLayout.elements.ITextFlow;
+ import org.apache.flex.textLayout.elements.ElementHelper;
+
+
+ // import container.TextFrame;
+
+
+
+ // [ExcludeClass]
+ /**
+ * @private
+ * PlainText import converter. Use this to import simple unformatted Unicode text.
+ * Newlines will be converted to paragraphs. Using the PlainTextImporter directly
+ * is equivalent to calling TextConverter.importToFlow(TextConverter.PLAIN_TEXT_FORMAT).
+ */
+ internal class PlainTextImporter extends ConverterBase implements ITextImporter
+ {
+ protected var _config:IConfiguration = null;
+
+ /** Constructor */
+ public function PlainTextImporter()
+ {
+ }
+
+ /** @copy ITextImporter#importToFlow()
+ */
+ public function importToFlow(source:Object):ITextFlow
+ {
+ if (source is String)
+ return importFromString(String(source));
+ return null;
+ }
+
+ /**
+ * The <code>configuration</code> property contains the IConfiguration instance that
+ * the importerd needs when creating new ITextFlow instances. This property
+ * is initially set to <code>null</code>.
+ * @see ITextFlow constructor
+ * @playerversion Flash 10.2
+ * @playerversion AIR 2.0
+ * @langversion 3.0
+ */
+ public function get configuration():IConfiguration
+ {
+ return _config;
+ }
+
+ public function set configuration(value:IConfiguration):void
+ {
+ _config = value;
+ }
+
+
+ // LF or CR or CR+LF. Equivalently, LF or CR, the latter optionally followed by LF
+//TODO regex
+ private static const _newLineRegex:RegExp = /foo/;// /\u000A|\u000D\u000A?/g;
+ // private static const _newLineRegex:RegExp = /\u000A|\u000D\u000A?/g;
+
+ /** Import text content, from an external source, and convert it into a ITextFlow.
+ * @param source source data to convert
+ * @return textFlows[] an array of ITextFlow objects that were created from the source.
+ */
+ protected function importFromString(source:String):ITextFlow
+ {
+ var paragraphStrings:Array = source.split(_newLineRegex);
+
+ var textFlow:ITextFlow = new TextFlow(TLFFactory.defaultTLFFactory,_config);
+ var paraText:String;
+ for each (paraText in paragraphStrings)
+ {
+ var paragraph:IParagraphElement = ElementHelper.getParagraph(); // No PMD
+ var span:ISpanElement = ElementHelper.getSpan(); // No PMD
+ span.replaceText(0, 0, paraText);
+ paragraph.replaceChildren(0, 0, span);
+ textFlow.replaceChildren(textFlow.numChildren, textFlow.numChildren, paragraph);
+ }
+
+ // Mark partial last paragraph (string doesn't end in paragraph terminator)
+ if (useClipboardAnnotations &&
+ source.lastIndexOf('\u000A', source.length - 1) != source.length - 1)
+ {
+ var lastLeaf:IFlowLeafElement = textFlow.getLastLeaf();
+ lastLeaf.setStyle(ConversionConstants.MERGE_TO_NEXT_ON_PASTE, "true");
+ lastLeaf.parent.setStyle(ConversionConstants.MERGE_TO_NEXT_ON_PASTE, "true");
+ textFlow.setStyle(ConversionConstants.MERGE_TO_NEXT_ON_PASTE, "true");
+ }
+ return textFlow;
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/SingletonAttributeImporter.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/SingletonAttributeImporter.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/SingletonAttributeImporter.as
new file mode 100644
index 0000000..e5db66b
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/SingletonAttributeImporter.as
@@ -0,0 +1,46 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.conversion
+{
+ // [ExcludeClass]
+ /**
+ * @private
+ */
+ internal class SingletonAttributeImporter implements IFormatImporter
+ {
+ private var _keyToMatch:String;
+ private var _rslt:String = null;
+
+ public function SingletonAttributeImporter(key:String)
+ { _keyToMatch = key; }
+ public function reset():void
+ { _rslt = null; }
+ public function get result():Object
+ { return _rslt; }
+ public function importOneFormat(key:String,val:String):Boolean
+ {
+ if (key == _keyToMatch)
+ {
+ _rslt = val;
+ return true;
+ }
+ return false;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/TLFormatImporter.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/TLFormatImporter.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/TLFormatImporter.as
new file mode 100644
index 0000000..1a2df81
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/TLFormatImporter.as
@@ -0,0 +1,65 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.conversion
+{
+ import org.apache.flex.textLayout.property.Property;
+ import org.apache.flex.textLayout.debug.assert;
+ // [ExcludeClass]
+ /**
+ * @private
+ */
+ public class TLFormatImporter implements IFormatImporter
+ {
+ private var _classType:Class;
+ private var _description:Object;
+
+ private var _rslt:Object;
+
+ public function TLFormatImporter(classType:Class,description:Object)
+ {
+ _classType = classType;
+ _description = description;
+ }
+
+ public function get classType():Class
+ { return _classType; }
+
+ public function reset():void
+ {
+ _rslt = null;
+ }
+ public function get result():Object
+ {
+ return _rslt;
+ }
+ public function importOneFormat(key:String,val:String):Boolean
+ {
+ if (_description.hasOwnProperty(key))
+ {
+ if (_rslt == null)
+ _rslt = new _classType();
+
+ CONFIG::debug { assert((_description[key] as Property) != null,"Bad description in TLFormatImporter"); }
+ _rslt[key] = _description[key].setHelper(undefined,val);
+ return true;
+ }
+ return false;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/TextConverter.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/TextConverter.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/TextConverter.as
new file mode 100644
index 0000000..21c12db
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/TextConverter.as
@@ -0,0 +1,649 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.conversion
+{
+ import org.apache.flex.textLayout.elements.IConfiguration;
+ import org.apache.flex.textLayout.elements.ITextFlow;
+ import org.apache.flex.textLayout.elements.TextFlow;
+
+
+
+
+ /**
+ * This is the gateway class for handling import and export. It serves as a unified access point to the
+ * conversion functionality in the Text Layout Framework. It contains a registry for predefined as well
+ * as user defined input and/or output converters, plus a set of conversion methods.
+ * <p>
+ * The format of the converted data is not predefined; user written converters are free to accept and return
+ * any format of their choice. Common formats are strings, XML, and ByteArray instances. Converter authors
+ * should document which formats are supported.
+ * </p>
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ */
+ public class TextConverter
+ {
+ /**
+ * HTML format.
+ * Use this for importing from, or exporting to, a TextFlow using the HTML fomat.
+ * The Text Layout Framework HTML supports a subset of the tags and attributes supported by
+ * the TextField class in the <code>flash.text</code> package.
+ * <p>The following table lists the HTML tags and attributes supported for the import
+ * and export process (tags and attributes supported by TextField, but not supported by
+ * the Text Layout Framework are specifically described as not supported):</p>
+ *
+ *
+ * <table class="innertable" width="640">
+ *
+ * <tr>
+ *
+ * <th>
+ * Tag
+ * </th>
+ *
+ * <th>
+ * Description
+ * </th>
+ *
+ * </tr>
+ *
+ * <tr>
+ *
+ * <td>
+ * Anchor tag
+ * </td>
+ *
+ * <td>
+ * The <code><a></code> tag creates a hypertext link and supports the following attributes:
+ * <ul>
+ *
+ * <li>
+ * <code>target</code>: Specifies the name of the target window where you load the page.
+ * Options include <code>_self</code>, <code>_blank</code>, <code>_parent</code>, and
+ * <code>_top</code>. The <code>_self</code> option specifies the current frame in the current window,
+ * <code>_blank</code> specifies a new window, <code>_parent</code> specifies the parent of the
+ * current frame, and <code>_top</code> specifies the top-level frame in the current window.
+ * </li>
+ *
+ * <li>
+ * <code>href</code>: Specifies a URL. The URL can
+ * be either absolute or relative to the location of the SWF file that
+ * is loading the page. An example of an absolute reference to a URL is
+ * <code>http://www.adobe.com</code>; an example of a relative reference is
+ * <code>/index.html</code>. Absolute URLs must be prefixed with
+ * http://; otherwise, Flash treats them as relative URLs.
+ * <strong>Note: Unlike the TextField class, </strong>ActionScript <code>link</code> events
+ * are not supported. Neither are
+ * <code>a:link</code>, <code>a:hover</code>, and <code>a:active</code> styles.
+ * </li>
+ *
+ * </ul>
+ *
+ * </td>
+ * </tr>
+ *
+ * <tr>
+ *
+ * <td>
+ * Bold tag
+ * </td>
+ *
+ * <td>
+ * The <code><b></code> tag renders text as bold. A bold typeface must be available for the font used.
+ * </td>
+ * </tr>
+ *
+ * <tr>
+ *
+ * <td>
+ * Break tag
+ * </td>
+ * <td>
+ * The <code><br></code> tag creates a line break in the text.
+ * </td>
+ * </tr>
+ *
+ * <tr>
+ *
+ * <td>
+ * Font tag
+ * </td>
+ *
+ * <td>
+ * The <code><font></code> tag specifies a font or list of fonts to display the text.The font tag
+ * supports the following attributes:
+ * <ul>
+ *
+ * <li>
+ * <code>color</code>: Only hexadecimal color (<code>#FFFFFF</code>) values are supported.
+ * </li>
+ *
+ * <li>
+ * <code>face</code>: Specifies the name of the font to use. As shown in the following example,
+ * you can specify a list of comma-delimited font names, in which case Flash Player selects the first available
+ * font. If the specified font is not installed on the local computer system or isn't embedded in the SWF file,
+ * Flash Player selects a substitute font.
+ * </li>
+ *
+ * <li>
+ * <code>size</code>: Specifies the size of the font. You can use absolute pixel sizes, such as 16 or 18
+ * or relative point sizes, such as +2 or -4.
+ * </li>
+ *
+ * <li>
+ * <code>letterspacing</code>: Specifies the tracking (manual kerning) in pixels to be applied to the right of each character.
+ * </li>
+ *
+ * <li>
+ * <code>kerning</code>: Specifies whether kerning is enabled or disabled. A non-zero value enables kerning, while zero disables it.
+ * </li>
+ *
+ * </ul>
+ *
+ * </td>
+ * </tr>
+ *
+ * <tr>
+ *
+ * <td>
+ * Image tag
+ * </td>
+ *
+ * <td>
+ * The <code><img></code> tag lets you embed external image files (JPEG, GIF, PNG), SWF files, and
+ * movie clips inside text.
+ *
+ * <p>The <code><img></code> tag supports the following attributes: </p>
+ *
+ * <ul >
+ *
+ * <li>
+ * <code>src</code>: Specifies the URL to an image or SWF file, or the linkage identifier for a movie clip
+ * symbol in the library. This attribute is required; all other attributes are optional. External files (JPEG, GIF, PNG,
+ * and SWF files) do not show until they are downloaded completely.
+ * </li>
+ *
+ * <li>
+ * <code>width</code>: The width of the image, SWF file, or movie clip being inserted, in pixels.
+ * </li>
+ *
+ * <li>
+ * <code>height</code>: The height of the image, SWF file, or movie clip being inserted, in pixels.
+ * </li>
+ * </ul>
+ * <p><strong>Note: </strong> Unlike the TextField class, the following attributes are not supported:
+ * <code>align</code>, <code>hspace</code>, <code>vspace</code>, <code>id</code>, and <code>checkPolicyFile</code>.</p>
+ *
+ * </td>
+ * </tr>
+ *
+ * <tr>
+ *
+ * <td>
+ * Italic tag
+ * </td>
+ *
+ * <td>
+ * The <code><i></code> tag displays the tagged text in italics. An italic typeface must be available
+ * for the font used.
+ * </td>
+ * </tr>
+ *
+ * <tr>
+ *
+ * <td>
+ * <em>List item tag</em>
+ * </td>
+ *
+ * <td>
+ * <strong>Note: </strong> Unlike the TextField class, the List item tag is not supported.
+ * </td>
+ * </tr>
+ *
+ * <tr>
+ *
+ * <td>
+ * Paragraph tag
+ * </td>
+ *
+ * <td>
+ * The <code><p></code> tag creates a new paragraph.
+ *
+ * The <code><p></code> tag supports the following attributes:
+ * <ul >
+ *
+ * <li>
+ * align: Specifies alignment of text within the paragraph; valid values are <code>left</code>, <code>right</code>, <code>justify</code>, and <code>center</code>.
+ * </li>
+ *
+ * <li>
+ * class: Specifies a class name that can be used for styling
+ * </li>
+ *
+ * </ul>
+ *
+ * </td>
+ * </tr>
+ *
+ * <tr>
+ *
+ * <td>
+ * Span tag
+ * </td>
+ *
+ * <td>
+ *
+ * The <code><span></code> tag supports the following attributes:
+ *
+ * <ul>
+ *
+ * <li>
+ * class: Specifies a class name that can be used for styling. While span tags are often used to set a style defined in a style sheet,
+ * TLFTextField instances do not support style sheets. The span tag is available for TLFTextField instances to refer to a class with
+ * style properties.</li>
+ * <li> You can also put properties directly in the span tag:
+ * <code><span fontFamily="Arial">Hi there</span></code>. However, nested span tags are not supported.
+ * </li>
+ *
+ * </ul>
+ *
+ * </td>
+ * </tr>
+ *
+ * <tr>
+ *
+ * <td>
+ * Text format tag
+ * </td>
+ *
+ * <td>
+ * <p>The <code><textformat></code> tag lets you use a subset of paragraph formatting
+ * properties of the TextFormat class within text fields, including line leading, indentation,
+ * margins, and tab stops. You can combine <code><textformat></code> tags with the
+ * built-in HTML tags. </p>
+ *
+ * <p>The <code><textformat></code> tag has the following attributes: </p>
+ * <ul >
+ *
+ *
+ * <li>
+ * <code>indent</code>: Specifies the indentation from the left margin to the first character
+ * in the paragraph; corresponds to <code>TextFormat.indent</code>. Both positive and negative
+ * numbers are acceptable.
+ * </li>
+ *
+ * <li>
+ * <code>blockindent</code>: Specifies the indentation applied to all lines of the paragraph.
+ * </li>
+ *
+ * <li>
+ * <code>leftmargin</code>: Specifies the left margin of the paragraph, in points; corresponds
+ * to <code>TextFormat.leftMargin</code>.
+ * </li>
+ *
+ * <li>
+ * <code>rightmargin</code>: Specifies the right margin of the paragraph, in points; corresponds
+ * to <code>TextFormat.rightMargin</code>.
+ * </li>
+ *
+ * <li>
+ * <code>leading</code>: Specifies the leading (line height) measured in pixels between a line's ascent and the previous line's descent
+ * </li>
+ *
+ * <li>
+ * <code>tabstops</code>: Specifies a comma-separated list of tab stop positions for the paragraph.
+ * </li>
+ * </ul>
+ *
+ * </td>
+ * </tr>
+ *
+ * <tr>
+ *
+ * <td>
+ * Underline tag
+ * </td>
+ *
+ * <td>
+ * The <code><u></code> tag underlines the tagged text.
+ * </td>
+ * </tr>
+ *
+ * </table>
+ *
+ * <p>When an unknown tag is imported the <code>textFieldHTMLFormat</code> importer will either set a single FlowElement's typeName property to that tag name
+ * or create a DivElement or a SubParagraphGroupElement with its typeName property set to the tag name.</p>
+ * <p>The <code>textFieldHTMLFormat</code> exporter will export <code>typeName</code> as the XML tag when it is different from the default.</p>
+ *
+ * @see org.apache.flex.textLayout.elements.FlowElement#typeName
+ *
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ */
+ public static const TEXT_FIELD_HTML_FORMAT:String = "textFieldHTMLFormat";
+
+ /**
+ * Plain text format.
+ * Use this for creating a TextFlow from a simple, unformatted String,
+ * or for creating a simple, unformatted String from a TextFlow.
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ */
+ public static const PLAIN_TEXT_FORMAT:String = "plainTextFormat";
+
+ /**
+ * TextLayout Format.
+ * Use this for importing from, or exporting to, a TextFlow using the TextLayout markup format.
+ * Text Layout format will detect the following errors:
+ * <ul>
+ * <li>Unexpected namespace</li>
+ * <li>Unknown element</li>
+ * <li>Unknown attribute</li>
+ * </ul>
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ */
+ public static const TEXT_LAYOUT_FORMAT:String = "textLayoutFormat";
+
+ // Descriptors - ordered list of all FormatDescriptors
+ /** @private */
+ static public var _descriptors:Array = [];
+
+ // register standard importers and exporters
+ setFormatsToDefault();
+
+ /** @private */
+ static public function setFormatsToDefault():void // No PMD
+ {
+ _descriptors = [];
+ addFormat(TEXT_LAYOUT_FORMAT, TextLayoutImporter, TextLayoutExporter, TEXT_LAYOUT_FORMAT);
+ addFormat(TEXT_FIELD_HTML_FORMAT, TextFieldHtmlImporter, TextFieldHtmlExporter, null);
+ addFormat(PLAIN_TEXT_FORMAT, PlainTextImporter, PlainTextExporter, "air:text");
+ }
+
+ /**
+ * Creates a TextFlow from source content in a specified format.
+ * <p>Use one of the static constants supplied with this class, a MIME type,
+ * to specify the <code>format</code> parameter, or use a user defined
+ * value for user-registered importers:
+ * <ul>
+ * <li>TextConverter.TEXT_FIELD_HTML_FORMAT</li>
+ * <li>TextConverter.PLAIN_TEXT_FORMAT</li>
+ * <li>TextConverter.TEXT_LAYOUT_FORMAT</li>
+ * </ul>
+ * </p>
+ * @param source Source content
+ * @param format Format of source content
+ * @param config IConfiguration to use when creating new TextFlows
+ * @return TextFlow that was created from the source, or null on errors.
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ * @see #TEXT_FIELD_HTML_FORMAT
+ * @see #PLAIN_TEXT_FORMAT
+ * @see #TEXT_LAYOUT_FORMAT
+ */
+ public static function importToFlow(source:Object, format:String, config:IConfiguration = null):ITextFlow
+ {
+ var parser:ITextImporter = getImporter(format, config);
+ if (!parser)
+ return null;
+ parser.throwOnError = false;
+ return parser.importToFlow(source);
+ }
+
+ /**
+ * Exports a TextFlow to a specified format.
+ * <p>Use one of the static constants supplied with this class, a MIME type,
+ * or a user defined format for user defined exporters to specify
+ * the <code>format</code> parameter:
+ * <ul>
+ * <li>TextConverter.TEXT_FIELD_HTML_FORMAT</li>
+ * <li>TextConverter.PLAIN_TEXT_FORMAT</li>
+ * <li>TextConverter.TEXT_LAYOUT_FORMAT</li>
+ * </ul>
+ * </p>
+ * <p>Specify the type of the exported data in the <code>conversionType</code> parameter
+ * with one of the static constants supplied by the ConversionType class, or a user defined
+ * data type for user defined exporters:
+ * <ul>
+ * <li>ConversionType.STRING_TYPE</li>
+ * <li>ConversionType.XML_TYPE</li>
+ * </ul>
+ * </p>
+ *
+ * Returns a representation of the TextFlow in the specified format, or null on errors.
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ * @param source Source content
+ * @param format Output format
+ * @param conversionType Type of exported data
+ * @return Object Exported form of the TextFlow, or null on errors
+ * @see #TEXT_FIELD_HTML_FORMAT
+ * @see #PLAIN_TEXT_FORMAT
+ * @see #TEXT_LAYOUT_FORMAT
+ * @see org.apache.flex.textLayout.conversion.ConversionType
+ */
+ public static function export(source:TextFlow, format:String, conversionType:String) : Object
+ {
+ var exporter:ITextExporter = getExporter(format);
+ if (!exporter)
+ return null;
+ exporter.throwOnError = false;
+ return exporter.export(source, conversionType);
+ }
+
+ /**
+ * Creates and returns an import converter, which you can then use to import from a
+ * source string, an XML object, or any user defined data formats to a TextFlow.
+ * Use this method if you have many separate imports to perform, or if you want to
+ * handle errors during import. It is equivalent to calling
+ * <code>org.apache.flex.textLayout.conversion.TextConverter.importToFlow()</code>.
+ * <p>Use one of the static constants supplied with this class
+ * to specify the <code>format</code> parameter, a MIME type, or a user defined
+ * data format.
+ * <ul>
+ * <li>TextConverter.TEXT_FIELD_HTML_FORMAT</li>
+ * <li>TextConverter.PLAIN_TEXT_FORMAT</li>
+ * <li>TextConverter.TEXT_LAYOUT_FORMAT</li>
+ * </ul>
+ * </p>
+ * <p>If the format has been added multiple times, the first one found will be used.</p>
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ * @param format Format of source content. Use constants from
+ * org.apache.flex.textLayout.conversion.TextConverter.TEXT_LAYOUT_FORMAT, PLAIN_TEXT_FORMAT, TEXT_FIELD_HTML_FORMAT etc,
+ * a MIME type, or a user defined format.
+ * @param config configuration to use during this import. null means take the current default.
+ * You can also set the configuration via the <code>ITextImporter.configuration</code>
+ * property.
+ * @return ITextImporter Text importer that can import the source data
+ * @see #TEXT_FIELD_HTML_FORMAT
+ * @see #PLAIN_TEXT_FORMAT
+ * @see #TEXT_LAYOUT_FORMAT
+ */
+ public static function getImporter(format:String,config:IConfiguration = null): ITextImporter
+ {
+ var importer:ITextImporter = null;
+ var i:int = findFormatIndex(format);
+ if (i >= 0)
+ {
+ var descriptor:FormatDescriptor = _descriptors[i];
+ if (descriptor && descriptor.importerClass)
+ {
+ importer = new descriptor.importerClass();
+ importer.configuration = config;
+ }
+ }
+ return importer;
+ }
+
+ /**
+ * Creates and returns an export converter, which you can then use to export from
+ * a TextFlow to a source string or XML object. Use this function if
+ * you have many separate exports to perform. It is equivalent to calling
+ * <code>org.apache.flex.textLayout.conversion.TextConverter.export()</code>.
+ * <p>Use one of the static constants supplied with this class
+ * to specify the <code>format</code> parameter:
+ * <ul>
+ * <li>TextConverter.TEXT_FIELD_HTML_FORMAT</li>
+ * <li>TextConverter.PLAIN_TEXT_FORMAT</li>
+ * <li>TextConverter.TEXT_LAYOUT_FORMAT</li>
+ * </ul>
+ * </p>
+ * <p>If the format has been added multiple times, the first one found will be used.</p>
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ * @param format Target format for exported data
+ * @return ITextExporter Text exporter that can export in the specified format
+ * @see #TEXT_FIELD_HTML_FORMAT
+ * @see #PLAIN_TEXT_FORMAT
+ * @see #TEXT_LAYOUT_FORMAT
+ */
+ public static function getExporter(format:String) : ITextExporter
+ {
+ var exporter:ITextExporter = null;
+ var i:int = findFormatIndex(format);
+ if (i >= 0)
+ {
+ var descriptor:FormatDescriptor = _descriptors[i];
+ if (descriptor && descriptor.exporterClass)
+ exporter = new descriptor.exporterClass();
+ }
+ return exporter;
+ }
+
+ /**
+ * Register a new format for import/export, at the specified location.
+ * Location can be significant for clients that have multiple
+ * choices for which format to use, such as when importing from the external clipboard.
+ * Lower numbers indicate higher priority; these converters will be tried first.
+ * The new format may support importing and/or exporting.
+ * If the format has already been added, then it will be present in multiple locations. The
+ * first one found will be used.
+ *
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ * @param importClass The import converter class to register or null
+ * @param exportClass The export converter class to register or null
+ * @param format The format string tagging the converter classes
+ * @param clipboardFormat The string used as the clipboard format when converting to/from the clipboard. Make this null if the format doesn't support clipboard access.
+ */
+ public static function addFormatAt(index:int, format:String, importerClass:Class, exporterClass:Class = null, clipboardFormat:String = null):void
+ {
+ var descriptor:FormatDescriptor = new FormatDescriptor(format, importerClass, exporterClass, clipboardFormat);
+ _descriptors.splice(index, 0, descriptor);
+ }
+
+ /**
+ * Register a new format for import/export. The new format will be added at the end,
+ * as the lowest priority. Location can be significant for clients that have multiple
+ * choices for which format to use, such as when importing from the external clipboard.
+ * The new format may support importing and/or exporting.
+ * If the format has already been added, then it will be present in multiple locations. The
+ * first one found will be used.
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ * @param importClass The import converter class to register or null
+ * @param exportClass The export converter class to register or null
+ * @param format The format string tagging the converter classes. Formats can be any name, but must be unique.
+ * @param clipboardFormat The string used as the clipboard format when converting to/from the clipboard. Make this null if the format doesn't support clipboard access.
+ */
+ public static function addFormat(format:String, importerClass:Class, exporterClass:Class, clipboardFormat:String):void
+ {
+ addFormatAt(_descriptors.length, format, importerClass, exporterClass, clipboardFormat);
+ }
+
+ /**
+ * Remove the format at the index location.
+ *
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ * @param index The format to remove
+ */
+ public static function removeFormatAt(index:int):void
+ {
+ if (index >= 0 && index < _descriptors.length)
+ _descriptors.splice(index, 1);
+ }
+
+ private static function findFormatIndex(format:String):int
+ {
+ for (var i:int = 0; i < numFormats; i++)
+ {
+ if (_descriptors[i].format == format)
+ return i;
+ }
+ return -1;
+ }
+ /**
+ * Remove the format.
+ * If a format was added multiple times, only the first one found is removed.
+ *
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ * @param format The converter format string to remove
+ */
+ public static function removeFormat(format:String):void
+ {
+ removeFormatAt(findFormatIndex(format));
+ }
+
+ /** Returns the format name for the index'th format.
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ */
+ public static function getFormatAt(index:int):String
+ {
+ return _descriptors[index].format;
+ }
+
+ /** Returns the FormatDescriptor for the index'th format.
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ */
+ public static function getFormatDescriptorAt(index:int):FormatDescriptor
+ {
+ return _descriptors[index];
+ }
+
+ /** Number of formats.
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ */
+ public static function get numFormats():int
+ {
+ return _descriptors.length;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/TextFieldHtmlExporter.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/TextFieldHtmlExporter.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/TextFieldHtmlExporter.as
new file mode 100644
index 0000000..2587649
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/conversion/TextFieldHtmlExporter.as
@@ -0,0 +1,580 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.conversion
+{
+ import org.apache.flex.textLayout.elements.ListElement;
+ import org.apache.flex.textLayout.elements.IFlowGroupElement;
+ import org.apache.flex.reflection.getQualifiedClassName;
+ import org.apache.flex.text.engine.Kerning;
+ import org.apache.flex.text.engine.TabAlignment;
+ import org.apache.flex.textLayout.debug.assert;
+ import org.apache.flex.textLayout.elements.BreakElement;
+ import org.apache.flex.textLayout.elements.DivElement;
+ import org.apache.flex.textLayout.elements.FlowGroupElement;
+ import org.apache.flex.textLayout.elements.IFlowElement;
+ import org.apache.flex.textLayout.elements.IFlowLeafElement;
+ import org.apache.flex.textLayout.elements.IParagraphElement;
+ import org.apache.flex.textLayout.elements.InlineGraphicElement;
+ import org.apache.flex.textLayout.elements.LinkElement;
+ import org.apache.flex.textLayout.elements.IListElement;
+ import org.apache.flex.textLayout.elements.ListItemElement;
+ import org.apache.flex.textLayout.elements.IParagraphElement;
+ import org.apache.flex.textLayout.elements.SpanElement;
+ import org.apache.flex.textLayout.elements.SubParagraphGroupElement;
+ import org.apache.flex.textLayout.elements.SubParagraphGroupElementBase;
+ import org.apache.flex.textLayout.elements.TCYElement;
+ import org.apache.flex.textLayout.elements.TabElement;
+ import org.apache.flex.textLayout.elements.ITextFlow;
+ import org.apache.flex.textLayout.formats.Direction;
+ import org.apache.flex.textLayout.formats.Float;
+ import org.apache.flex.textLayout.formats.FormatValue;
+ import org.apache.flex.textLayout.formats.ITextLayoutFormat;
+ import org.apache.flex.textLayout.formats.LeadingModel;
+ import org.apache.flex.textLayout.formats.TabStopFormat;
+ import org.apache.flex.textLayout.formats.TextAlign;
+ import org.apache.flex.textLayout.formats.TextLayoutFormat;
+
+ // [ExcludeClass]
+ /**
+ * @private
+ * Export converter for HTML format.
+ */
+ public class TextFieldHtmlExporter extends ConverterBase implements ITextExporter
+ {
+ /** @private */
+ public static var _config:ImportExportConfiguration;
+
+ public function TextFieldHtmlExporter()
+ {
+ if (!_config)
+ {
+ _config = new ImportExportConfiguration();
+ _config.addIEInfo(null, DivElement, null, exportDiv);
+ _config.addIEInfo(null, IParagraphElement, null, exportParagraph);
+ _config.addIEInfo(null, LinkElement, null, exportLink);
+ _config.addIEInfo(null, TCYElement, null, exportTCY);
+ _config.addIEInfo(null, SubParagraphGroupElement, null, exportSPGE);
+ _config.addIEInfo(null, SpanElement, null, exportSpan);
+ _config.addIEInfo(null, InlineGraphicElement, null, exportImage);
+ _config.addIEInfo(null, TabElement, null, exportTab);
+ _config.addIEInfo(null, BreakElement, null, exportBreak);
+ _config.addIEInfo(null, ListElement, null, exportList);
+ _config.addIEInfo(null, ListItemElement, null, exportListItem);
+ }
+ }
+
+ /** @copy ITextExporter#export()
+ */
+ public function export(source:ITextFlow, conversionType:String):Object
+ {
+ var result:XML = exportToXML(source);
+ return conversionType == ConversionType.STRING_TYPE ? BaseTextLayoutExporter.convertXMLToString(result) : result;
+ }
+
+ /** Export text content of a TextFlow into HTML format.
+ * @param source the text to export
+ * @return XML the exported content
+ * @private
+ */
+ public function exportToXML(textFlow:ITextFlow) : XML
+ {
+ var html:XML = <HTML/>;
+
+ if (textFlow.numChildren != 0)
+ {
+ if (textFlow.getChildAt(0).typeName != "BODY")
+ {
+ var body:XML = <BODY/>;
+ html.appendChild(body);
+ exportChildren(textFlow,body);
+ }
+ else
+ exportChildren(textFlow,html);
+ }
+
+ return html;
+ }
+
+ /** create the XMl tag for an element. @private */
+ static public function makeTaggedTypeName(elem:IFlowElement,defaultTag:String):XML
+ {
+ if (elem.typeName == elem.defaultTypeName)
+ return <{defaultTag}/>;
+ return <{elem.typeName.toUpperCase()}/>;
+ }
+
+ /** export styleName and id @private */
+ public static function exportStyling(elem:IFlowElement, xml:XML):void
+ {
+ if (elem.id != null)
+ xml.@id = elem.id;
+//TODO @
+ // if (elem.styleName != null)
+ // xml.@["class"] = elem.styleName;
+ }
+
+ /** export FlowGroupElement children into parentXML. @private */
+ public function exportChildren(elem:IFlowGroupElement,parentXML:XML):void
+ {
+ for (var idx:int = 0; idx < elem.numChildren; idx++)
+ {
+ var child:IFlowElement = elem.getChildAt(idx);
+ exportElement(child,parentXML);
+ }
+ }
+
+ /** Export a List @private */
+ public function exportList(list:IListElement, parentXML:XML):void
+ {
+ var xml:XML;
+ if (list.isNumberedList())
+ xml = <OL/>;
+ else
+ xml = <UL/>;
+ exportStyling(list, xml);
+ exportChildren(list, xml);
+
+ if (list.typeName != list.defaultTypeName)
+ {
+ var typeNameXML:XML = <{list.typeName}/>;
+ typeNameXML.appendChild(xml);
+ parentXML.appendChild(typeNameXML);
+ }
+ else
+ parentXML.appendChild(xml);
+ }
+
+
+ /** Export a ListItem @private */
+ public function exportListItem(li:ListItemElement, parentXML:XML):void
+ {
+ // WARNING: no solution for a listitem with a custom typeName - loose the typeName
+ var xml:XML = <LI/>;
+ exportStyling(li, xml);
+ exportChildren(li, xml);
+
+ // if we've got exactly one P promote its child directly into the LI. It causes TextField to add an extra paragraph. Ugly.
+ var children:XMLList = xml.children();
+ if (children.length() == 1)
+ {
+ var child:XML = children[0];
+ if (child.name().localName == "P")
+ {
+ var paraChildren:XMLList = child.children();
+ if (paraChildren.length() == 1)
+ {
+ xml = <LI/>;
+ xml.appendChild(paraChildren[0]);
+ }
+ }
+ }
+ parentXML.appendChild(xml);
+ }
+
+ /** Export a DIV element */
+ public function exportDiv(div:DivElement, parentXML:XML):void
+ {
+ var xml:XML = makeTaggedTypeName(div,"DIV");
+ exportStyling(div, xml);
+ exportChildren(div, xml);
+ parentXML.appendChild(xml);
+ }
+
+ /** Export a paragraph
+ * @private
+ */
+ public function exportParagraph(para:IParagraphElement, parentXML:XML):void
+ {
+ // Exported as a <P/>
+ // Some paragraph-level formats (such as textAlign) are exported as attributes of <P/>,
+ // Others (such as textIndent) are exported as attributes of the <TEXTFORMAT/> parent of <P/>
+ // Some character-level formats (such as fontSize) are exported as attributes of the <FONT/> child of <P/>
+ // Children of the IParagraphElement are nested inside the <FONT/>
+ var xml:XML = makeTaggedTypeName(para,"P");
+ exportStyling(para, xml);
+
+ var fontXML:XML = exportFont(para.computedFormat);
+ CONFIG::debug { assert(fontXML != null, "Expect exportFont to return non-null xml if second parameter (ifDifferentFromFormat) is null"); }
+ exportSubParagraphChildren(para, fontXML);
+ nest(xml, fontXML);
+
+ parentXML.appendChild(exportParagraphFormat(xml, para));
+ }
+
+ /** Export a link
+ * @private
+ */
+ public function exportLink(link:LinkElement, parentXML:XML):void
+ {
+ // Exported as an <A/> with HREF and TARGET attributes
+ // Children of the LinkElement are nested inside the <A/>
+ // If the computed values of certain character-level formats differ from the corresponding computed values for the
+ // containing paragraph, these are exported as attributes of a <FONT/> which (in this case) parents the <A/>.
+ var xml:XML = <A/>;
+
+ if (link.href)
+ xml.@HREF= link.href;
+ if (link.target)
+ xml.@TARGET = link.target;
+ else
+ {
+ // TextField uses _self as the default target
+ // while TLF uses null (funcionally identical to _blank). Account for this difference.
+ xml.@TARGET = "_blank";
+ }
+ exportSubParagraphElement(link, xml, parentXML);
+ }
+
+ /** Export a tcy element
+ * @private
+ */
+ public function exportTCY(tcy:TCYElement, parentXML:XML):void
+ {
+ // make it a custom element - this will round trip it
+ // note if the element has a custom typeName that typeName is going to be built as a parent
+ var xml:XML = <TCY/>;
+ exportSubParagraphElement(tcy, xml, parentXML);
+ }
+
+
+ /** Export a SubParagraphGroupElement
+ * @private
+ */
+ public function exportSPGE(spge:SubParagraphGroupElement, parentXML:XML):void
+ {
+ var xml:XML = spge.typeName != spge.defaultTypeName ? <{spge.typeName}/> : <SPAN/>;
+ exportSubParagraphElement(spge, xml, parentXML, false);
+ }
+
+ public function exportSubParagraphElement(elem:SubParagraphGroupElementBase, xml:XML, parentXML:XML, checkTypeName:Boolean=true):void
+ {
+ exportStyling(elem, xml);
+ exportSubParagraphChildren(elem, xml);
+
+ var format:ITextLayoutFormat = elem.computedFormat;
+ var ifDifferentFromFormat:ITextLayoutFormat = elem.parent.computedFormat;
+
+ var font:XML = exportFont(format, ifDifferentFromFormat);
+ var childXML:XML = font ? nest(font, xml) : xml;
+
+ if (checkTypeName && elem.typeName != elem.defaultTypeName)
+ {
+ var typeNameXML:XML = <{elem.typeName}/>;
+ typeNameXML.appendChild(childXML);
+ parentXML.appendChild(typeNameXML);
+ }
+ else
+ parentXML.appendChild(childXML);
+ }
+
+ /** @private */
+//TODO regex
+ static public const brRegEx:RegExp = /foo/;
+ // static public const brRegEx:RegExp = /\u2028/;
+
+ /** Gets the xml element used to represent a character in the export format
+ * @private
+ */
+ static public function getSpanTextReplacementXML(ch:String):XML
+ {
+ CONFIG::debug {assert(ch == '\u2028', "Did not recognize character to be replaced with XML"); }
+ return <BR/>;
+ }
+
+ /** Export a span
+ * @private
+ */
+ public function exportSpan(span:SpanElement, parentXML:XML):void
+ {
+ // Span text is exported as a text node (or text nodes delimited by <BR/> elements for any occurences of U+2028)
+ // These text nodes and <BR/> elements are optionally nested in formatting elements
+ var xml:XML = makeTaggedTypeName(span, "SPAN");
+ exportStyling(span, xml);
+ BaseTextLayoutExporter.exportSpanText(xml, span, brRegEx, getSpanTextReplacementXML);
+
+ // for brevity, do not export attribute-less <span> tags; export just their children
+ if (span.id == null && span.styleName == null && span.typeName == span.defaultTypeName)
+ {
+ var children:Object = xml.children();
+
+ // Workaround for bug 1852072 : extraneous tags can appear around a string child added after an XML element
+ if (children.length() == 1 && children[0].nodeKind() == "text")
+ children = xml.text()[0];
+
+ parentXML.appendChild(exportSpanFormat(children, span));
+ }
+ else
+ parentXML.appendChild(exportSpanFormat(xml, span));
+ }
+
+ /** Export an inline graphic
+ * @private
+ */
+ public function exportImage(image:InlineGraphicElement, parentXML:XML):void
+ {
+ // Exported as an <IMG/> with SRC, WIDTH, HEIGHT and ALIGN attributes
+ var xml:XML = <IMG/>;
+ exportStyling(image, xml);
+ if (image.source)
+ xml.@SRC = image.source;
+ if (image.width !== undefined && image.width != FormatValue.AUTO)
+ xml.@WIDTH = image.width;
+ // xml.@WIDTH = image.actualWidth;
+ if (image.height !== undefined && image.height != FormatValue.AUTO)
+ xml.@HEIGHT = image.height;
+ // xml.@HEIGHT = image.actualHeight;
+ if (image.computedFloat != Float.NONE)
+ xml.@ALIGN = image.float;
+
+ if (image.typeName != image.defaultTypeName)
+ {
+ var typeNameXML:XML = <{image.typeName}/>;
+ typeNameXML.appendChild(xml);
+ parentXML.appendChild(typeNameXML);
+ }
+ else
+ parentXML.appendChild(xml);
+ }
+
+ /** Export a break
+ * Is this ever called: BreakElements are either merged with adjacent spans or become spans?
+ * @private
+ */
+ public function exportBreak(breakElement:BreakElement,parentXML:XML):void
+ {
+ parentXML.appendChild(<BR/>);
+ }
+
+ /** Export a tab
+ * Is this ever called: TabElements are either merged with adjacent spans or become spans?
+ * @private
+ */
+ public function exportTab(tabElement:TabElement, parentXML:XML):void
+ {
+ // Export as a span
+ exportSpan(tabElement, parentXML);
+ }
+
+ /** @private */
+ public function exportTextFormatAttribute (textFormatXML:XML, attrName:String, attrVal:*):XML
+ {
+ if (!textFormatXML)
+ textFormatXML = <TEXTFORMAT/>;
+
+//TODO @
+ // textFormatXML.@[attrName] = attrVal;
+
+ return textFormatXML;
+ }
+
+ /** Exports the paragraph-level format for a paragraph
+ * @param xml xml to decorate with attributes or add nest in formatting elements
+ * @para the paragraph
+ * @return XML the outermost XML element after exporting
+ * @private
+ */
+ public function exportParagraphFormat(xml:XML, para:IParagraphElement):XML
+ {
+ var paraFormat:ITextLayoutFormat = para.computedFormat;
+
+ var textAlignment:String;
+ switch(paraFormat.textAlign)
+ {
+ case TextAlign.START:
+ textAlignment = (paraFormat.direction == Direction.LTR) ? TextAlign.LEFT : TextAlign.RIGHT;
+ break;
+ case TextAlign.END:
+ textAlignment = (paraFormat.direction == Direction.LTR) ? TextAlign.RIGHT : TextAlign.LEFT;
+ break;
+ default:
+ textAlignment = paraFormat.textAlign;
+ }
+ xml.@ALIGN = textAlignment;
+
+ var textFormat:XML;
+
+ if (paraFormat.paragraphStartIndent != 0)
+ textFormat = exportTextFormatAttribute (textFormat, paraFormat.direction == Direction.LTR ? "LEFTMARGIN" : "RIGHTMARGIN", paraFormat.paragraphStartIndent);
+
+ if (paraFormat.paragraphEndIndent != 0)
+ textFormat = exportTextFormatAttribute (textFormat, paraFormat.direction == Direction.LTR ? "RIGHTMARGIN" : "LEFTMARGIN", paraFormat.paragraphEndIndent);
+
+ if (paraFormat.textIndent != 0)
+ textFormat = exportTextFormatAttribute(textFormat, "INDENT", paraFormat.textIndent);
+
+ if (paraFormat.leadingModel == LeadingModel.APPROXIMATE_TEXT_FIELD)
+ {
+ var firstLeaf:IFlowLeafElement = para.getFirstLeaf();
+ if (firstLeaf)
+ {
+ var lineHeight:Number = TextLayoutFormat.lineHeightProperty.computeActualPropertyValue(firstLeaf.computedFormat.lineHeight,firstLeaf.getEffectiveFontSize());
+ if (lineHeight != 0)
+ textFormat = exportTextFormatAttribute(textFormat, "LEADING", lineHeight);
+ }
+ }
+
+ var tabStops:Array = paraFormat.tabStops;
+ if (tabStops)
+ {
+ var tabStopsString:String = "";
+ for each (var tabStop:TabStopFormat in tabStops)
+ {
+ if (tabStop.alignment != TabAlignment.START)
+ break;
+
+ if (tabStopsString.length)
+ tabStopsString += ", ";
+
+ tabStopsString += tabStop.position;
+ }
+
+ if (tabStopsString.length)
+ textFormat = exportTextFormatAttribute(textFormat, "TABSTOPS", tabStopsString);
+ }
+
+ return textFormat ? nest(textFormat, xml) : xml;
+ }
+
+ /** Exports the character-level format for a span
+ * @param xml xml/xmlList to nest in formatting elements
+ * @span the span
+ * @return XML the outermost XML element after exporting
+ * @private
+ */
+ public function exportSpanFormat(xml:Object, span:SpanElement):Object
+ {
+ // These are optionally nested in a <FONT/> with appopriate attributes ,
+
+ var format:ITextLayoutFormat = span.computedFormat;
+ var outerElement:Object = xml;
+
+ // Nest in <B/>, <I/>, or <U/> if applicable
+ if (format.textDecoration.toString() == org.apache.flex.textLayout.formats.TextDecoration.UNDERLINE)
+ outerElement = nest (<U/>, outerElement);
+//TODO get HTML based on styles
+// if (format.fontStyle.toString() == org.apache.flex.text.engine.FontPosture.ITALIC)
+// outerElement = nest (<I/>, outerElement);
+// if (format.fontWeight.toString() == org.apache.flex.text.engine.FontWeight.BOLD)
+// outerElement = nest (<B/>, outerElement);
+
+ // Nest in <FONT/> if the computed values of certain character-level formats
+ // differ from the corresponding computed values for the containing parent that's exported
+ // A span can be contained in a TCY, link, or paragraph. Of these, TCY is not exported, so only
+ // check link and paragraph.
+ var exportedParent:IFlowElement = span.getParentByType("LinkElement");
+ if (!exportedParent)
+ exportedParent = span.getParagraph();
+
+ var font:XML = exportFont(format, exportedParent.computedFormat);
+ if (font)
+ outerElement = nest(font, outerElement);
+
+ return outerElement;
+ }
+
+ /** @private */
+ public function exportFontAttribute (fontXML:XML, attrName:String, attrVal:*):XML
+ {
+ if (!fontXML)
+ fontXML = <FONT/>;
+
+//TODO @
+ // fontXML.@[attrName] = attrVal;
+
+ return fontXML;
+ }
+
+ /**
+ * Exports certain character level formats as a <FONT/> with appropriate attributes
+ * @param format format to export
+ * @param ifDifferentFromFormat if non-null, a value in format is exported only if it differs from the corresponding value in ifDifferentFromFormat
+ * @return XML the populated XML element
+ * @private
+ */
+ public function exportFont(format:ITextLayoutFormat, ifDifferentFromFormat:ITextLayoutFormat=null):XML
+ {
+ var font:XML;
+ if (!ifDifferentFromFormat || ifDifferentFromFormat.fontFamily != format.fontFamily)
+ font = exportFontAttribute(font, "FACE", format.fontFamily);
+ if (!ifDifferentFromFormat || ifDifferentFromFormat.fontSize != format.fontSize)
+ font = exportFontAttribute(font, "SIZE", format.fontSize);
+ if (!ifDifferentFromFormat || ifDifferentFromFormat.color != format.color)
+ {
+ var rgb:String = format.color.toString(16);
+ while (rgb.length < 6)
+ rgb = "0" + rgb; // pad with leading zeros
+ rgb = "#" + rgb;
+ font = exportFontAttribute(font, "COLOR", rgb);
+ }
+ if (!ifDifferentFromFormat || ifDifferentFromFormat.trackingRight != format.trackingRight)
+ font = exportFontAttribute(font, "LETTERSPACING", format.trackingRight);
+ if (!ifDifferentFromFormat || ifDifferentFromFormat.kerning != format.kerning)
+ font = exportFontAttribute(font, "KERNING", format.kerning == Kerning.OFF ? "0" : "1");
+
+ return font;
+ }
+
+ /** Exports the flow element by finding the appropriate exporter
+ * @param flowElement Element to export
+ * @return Object XML/XMLList for the flowElement
+ * @private
+ */
+ public function exportElement(flowElement:IFlowElement, parentXML:XML):void
+ {
+ var className:String = getQualifiedClassName(flowElement);
+ var info:FlowElementInfo = _config.lookupByClass(className);
+ if (info)
+ info.exporter(flowElement, parentXML);
+ else
+ {
+ CONFIG::debug { assert(flowElement is FlowGroupElement,"Bad element in HtmlExport.exportElement"); }
+ var xml:XML = <{flowElement.typeName.toUpperCase()}/>;
+ exportChildren(flowElement as FlowGroupElement, xml);
+ parentXML.appendChild(xml);
+ }
+ }
+
+ /** Exports the children of a flow group element
+ * @param xml XML to append children to
+ * @param flowGroupElement the flow group element
+ * @private
+ */
+ public function exportSubParagraphChildren(flowGroupElement:IFlowGroupElement, parentXML:XML):void
+ {
+ for(var i:int=0; i < flowGroupElement.numChildren; ++i)
+ {
+ exportElement(flowGroupElement.getChildAt(i),parentXML);
+ }
+ }
+
+ /** Helper to establish a parent-child relationship between two xml elements
+ * and return the parent
+ * @param parent the intended parent
+ * @param children the intended children (XML or XMLList)
+ * @return the parent
+ * @private
+ */
+ static public function nest (parent:XML, children:Object):XML
+ {
+ parent.setChildren(children);
+ return parent;
+ }
+
+ }
+}
\ No newline at end of file