blob: e0f0a2cc2733955083332045d211ed983b5083e4 [file] [log] [blame]
////////////////////////////////////////////////////////////////////////////////
//
// 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 flashx.textLayout.conversion
{
import flash.utils.Dictionary;
import flashx.textLayout.elements.IConfiguration;
import flashx.textLayout.elements.TextFlow;
import flashx.textLayout.elements.TextRange;
import flashx.textLayout.tlf_internal;
use namespace tlf_internal;
/**
* 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>
* @includeExample examples\TextConverter_example.as -noswf
* @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>&lt;a&gt;</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>&lt;b&gt;</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>&lt;br&gt;</code> tag creates a line break in the text.
* </td>
* </tr>
*
* <tr>
*
* <td>
* Font tag
* </td>
*
* <td>
* The <code>&lt;font&gt;</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>&lt;img&gt;</code> tag lets you embed external image files (JPEG, GIF, PNG), SWF files, and
* movie clips inside text.
*
* <p>The <code>&lt;img&gt;</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>&lt;i&gt;</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>&lt;p&gt;</code> tag creates a new paragraph.
*
* The <code>&lt;p&gt;</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>&lt;span&gt;</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>&lt;span fontFamily="Arial"&gt;Hi there&lt;/span&gt;</code>. However, nested span tags are not supported.
* </li>
*
* </ul>
*
* </td>
* </tr>
*
* <tr>
*
* <td>
* Text format tag
* </td>
*
* <td>
* <p>The <code>&lt;textformat&gt;</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>&lt;textformat&gt;</code> tags with the
* built-in HTML tags. </p>
*
* <p>The <code>&lt;textformat&gt;</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>&lt;u&gt;</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 flashx.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 tlf_internal var _descriptors:Array = [];
// register standard importers and exporters
setFormatsToDefault();
/** @private */
static tlf_internal 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) : TextFlow
{
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 flashx.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>flashx.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>
* @includeExample examples\getImporter_example.as -noswf
* @playerversion Flash 10
* @playerversion AIR 1.5
* @langversion 3.0
* @param format Format of source content. Use constants from
* flashx.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>flashx.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>
* @includeExample examples\getExporter_example.as -noswf
* @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;
}
}
}