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:44 UTC

[24/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/edit/ISelectionManager.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/edit/ISelectionManager.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/edit/ISelectionManager.as
new file mode 100644
index 0000000..1950519
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/edit/ISelectionManager.as
@@ -0,0 +1,515 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.edit
+{
+	import org.apache.flex.textLayout.elements.CellCoordinates;
+	import org.apache.flex.textLayout.elements.CellRange;
+	import org.apache.flex.textLayout.elements.ITableElement;
+	import org.apache.flex.textLayout.elements.ITextFlow;
+	import org.apache.flex.textLayout.elements.TextRange;
+	import org.apache.flex.textLayout.formats.TextLayoutFormat;
+
+	/** 
+	 * The ISelectionManager interface defines the interface for handling text selection.
+	 * 
+	 * <p>A SelectionManager keeps track of the selected text range and handles events for a TextFlow.</p>
+	 * 
+	 * <p>A selection can be either a point selection or a range selection. A point selection is the insertion point
+	 * and is indicated visually by drawing a cursor. A range
+	 * selection includes the text between an anchor point and an active point.</p>
+	 * 
+	 * @see org.apache.flex.textLayout.edit.SelectionManager
+	 * @see org.apache.flex.textLayout.edit.TextScrap
+	 * @see org.apache.flex.textLayout.elements.TextFlow
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+	 */
+	public interface ISelectionManager extends IInteractionEventHandler
+	{		
+		/** 
+		 * The TextFlow object managed by this selection manager. 
+		 * 
+		 * <p>A selection manager manages a single text flow. A selection manager can also be
+		 * assigned to a text flow by setting the <code>interactionManager</code> property of the
+		 * TextFlow object.</p>
+		 * 
+		 * @see org.apache.flex.textLayout.elements.TextFlow#interactionManager
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function get textFlow():ITextFlow;
+		function set textFlow(flow:ITextFlow):void;
+
+		function get currentTable():ITableElement;
+		function set currentTable(table:ITableElement):void;
+		function hasCellRangeSelection():Boolean;
+		
+		function selectCellRange(anchorCoords:CellCoordinates,activeCoords:CellCoordinates):void;
+		
+		function getCellRange():CellRange;
+		function setCellRange(range:CellRange):void;
+
+		/** Anchor point of the current cell selection, as coordinates within the table. */
+		function get anchorCellPosition():CellCoordinates;
+		function set anchorCellPosition(value:CellCoordinates):void;
+		
+		/** Active end of the current cell selection, as coordinates within the table. */
+		function get activeCellPosition():CellCoordinates;
+		function set activeCellPosition(value:CellCoordinates):void;
+
+		/** 
+		 * The text position of the start of the selection, as an offset from the start of the text flow.
+		 *  
+		 * <p>The absolute start is the same as either the active or the anchor point of the selection, whichever comes
+		 * first in the text flow.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function get absoluteStart() : int;
+		/** 
+		 * The text position of the end of the selection, as an offset from the start of the text flow.
+		 *  
+		 * <p>The absolute end is the same as either the active or the anchor point of the selection, whichever comes
+		 * last in the text flow.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function get absoluteEnd() : int;
+
+		/**
+		 * Selects a range of text.
+		 * 
+		 * <p>If a negative number is passed as either of the parameters, then any existing selection is
+		 * removed.</p>
+		 * 
+		 * @param anchorPosition	The anchor point for the new selection, as an absolute position in the TextFlow 
+		 * @param activePosition	The active end of the new selection, as an absolute position in the TextFlow
+		 * 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function selectRange(anchorPosition:int, activePosition:int) : void
+		
+		/**
+		 * Selects the entire flow.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function selectAll() : void
+		
+		/**
+		 * Selects the last position in the entire flow.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function selectLastPosition() : void
+		
+		/**
+		 * Selects the first position in the entire flow.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function selectFirstPosition() : void
+
+		/**
+		 * Removes any selection from the text flow
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function deselect() : void
+
+		/** 
+		 * The anchor point of the selection. 
+		 * 
+		 * <p>An <em>anchor</em> point is the stable end of the selection. When the selection
+		 * is extended, the anchor point does not change. The anchor point can be at either the beginning 
+		 * or the end of the selection.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */								
+		function get anchorPosition() : int;
+
+		/** 
+		 * The active point of the selection.
+		 * 
+		 * <p>The <em>active</em> point is the volatile end of the selection. The active point is changed 
+		 * when the selection is modified. The active point can be at either the beginning 
+		 * or the end of the selection.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */										
+		function get activePosition() : int;
+		
+		/**
+		 * Indicates whether there is a text selection. 
+		 * 
+		 * <p>Returns <code>true</code> if there is either a range selection or a point selection. 
+		 * By default, when a selection manager is first set up, there is no selection (the start and end are -1).</p>
+		 * 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function hasSelection():Boolean;
+
+		/**
+		 * Indicates whether there is a text or cell selection. 
+		 * 
+		 * <p>Returns <code>true</code> if there is either a range selection or a point selection. 
+		 * By default, when a selection manager is first set up, there is no selection (the start and end are -1).</p>
+		 * 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function hasAnySelection():Boolean;
+
+		/**
+		 * Indicates the type of selection. 
+		 * 
+		 * <p>The <code>selectionType</code> describes the kind of selection. 
+		 * It can either be <code>SelectionType.TEXT</code> or <code>SelectionType.CELLS</code></p>
+		 * 
+		 * @see org.apache.flex.textLayout.edit.SelectionType
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function get selectionType() : String;
+		
+		/**
+		 * Indicates whether the selection covers a range of text.
+		 * 
+		 * <p>Returns <code>true</code> if there is a selection that extends past a single position.</p> 
+		 * 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function isRangeSelection():Boolean;
+		
+		/**
+		 * Gets the SelectionState object of the current selection.
+		 * 
+		 * 
+		 * @see org.apache.flex.textLayout.edit.SelectionState
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		function getSelectionState():SelectionState;
+		
+		/**
+		 * Sets the SelectionState object of the current selection.
+		 * 
+		 * @see org.apache.flex.textLayout.edit.SelectionState
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function setSelectionState(state:SelectionState):void;
+
+		/** 
+		 * Redisplays the selection shapes. 
+		 * 
+		 * <p><b>Note:</b> You do not need to call this method directly. It is called automatically.</p>	
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */	
+		function refreshSelection():void;
+
+		/** 
+		 * Clears the selection shapes. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */	
+		function clearSelection():void;
+
+		/** 
+		 * Gives the focus to the first container in the selection.
+		 *  
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+ 		 */
+		function setFocus():void;
+		
+		/** 
+		 * Indicates whether a container in the text flow has the focus.
+		 * 
+		 * <p>The <code>focused</code> property is <code>true</code> 
+		 * if any of the containers in the text flow has key focus.</p> 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function get focused():Boolean;
+		
+		/** 
+		 * Indicates whether the window associated with the text flow is active.
+		 * 
+		 * <p>The <code>windowActive</code> property is <code>true</code> if the window 
+		 * displaying with the text flow is the active window.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function get windowActive():Boolean;
+		
+		/** 
+		 * The current SelectionFormat object.
+		 * 
+		 * <p>The current SelectionFormat object is chosen from the SelectionFormat objects assigned to the 
+		 * <code>unfocusedSelectionFormat</code>, <code>inactiveSelectionFormat</code> and <code>focusedSelectionFormat</code> 
+		 * properties based on the current state of the <code>windowActive</code> and <code>focused</code> properties.</p> 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function get currentSelectionFormat():SelectionFormat;
+
+		/** 
+		 * The current Cell SelectionFormat object.
+		 * 
+		 * <p>The current cell SelectionFormat object is chosen from the SelectionFormat objects assigned to the 
+		 * <code>unfocusedCellSelectionFormat</code>, <code>inactiveCellSelectionFormat</code> and <code>focusedCellSelectionFormat</code> 
+		 * properties based on the current state of the <code>windowActive</code> and <code>focused</code> properties.</p> 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function get currentCellSelectionFormat():SelectionFormat;
+
+		/**
+		 * Gets the character format attributes that are common to all characters in the specified text range or current selection.
+		 * 
+		 * <p>Format attributes that do not have the same value for all characters in the specified element range or selection are set to 
+		 * <code>null</code> in the returned TextLayoutFormat instance.</p>
+		 * 
+		 * @param range The optional range of text for which common attributes are requested. If null, the current selection is used. 
+		 * @return The common character style settings
+		 * 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function getCommonCharacterFormat (range:TextRange=null):TextLayoutFormat;
+		 
+		 /**
+		 * Gets the paragraph format attributes that are common to all paragraphs in the specified text range or current selection.
+		 * 
+		 * <p>Format attributes that do not have the same value for all paragraphs in the specified element range or selection are set to 
+		 * <code>null</code> in the returned TextLayoutFormat instance.</p>
+		 * 
+		 * @param range The optional range of text for which common attributes are requested. If null, the current selection is used. 
+		 * @return The common paragraph style settings
+		 * 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function getCommonParagraphFormat (range:TextRange=null):TextLayoutFormat;
+		 
+		/**
+		 * Gets the container format attributes that are common to all containers in the specified text range or current selection.
+		 * 
+		 * <p>Format attributes that do not have the same value for all containers in the specified element range or selection are set to 
+		 * <code>null</code> in the returned TextLayoutFormat instance.</p>
+		 * 
+		 * @param range The optional range of text for which common attributes are requested. If null, the current selection is used. 
+		 * @return The common container style settings
+		 * 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function getCommonContainerFormat (range:TextRange=null):TextLayoutFormat;
+
+		/**
+		 * The editing mode. 
+		 * 
+		 * <p>The editing mode indicates whether the text flow supports selection, editing, or only reading.
+		 * A text flow is made selectable by assigning a selection manager and editable by assigning an edit manager.
+		 * Constants representing the editing modes are defined in the EditingMode class.</p>
+		 * 
+		 * @see org.apache.flex.textLayout.EditingMode
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		 function get editingMode():String;		
+		
+		/**
+		 * The SelectionFormat object used to draw the selection in a focused container. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */		 
+		 function get focusedSelectionFormat():SelectionFormat;
+		 function set focusedSelectionFormat(val:SelectionFormat):void;
+		 
+		/**
+		 * The SelectionFormat object used to draw the selection when it is not in a focused container, but is in
+		 * the active window.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */		 		 
+		 function get unfocusedSelectionFormat():SelectionFormat;
+		 function set unfocusedSelectionFormat(val:SelectionFormat):void;
+		 
+		/**
+		 * The SelectionFormat object used to draw the selection when it is not in the active window.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */		 		 
+		 function get inactiveSelectionFormat():SelectionFormat;
+		 function set inactiveSelectionFormat(val:SelectionFormat):void;		 		 
+
+		 /**
+		  * The SelectionFormat object used to draw cell selections in a focused container. 
+		  * 
+		  * @playerversion Flash 10
+		  * @playerversion AIR 1.5
+		  * @langversion 3.0
+		  */		 
+		 function get focusedCellSelectionFormat():SelectionFormat;
+		 function set focusedCellSelectionFormat(val:SelectionFormat):void;
+		 
+		 /**
+		  * The SelectionFormat object used to draw cell selections when they are not in a focused container, but are in
+		  * the active window.
+		  * 
+		  * @playerversion Flash 10
+		  * @playerversion AIR 1.5
+		  * @langversion 3.0
+		  */		 		 
+		 function get unfocusedCellSelectionFormat():SelectionFormat;
+		 function set unfocusedCellSelectionFormat(val:SelectionFormat):void;
+		 
+		 /**
+		  * The SelectionFormat object used to draw cell selections when they are not in the active window.
+		  * 
+		  * @playerversion Flash 10
+		  * @playerversion AIR 1.5
+		  * @langversion 3.0
+		  */		 		 
+		 function get inactiveCellSelectionFormat():SelectionFormat;
+		 function set inactiveCellSelectionFormat(val:SelectionFormat):void;		 		 
+
+		/**
+		 * Executes any pending FlowOperations. 
+		 * 
+		 * <p>The execution of some editing operations, such as text insertion, is delayed 
+		 * until the next enterFrame event. Calling <code>flushPendingOperations()</code> causes any deferred operations to be executed 
+		 * immediately.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 * 
+		 */
+		function flushPendingOperations():void;
+
+		/** 
+		 * Updates the selection manager when text is inserted or deleted.
+		 * 
+		 * <p>Operations must call <code>notifyInsertOrDelete</code> when changing the text in the text flow. 
+		 * The selection manager adjusts index-based position indicators accordingly. If you create a new Operation
+		 * class that changes text in a text flow directly (not using another operation) your operation must call this function 
+		 * to keep the selection up to date.</p>
+		 * 
+		 * @param absolutePosition	The point in the text where the change was made.
+		 * @param length A positive or negative number indicating how many characters were inserted or deleted.
+		 * 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		function notifyInsertOrDelete(absolutePosition:int, length:int):void;		 
+		 
+		/**
+		 * The ISelectionManager object used to for cell selections nested within the TextFlow managed by this ISelectionManager.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */		 		 
+		function get subManager():ISelectionManager;
+		function set subManager(value:ISelectionManager):void;
+		
+		/**
+		 * The ISelectionManager object used to manage the parent TextFlow of this ISelectionManager (i.e. for cell ISelectionManagers).
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */		 		 
+		function get superManager():ISelectionManager;
+		function set superManager(value:ISelectionManager):void;
+		
+		function copy(sharedUndo:Boolean):ISelectionManager;
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/edit/Mark.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/edit/Mark.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/edit/Mark.as
new file mode 100644
index 0000000..a4da370
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/edit/Mark.as
@@ -0,0 +1,38 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.edit
+{
+// [ExcludeClass]
+
+	/** @private - not ready for prime time */
+	public class Mark
+	{
+		private var _position:int;
+
+		public function Mark(value:int = 0)
+		{
+			_position = value;
+		}
+		
+		public function get position():int
+			{ return _position; }
+		public function set position(value:int):void
+			{ _position = value; }
+	}
+}
\ 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/edit/MementoList.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/edit/MementoList.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/edit/MementoList.as
new file mode 100644
index 0000000..1115b73
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/edit/MementoList.as
@@ -0,0 +1,78 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.edit 
+{
+	import org.apache.flex.textLayout.elements.ITextFlow;
+	
+	// [ExcludeClass]
+	/** 
+	 * The MementoList class is a meta-memento.  It encapuslates the concept of having a sequence of mementos behave as a memento.
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+
+	public class MementoList implements IMemento
+	{
+		private var _mementoList:Array;
+		/**
+		 * MementoList is a memento made of a list of other mementos
+		 */
+		public function MementoList(textFlow:ITextFlow)
+		{ 
+		}
+		
+		public function push(memento:IMemento):void
+		{
+			if (memento)
+				mementoList.push(memento);
+		}
+		
+		private function get mementoList():Array
+		{
+			if(!_mementoList)
+				_mementoList = [];
+			
+			return _mementoList;
+		}
+		
+		public function undo():*
+		{
+			var retVal:Array = [];
+			if(_mementoList)
+			{
+				_mementoList.reverse();
+				for each (var memento:IMemento in  _mementoList)
+					retVal.push(memento.undo());
+				_mementoList.reverse();
+			}
+			
+			return retVal; 
+		}
+		
+		public function redo():*
+		{
+			var retVal:Array = [];
+			for each (var memento:IMemento in  _mementoList)
+				retVal.push(memento.redo());
+			return retVal;	
+		}
+	}
+}
\ 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/edit/ModelEdit.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/edit/ModelEdit.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/edit/ModelEdit.as
new file mode 100644
index 0000000..f7507c1
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/edit/ModelEdit.as
@@ -0,0 +1,159 @@
+// //////////////////////////////////////////////////////////////////////////////
+//
+// 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.edit
+{
+	import org.apache.flex.textLayout.debug.assert;
+	import org.apache.flex.textLayout.edit.mementos.AddElementMemento;
+	import org.apache.flex.textLayout.edit.mementos.DeleteTextMemento;
+	import org.apache.flex.textLayout.edit.mementos.JoinMemento;
+	import org.apache.flex.textLayout.edit.mementos.MoveElementMemento;
+	import org.apache.flex.textLayout.edit.mementos.RemoveElementsMemento;
+	import org.apache.flex.textLayout.edit.mementos.SplitMemento;
+	import org.apache.flex.textLayout.edit.mementos.TextRangeMemento;
+	import org.apache.flex.textLayout.elements.ElementHelper;
+	import org.apache.flex.textLayout.elements.IFlowElement;
+	import org.apache.flex.textLayout.elements.IFlowGroupElement;
+	import org.apache.flex.textLayout.elements.IFlowLeafElement;
+	import org.apache.flex.textLayout.elements.IListItemElement;
+	import org.apache.flex.textLayout.elements.IParagraphElement;
+	import org.apache.flex.textLayout.elements.ISpanElement;
+	import org.apache.flex.textLayout.elements.ITextFlow;
+
+	// [ExcludeClass]
+	/** 
+	 * The ModelEdit class contains static functions for performing speficic suboperations.  Each suboperation returns a "memento" for undo/redo.
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	public class ModelEdit
+	{
+		public static function splitElement(textFlow:ITextFlow, elemToSplit:IFlowGroupElement, relativePosition:int):IMemento
+		{
+			return SplitMemento.perform(textFlow, elemToSplit, relativePosition, true);
+		}
+
+		public static function joinElement(textFlow:ITextFlow, element1:IFlowGroupElement, element2:IFlowGroupElement):IMemento
+		{
+			return JoinMemento.perform(textFlow, element1, element2, true);
+		}
+
+		public static function addElement(textFlow:ITextFlow, elemToAdd:IFlowElement, parent:IFlowGroupElement, index:int):IMemento
+		{
+			CONFIG::debug
+			{
+				assert(elemToAdd.parent == null, "Use moveElement"); }
+			return AddElementMemento.perform(textFlow, elemToAdd, parent, index, true);
+		}
+
+		public static function moveElement(textFlow:ITextFlow, elemToMove:IFlowElement, parent:IFlowGroupElement, index:int):IMemento
+		{
+			CONFIG::debug
+			{
+				assert(elemToMove.parent != null, "Use addElement"); }
+			return MoveElementMemento.perform(textFlow, elemToMove, parent, index, true);
+		}
+
+		public static function removeElements(textFlow:ITextFlow, elemtToRemoveParent:IFlowGroupElement, startIndex:int, numElements:int):IMemento
+		{
+			return RemoveElementsMemento.perform(textFlow, elemtToRemoveParent, startIndex, numElements, true);
+		}
+
+		public static function deleteText(textFlow:ITextFlow, absoluteStart:int, absoluteEnd:int, createMemento:Boolean):IMemento
+		{
+			var memento:MementoList;
+			var mergePara:IParagraphElement;
+
+			// Special case to see if the whole of the last element of the flow is selected. If so, force the terminator at the end to be deleted
+			// so that if there is a list or a div at the end, it will be entirely removed.
+			if (absoluteEnd == textFlow.textLength - 1)
+			{
+				var lastElement:IFlowElement = textFlow.getChildAt(textFlow.numChildren - 1);
+				if (absoluteStart <= lastElement.getAbsoluteStart())
+					absoluteEnd = textFlow.textLength;
+			}
+
+			// Special case for when the last paragraph in the flow is deleted. We clone the last paragraph
+			// before letting the delete get processed. This lets whatever hierarchy is associated with the
+			// old last paragraph die a natural death, but doesn't leave the flow with no terminator.
+			var newLastParagraph:IParagraphElement;
+			if (absoluteEnd >= textFlow.textLength)
+			{
+				var lastSpan:IFlowLeafElement = textFlow.getLastLeaf();
+				var lastParagraph:IParagraphElement = lastSpan.getParagraph();
+				newLastParagraph = ElementHelper.getParagraph();
+				var newLastSpan:ISpanElement = ElementHelper.getSpan();
+				newLastParagraph.replaceChildren(0, 0, newLastSpan);
+				newLastParagraph.format = lastParagraph.format;
+				newLastSpan.format = lastSpan.format;
+				absoluteEnd = textFlow.textLength;
+			}
+
+			if (createMemento)
+			{
+				memento = new MementoList(textFlow);
+				if (newLastParagraph)
+					memento.push(addElement(textFlow, newLastParagraph, textFlow, textFlow.numChildren));
+				var deleteTextMemento:DeleteTextMemento = new DeleteTextMemento(textFlow, absoluteStart, absoluteEnd);
+				memento.push(deleteTextMemento);
+
+				mergePara = TextFlowEdit.deleteRange(textFlow, absoluteStart, absoluteEnd);
+				memento.push(TextFlowEdit.joinNextParagraph(mergePara, false));
+				checkNormalize(textFlow, deleteTextMemento.commonRoot, memento);
+			}
+			else
+			{
+				if (newLastParagraph)
+					textFlow.replaceChildren(textFlow.numChildren, textFlow.numChildren, newLastParagraph);
+				mergePara = TextFlowEdit.deleteRange(textFlow, absoluteStart, absoluteEnd);
+				TextFlowEdit.joinNextParagraph(mergePara, false);
+			}
+
+			if (textFlow.interactionManager)
+				textFlow.interactionManager.notifyInsertOrDelete(absoluteStart, -(absoluteEnd - absoluteStart));
+
+			return memento;
+		}
+
+		/**
+		 * @flexjsignorecoercion org.apache.flex.textLayout.elements.IFlowGroupElement
+		 */
+		private static function checkNormalize(textFlow:ITextFlow, commonRoot:IFlowGroupElement, mementoList:MementoList):void
+		{
+			if ((commonRoot is IListItemElement) && (commonRoot as IListItemElement).normalizeNeedsInitialParagraph())
+			{
+				var paragraph:IParagraphElement = ElementHelper.getParagraph();
+				paragraph.replaceChildren(0, 0, ElementHelper.getSpan());
+				mementoList.push(addElement(textFlow, paragraph, commonRoot, 0));
+			}
+			for (var index:int = 0; index < commonRoot.numChildren; ++index)
+			{
+				var child:IFlowGroupElement = commonRoot.getChildAt(index) as IFlowGroupElement;
+				if (child)
+					checkNormalize(textFlow, child, mementoList);
+			}
+		}
+
+		public static function saveCurrentState(textFlow:ITextFlow, absoluteStart:int, absoluteEnd:int):IMemento
+		{
+			return new TextRangeMemento(textFlow, absoluteStart, absoluteEnd);
+		}
+	}
+}
\ 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/edit/ParaEdit.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/edit/ParaEdit.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/edit/ParaEdit.as
new file mode 100644
index 0000000..bdfbc88
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/edit/ParaEdit.as
@@ -0,0 +1,673 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.edit
+{
+	import org.apache.flex.textLayout.container.IContainerController;
+	import org.apache.flex.textLayout.debug.assert;
+	import org.apache.flex.textLayout.elements.ElementHelper;
+	import org.apache.flex.textLayout.elements.IFlowElement;
+	import org.apache.flex.textLayout.elements.IFlowGroupElement;
+	import org.apache.flex.textLayout.elements.IFlowLeafElement;
+	import org.apache.flex.textLayout.elements.IParagraphElement;
+	import org.apache.flex.textLayout.elements.ISpanElement;
+	import org.apache.flex.textLayout.elements.ITextFlow;
+	import org.apache.flex.textLayout.elements.IInlineGraphicElement;
+	import org.apache.flex.textLayout.elements.ISubParagraphGroupElementBase;
+	import org.apache.flex.textLayout.elements.ITableElement;
+	import org.apache.flex.textLayout.elements.ITableLeafElement;
+	import org.apache.flex.textLayout.formats.ITextLayoutFormat;
+	import org.apache.flex.textLayout.formats.TextLayoutFormat;
+
+	// [ExcludeClass]
+	/**
+	 * Encapsulates all methods necessary for dynamic editing of a text.  The methods are all static member functions of this class.
+	 * @private - because we can't make it tlf_internal. Used by the operations package 
+	 */
+ 	public class ParaEdit
+	{
+		/**
+		 * Inserts text into specified paragraph
+		 * @param textFlow		ITextFlow to insert into
+		 * @param absoluteStart	index relative to beginning of the ITextFlow to insert text
+		 * @param text	actual text to insert 
+		 * @param createNewSpan	flag to force creation of a new span
+		 */
+		public static function insertText(textFlow:ITextFlow, absoluteStart:int,insertText:String, createNewSpan:Boolean):ISpanElement
+		{
+			if (insertText.length == 0)
+				return null;	// error? other sanity checks needed here?
+				
+			var sibling:IFlowElement = textFlow.findLeaf(absoluteStart);
+			var siblingIndex:int;
+			var paragraph:IParagraphElement = sibling.getParagraph();
+			var paraStart:int = paragraph.getAbsoluteStart();
+			var paraSelBegIdx:int = absoluteStart - paraStart;
+			
+			if (paraStart == absoluteStart)		// insert to start of paragraph
+				siblingIndex = 0;
+			else 
+			{
+				// If we're at the start a span, go to the previous span in the same paragraph, and insert at the end of it
+				if (paraSelBegIdx == sibling.getElementRelativeStart(paragraph))
+					sibling = IFlowLeafElement(sibling).getPreviousLeaf(paragraph);
+				if(sibling is ITableLeafElement)
+					siblingIndex = sibling.parent.parent.getChildIndex(sibling.parent) + 1;
+				else
+					siblingIndex = sibling.parent.getChildIndex(sibling) + 1;
+			}
+			var insertParent:IFlowGroupElement = sibling.parent;
+			if(insertParent is ITableElement)
+				insertParent = insertParent.parent;
+			
+			// If we are adding text to the start or end of a link, it doesn't allow the insertion to group with the link.
+			// So in that case, we will insert to the element beside the position that is *not* part of the link.
+			var curSPGElement:ISubParagraphGroupElementBase = sibling.getParentByType("SubParagraphGroupElementBase") as ISubParagraphGroupElementBase;
+			while (curSPGElement != null)
+			{
+				var subParInsertionPoint:int = paraSelBegIdx - curSPGElement.getElementRelativeStart(paragraph);
+				if (((subParInsertionPoint == 0) && (!curSPGElement.acceptTextBefore())) ||
+					((!curSPGElement.acceptTextAfter() && (subParInsertionPoint == curSPGElement.textLength || 
+					(subParInsertionPoint == curSPGElement.textLength - 1 && (sibling == paragraph.getLastLeaf()))))))
+				{
+					createNewSpan = true;
+					sibling = insertParent;
+					insertParent = insertParent.parent;
+					curSPGElement = curSPGElement.getParentByType("SubParagraphGroupElementBase") as ISubParagraphGroupElementBase;
+					siblingIndex = insertParent.getChildIndex(sibling) + 1;
+				} else {
+					break;
+				}
+			}
+			// adjust the flow so that we are in a span for the insertion
+			var insertSpan:ISpanElement = sibling as ISpanElement;
+			
+			// use the terminator span if it's empty
+			if(paragraph.terminatorSpan.textLength == 1 && paragraph.terminatorSpan == insertSpan)
+				createNewSpan = false;
+			
+			if (!insertSpan || createNewSpan)
+			{
+				var newSpan:ISpanElement = ElementHelper.getSpan();
+//				var insertIdx:int;
+				if (siblingIndex > 0)
+				{
+					var relativeStart:int = paraSelBegIdx - sibling.getElementRelativeStart(paragraph);
+					if (createNewSpan)
+					{
+						if (relativeStart == 0)
+							siblingIndex--;
+						else if (relativeStart != sibling.textLength)
+							sibling.splitAtPosition(relativeStart);		// we'll insert between the two elements
+					}
+				}
+				var nextLeaf:IFlowLeafElement = paragraph.findLeaf(paraSelBegIdx);
+				if(nextLeaf && nextLeaf.textLength == 1 && nextLeaf.parent == insertParent && nextLeaf == paragraph.terminatorSpan)
+				{
+					// use the terminator span instead of inserting a new one.
+					newSpan = ISpanElement(nextLeaf);
+				}
+				else {
+					insertParent.replaceChildren(siblingIndex, siblingIndex, newSpan);
+				}
+				var formatElem:IFlowLeafElement = newSpan.getPreviousLeaf(paragraph);
+				if (formatElem == null)
+					newSpan.format = newSpan.getNextLeaf(paragraph).format;
+				else
+					newSpan.format = formatElem.format;
+					
+				insertSpan = newSpan;
+			}
+			
+			var runInsertionPoint:int = paraSelBegIdx - insertSpan.getElementRelativeStart(paragraph);
+			
+				
+			insertSpan.replaceText(runInsertionPoint, runInsertionPoint, insertText);
+			return insertSpan;
+		}
+		
+		private static function deleteTextInternal(para:IParagraphElement, paraSelBegIdx:int, totalToDelete:int):void
+		{
+			var composeNode:IFlowElement;
+			var curSpan:ISpanElement;
+			
+			var curNumToDelete:int;
+			var curSpanDeletePos:int = 0;
+			
+			while (totalToDelete > 0)
+			{
+				composeNode = para.findLeaf(paraSelBegIdx);
+				CONFIG::debug { assert(composeNode is ISpanElement,"deleteTextInternal: leaf element is not a span"); }
+								
+				curSpan = composeNode as ISpanElement;
+				var curSpanRelativeStart:int = curSpan.getElementRelativeStart(para);
+				curSpanDeletePos = paraSelBegIdx - curSpanRelativeStart;
+				if (paraSelBegIdx > (curSpanRelativeStart + curSpan.textLength))
+				{
+					curNumToDelete = curSpan.textLength;
+				}
+				else
+				{
+					curNumToDelete = (curSpanRelativeStart + curSpan.textLength) - paraSelBegIdx;
+				}
+				
+				if (totalToDelete < curNumToDelete)
+				{
+					curNumToDelete = totalToDelete;
+				}
+				
+				curSpan.replaceText(curSpanDeletePos, curSpanDeletePos + curNumToDelete, "");
+				if (curSpan.textLength == 0)
+				{
+					var delIdx:int = curSpan.parent.getChildIndex(curSpan);
+					curSpan.parent.replaceChildren(delIdx,delIdx+1,null);						
+				}
+				totalToDelete -= curNumToDelete;
+			}			
+		}
+		
+		public static function deleteText(para:IParagraphElement, paraSelBegIdx:int, totalToDelete:int):void
+		{
+			var lastParPos:int = para.textLength - 1;
+			if ((paraSelBegIdx < 0) || (paraSelBegIdx > lastParPos))
+			{
+				//not much we can do. There's nothing to delete in this paragraph
+				return;
+			}
+			
+			if (totalToDelete <= 0)
+			{
+				//can't delete a negative number of characters... just return
+				return;
+			}
+			
+			var endPos:int = paraSelBegIdx + totalToDelete - 1;
+			if (endPos > lastParPos)
+			{
+				endPos = lastParPos;
+				totalToDelete = endPos - paraSelBegIdx + 1;
+			}
+			
+			deleteTextInternal(para,paraSelBegIdx,totalToDelete);
+		}
+		
+		/**
+		 * Creates image and inserts it into specified FlowGroupElement
+		 * @param flowBlock	FlowGroupElement to insert image into
+		 * @param flowSelBegIdx	index relative to beginning of the FlowGroupElement to insert image
+		 * @param urlString	the url of image to insert
+		 * @param width	the width of the image
+		 * @param height the height of the image
+		 * @param options none supported
+		 * @flexjsignorecoercion org.apache.flex.textLayout.element.ISpanElement
+		 */
+		public static function createImage(flowBlock:IFlowGroupElement, flowSelBegIdx:int,source:Object, width:Object, height:Object, options:Object, pointFormat:ITextLayoutFormat):IInlineGraphicElement
+		{
+			//first, split the element that we are on
+			var curComposeNode:IFlowElement = flowBlock.findLeaf(flowSelBegIdx);
+			var posInCurComposeNode:int = 0;
+			if (curComposeNode != null)
+			{
+				posInCurComposeNode = flowSelBegIdx - curComposeNode.getElementRelativeStart(flowBlock); // curComposeNode.parentRelativeStart;
+			}			
+			
+			if ((curComposeNode != null) && (posInCurComposeNode > 0) && (posInCurComposeNode < curComposeNode.textLength))
+			{
+				//it is a LeafElement, and not position 0. It has to be a Span 
+				(curComposeNode as ISpanElement).splitAtPosition(posInCurComposeNode);
+			}
+			
+			//the FlowElement or FlowGroupElement is now split.  Insert the image now.
+			var imgElem:IInlineGraphicElement = ElementHelper.getInline();
+			imgElem.height = height;
+			imgElem.width = width;
+			imgElem.float = options ? options.toString() : undefined;
+			
+			var src:Object = source;
+			var embedStr:String = "@Embed";
+			if (src is String && src.length > embedStr.length && src.substr(0, embedStr.length) == embedStr) {
+				// we should be dealing with an embedded asset. They are of the form "url=@Embed(source='path-to-asset')"
+				var searchStr:String = "source=";
+				var index:int = src.indexOf(searchStr, embedStr.length);
+				if (index > 0) {
+					index += searchStr.length;
+					index = src.indexOf("'", index);
+					src = src.substring(index+1, src.indexOf("'", index+1));
+				}
+			}
+			imgElem.source = src;
+			
+			while (curComposeNode && curComposeNode.parent != flowBlock)
+			{
+				curComposeNode = curComposeNode.parent;
+			}
+
+			var elementIdx:int = curComposeNode != null ? flowBlock.getChildIndex(curComposeNode) : flowBlock.numChildren;
+			if (curComposeNode && posInCurComposeNode > 0)
+				elementIdx++;
+			flowBlock.replaceChildren(elementIdx,elementIdx,imgElem);
+			
+			//clone characterFormat from the left OR iff the the first element the right
+			var p:IParagraphElement = imgElem.getParagraph();
+			var attrElem:IFlowLeafElement = imgElem.getPreviousLeaf(p);
+			if (!attrElem)
+				attrElem = imgElem.getNextLeaf(p);
+			CONFIG::debug { assert(attrElem != null, "no element to get attributes from"); }
+			
+			if (attrElem.format || pointFormat)
+			{
+				var imageElemFormat:TextLayoutFormat = new TextLayoutFormat(attrElem.format);
+				if (pointFormat)
+					imageElemFormat.apply(pointFormat);
+				imgElem.format = imageElemFormat;
+			}
+			return imgElem;			
+		}		
+		
+		/** Merge changed attributes into this
+		 */
+		static private function splitForChange(span:ISpanElement,begIdx:int,rangeLength:int):ISpanElement
+		{
+			var startOffset:int = span.getAbsoluteStart();
+			if (begIdx == startOffset && rangeLength == span.textLength)
+				return span;
+				
+			// element must be split into spans
+			var elemToUpdate:ISpanElement;
+			var origLength:int = span.textLength;
+			
+			var begRelativeIdx:int = begIdx - startOffset;
+			if (begRelativeIdx > 0)
+			{
+				// We create an initial span to hold the text before the new span, then
+				// a following span for the specified range.
+				elemToUpdate = span.splitAtPosition(begRelativeIdx) as ISpanElement;
+				if (begRelativeIdx + rangeLength < origLength)
+					elemToUpdate.splitAtPosition(rangeLength);
+			}
+			else
+			{
+				// The specified range falls at the start of the element, so this span is the 
+				// one that's getting the new format.
+				span.splitAtPosition(rangeLength);
+				elemToUpdate = span;
+			}
+
+			return elemToUpdate;
+		}
+		
+		private static function undefineDefinedFormats(target:TextLayoutFormat,undefineFormat:ITextLayoutFormat):void
+		{
+			if (undefineFormat)
+			{
+				// this is fairly rare so this operation is not optimizied
+				var tlfUndefineFormat:TextLayoutFormat;
+				if (undefineFormat is TextLayoutFormat)
+					tlfUndefineFormat = undefineFormat as TextLayoutFormat;
+				else 
+					tlfUndefineFormat = new TextLayoutFormat(undefineFormat);
+				for (var prop:String in tlfUndefineFormat.styles)
+					target.setStyle(prop, undefined);
+			}
+		}
+
+		/**
+		 * Apply formatting changes to a range of text in the FlowElement
+		 *
+		 * @param begIdx	text index of first text in span
+		 * @param rangeLength	number of characters to modify
+		 * @param applyFormat		Character Format to apply to content
+		 * @param undefineFormat	Character Format to undefine to content
+		 * @return begIdx + number of actual actual characters modified.
+		 */
+		static private function applyCharacterFormat(leaf:IFlowLeafElement, begIdx:int, rangeLength:int, applyFormat:ITextLayoutFormat, undefineFormat:ITextLayoutFormat):int
+		{
+			var newFormat:TextLayoutFormat = new TextLayoutFormat(leaf.format);
+			if (applyFormat)
+				newFormat.apply(applyFormat);
+			undefineDefinedFormats(newFormat,undefineFormat);
+			return setCharacterFormat(leaf, newFormat, begIdx, rangeLength);
+		}
+		
+		/**
+		 * Set formatting to a range of text in the FlowElement
+		 *
+		 * @param format	Character Format to apply to content
+		 * @param begIdx	text index of first text in span
+		 * @param rangeLength	number of characters to modify
+		 * @return starting position of following span
+		 */
+		static private function setCharacterFormat(leaf:IFlowLeafElement, format:ITextLayoutFormat, begIdx:int, rangeLength:int):int
+		{
+			var startOffset:int = leaf.getAbsoluteStart();
+			if (!(format is ITextLayoutFormat) || !TextLayoutFormat.isEqual(ITextLayoutFormat(format),leaf.format))
+			{				
+//				var para:IParagraphElement = leaf.getParagraph();
+//				var paraStartOffset:int = para.getAbsoluteStart();
+				
+				// clip rangeLength to the length of this span. Extend the rangeLength by one to include the terminator if
+				// it is in the span, and the end of the range abuts the terminator. That way the terminator will stay in the 
+				// last span.
+				var begRelativeIdx:int = begIdx - startOffset;
+				if (begRelativeIdx + rangeLength > leaf.textLength)
+					rangeLength = leaf.textLength - begRelativeIdx;
+				if (begRelativeIdx + rangeLength == leaf.textLength - 1 && (leaf is ISpanElement) && ISpanElement(leaf).hasParagraphTerminator)
+					++rangeLength;
+				
+				var elemToUpdate:IFlowLeafElement;
+				if (leaf is ISpanElement)
+					elemToUpdate = splitForChange(ISpanElement(leaf),begIdx,rangeLength);
+				else
+				{
+					CONFIG::debug { assert(rangeLength >= leaf.textLength,"unable to split non-span leaf"); }
+					elemToUpdate = leaf;
+				}
+				
+				if (format is ITextLayoutFormat)
+					elemToUpdate.format = ITextLayoutFormat(format);
+				else
+					elemToUpdate.setStylesInternal(format);
+				
+				return begIdx+rangeLength;
+			}
+			
+			rangeLength = leaf.textLength;
+			return startOffset+rangeLength;
+		}
+		
+		public static function applyTextStyleChange(flowRoot:ITextFlow,begChange:int,endChange:int,applyFormat:ITextLayoutFormat,undefineFormat:ITextLayoutFormat):void
+		{	
+			// TODO: this code only works for span's.  Revisit when new FlowLeafElement types enabled
+			var workIdx:int = begChange;
+			while (workIdx < endChange)
+			{
+				var elem:IFlowLeafElement = flowRoot.findLeaf(workIdx);
+				CONFIG::debug  { assert(elem != null,"null FlowLeafElement found"); }
+				workIdx = applyCharacterFormat(elem,workIdx,endChange-workIdx,applyFormat,undefineFormat); 
+			}
+		}
+		
+		// used for undo of operation
+		public static function setTextStyleChange(flowRoot:ITextFlow,begChange:int, endChange:int, coreStyle:ITextLayoutFormat):void
+		{
+			// TODO: this code only works for span's.  Revisit when new FlowLeafElement types enabled
+			var workIdx:int = begChange;
+			while (workIdx < endChange)
+			{
+				var elem:IFlowElement = flowRoot.findLeaf(workIdx);
+				CONFIG::debug  { assert(elem != null,"null FlowLeafElement found"); }
+				workIdx = setCharacterFormat(IFlowLeafElement(elem),coreStyle,workIdx,endChange-workIdx);
+			}
+		}
+		
+		/**
+		 * @flexjsignorecoercion org.apache.flex.textLayout.elements.IFlowGroupElement
+		 */
+		public static function splitElement(elem:IFlowGroupElement, splitPos:int):IFlowGroupElement
+		{
+			CONFIG::debug { assert(splitPos >= 0 && splitPos <= elem.textLength, "Invalid call to ParaEdit.splitElement"); }
+			
+			var rslt:IFlowGroupElement = elem.splitAtPosition(splitPos) as IFlowGroupElement;
+			
+			// rslt always follows elem
+			
+
+			if (!(rslt is ISubParagraphGroupElementBase))
+			{
+				
+				// need to insure there is a paragraph and a span on each side
+				var rsltParagraph:IFlowGroupElement = rslt;
+				while (!(rsltParagraph is IParagraphElement) && rsltParagraph.numChildren)
+					rsltParagraph = rsltParagraph.getChildAt(0) as IFlowGroupElement;
+				
+				var elemParagraph:IFlowGroupElement = elem;
+				while (!(elemParagraph is IParagraphElement) && elemParagraph.numChildren)
+					elemParagraph = elemParagraph.getChildAt(elemParagraph.numChildren-1) as IFlowGroupElement;
+				
+				CONFIG::debug { assert (elemParagraph is IParagraphElement || rsltParagraph is IParagraphElement,"ParaEdit.splitElement didn't find at least one paragraph"); }
+				
+				var p:IParagraphElement;
+				
+				if (!(elemParagraph is IParagraphElement))
+				{
+					// clone rlstParagraph
+					p = rsltParagraph.shallowCopy() as IParagraphElement;
+					elemParagraph.addChild(p);
+					elemParagraph = p;
+				}
+				else if (!(rsltParagraph is IParagraphElement))
+				{
+					p = elemParagraph.shallowCopy() as IParagraphElement;
+					rsltParagraph.addChild(p);
+					rsltParagraph = p;						
+				}
+				
+				// if we have an empty before or after para need to make sure the formats got copied
+				if (elemParagraph.textLength <= 1)
+				{
+					elemParagraph.normalizeRange(0,elemParagraph.textLength);
+					elemParagraph.getLastLeaf().quickCloneTextLayoutFormat(rsltParagraph.getFirstLeaf());
+				}
+				else if (rsltParagraph.textLength <= 1)
+				{
+					rsltParagraph.normalizeRange(0,rsltParagraph.textLength);
+					rsltParagraph.getFirstLeaf().quickCloneTextLayoutFormat(elemParagraph.getLastLeaf());
+				}
+			}
+
+			return rslt;
+		}		
+		// TODO: rewrite this method by moving the elements.  This is buggy.
+		/**
+		 * @flexjsignorecoercion org.apache.flex.textLayout.element.IParagraphElement
+		 */
+		public static function mergeParagraphWithNext(para:IParagraphElement):Boolean
+		{
+			var indexOfPara:int = para.parent.getChildIndex(para);
+			
+			// last can't merge
+			if (indexOfPara == para.parent.numChildren-1)
+				return false;
+				
+			var nextPar:IParagraphElement  = para.parent.getChildAt(indexOfPara + 1) as IParagraphElement;
+			// next is not a paragraph
+			if (nextPar == null)
+				return false;
+				
+			// remove nextPar from its parent - do this first because it will require less updating of starts and lengths
+			para.parent.replaceChildren(indexOfPara+1,indexOfPara+2,null);
+			if (nextPar.textLength <= 1) 
+				return true;
+			
+			// move all the elements
+			while (nextPar.numChildren)
+			{
+				var elem:IFlowElement = nextPar.getChildAt(0);
+				nextPar.replaceChildren(0,1,null);
+				para.replaceChildren(para.numChildren,para.numChildren,elem);
+				if ((para.numChildren >  1) && (para.getChildAt(para.numChildren - 2).textLength == 0))
+				{
+					//bug 1658164
+					//imagine that the last element of para is only a kParaTerminator (like a single
+					//span of length 1 that only contains a kParaTerminator, and you merge with the
+					//next paragraph. That kParaTerminator will move, leaving an empty leaf element
+					para.replaceChildren(para.numChildren - 2, para.numChildren - 1, null);
+				}
+			}
+
+			return true;
+		}
+		
+		public static function cacheParagraphStyleInformation(flowRoot:ITextFlow,begSel:int,endSel:int,undoArray:Array):void
+		{
+			while (begSel <= endSel && begSel >= 0)
+			{
+				var para:IParagraphElement = flowRoot.findLeaf(begSel).getParagraph();
+				
+				// build an object holding the old style and format
+				var obj:Object = {};
+				obj.begIdx = para.getAbsoluteStart();
+				obj.endIdx = obj.begIdx + para.textLength - 1;
+				obj.attributes = new TextLayoutFormat(para.format);
+				undoArray.push(obj);
+
+				begSel = obj.begIdx + para.textLength;
+			}
+		}
+
+		/**
+		 * Replace the existing paragraph attributes with the incoming attributes.
+		 * 
+		 * @param flowRoot	text flow where paragraphs are
+		 * @param format	attributes to apply
+		 * @param beginIndex	text index within the first paragraph in the range
+		 * @param endIndex		text index within the last paragraph in the range
+		 */
+		// used for undo of operation
+		public static function setParagraphStyleChange(flowRoot:ITextFlow,begChange:int, endChange:int, format:ITextLayoutFormat):void
+		{
+			var beginPara:int = begChange;
+			while (beginPara <= endChange)
+			{
+				var para:IParagraphElement = flowRoot.findLeaf(beginPara).getParagraph();
+				
+				para.format = format ? new TextLayoutFormat(format) : null;
+				beginPara = para.getAbsoluteStart() + para.textLength;
+			}
+		}
+		
+		/**
+		 * Additively apply the paragraph formating attributes to the paragraphs in the specified range.
+		 * Each non-null field in the incoming format is copied into the existing paragraph attributes.
+		 * 
+		 * @param flowRoot	text flow where paragraphs are
+		 * @param format	attributes to apply
+		 * @param beginIndex	text index within the first paragraph in the range
+		 * @param endIndex		text index within the last paragraph in the range
+		 */
+		public static function applyParagraphStyleChange(flowRoot:ITextFlow,begChange:int,endChange:int,applyFormat:ITextLayoutFormat,undefineFormat:ITextLayoutFormat):void
+		{	
+			var curIndex:int = begChange;
+			while (curIndex <= endChange)
+			{
+				var leaf:IFlowLeafElement = flowRoot.findLeaf(curIndex);
+				if (!leaf)
+					break;
+				var para:IParagraphElement = leaf.getParagraph();
+				
+				// now, need to get the change from "format" and apply to para. We make
+				// a new ParagraphFormat object instead of changing the ParagraphFormat
+				// already in the paragraph so that if the object is shared, other uses
+				// in other paragraphs will not be affected.
+				var newFormat:TextLayoutFormat = new TextLayoutFormat(para.format);
+				if (applyFormat)
+					newFormat.apply(applyFormat);
+				undefineDefinedFormats(newFormat,undefineFormat);
+				para.format = newFormat;
+				
+				curIndex = para.getAbsoluteStart() + para.textLength;
+			}		
+		}
+
+		public static function cacheStyleInformation(flowRoot:ITextFlow,begSel:int,endSel:int,undoArray:Array):void
+		{
+			var elem:IFlowElement = flowRoot.findLeaf(begSel);
+			var elemLength:int = elem.getAbsoluteStart()+elem.textLength-begSel;
+			var countRemaining:int = endSel - begSel;
+			CONFIG::debug { assert(countRemaining != 0,"cacheStyleInformation called on point selection"); }
+			for (;;)
+			{
+				// build an object holding the old style and format
+				var obj:Object = {};
+
+				obj.begIdx = begSel;
+				var objLength:int = Math.min(countRemaining, elemLength);
+				obj.endIdx = begSel + objLength;
+				
+				// just the styles
+				obj.style = new TextLayoutFormat(elem.format);
+				undoArray.push(obj);
+				
+				countRemaining -= Math.min(countRemaining, elemLength);
+				if (countRemaining == 0)
+					break;
+				
+				// advance
+				begSel = obj.endIdx;
+				
+				elem = flowRoot.findLeaf(begSel);
+				elemLength = elem.textLength;
+			}
+		}
+		
+		public static function cacheContainerStyleInformation(flowRoot:ITextFlow,begIdx:int,endIdx:int,undoArray:Array):void
+		{
+			CONFIG::debug { assert(begIdx <= endIdx,"bad indexeds passed to ParaEdit.cacheContainerStyleInformation");  }
+			if (flowRoot.flowComposer)
+			{
+				var ctrlrBegIdx:int = flowRoot.flowComposer.findControllerIndexAtPosition(begIdx,false);
+				if (ctrlrBegIdx == -1)
+					return;
+				var ctrlrEndIdx:int = flowRoot.flowComposer.findControllerIndexAtPosition(endIdx,true);
+				if (ctrlrEndIdx == -1)
+					ctrlrEndIdx = flowRoot.flowComposer.numControllers-1;
+				while (ctrlrBegIdx <= ctrlrEndIdx)
+				{
+					var controller:IContainerController = flowRoot.flowComposer.getControllerAt(ctrlrBegIdx);
+					var obj:Object = {};
+					obj.container = controller;
+					// save just the styles
+					obj.attributes = new TextLayoutFormat(controller.format);
+					undoArray.push(obj);
+					ctrlrBegIdx++;
+				}
+			}
+		}
+
+		public static function applyContainerStyleChange(flowRoot:ITextFlow,begIdx:int,endIdx:int,applyFormat:ITextLayoutFormat,undefineFormat:ITextLayoutFormat):void
+		{
+			CONFIG::debug { assert(begIdx <= endIdx,"bad indexes passed to ParaEdit.cacheContainerStyleInformation");  }
+			if (flowRoot.flowComposer)
+			{
+				var ctrlrBegIdx:int = flowRoot.flowComposer.findControllerIndexAtPosition(begIdx,false);
+				if (ctrlrBegIdx == -1)
+					return;
+				var ctrlrEndIdx:int = flowRoot.flowComposer.findControllerIndexAtPosition(endIdx,true);
+				if (ctrlrEndIdx == -1)
+					ctrlrEndIdx = flowRoot.flowComposer.numControllers-1;
+//				var controllerIndex:int = flowRoot.flowComposer.findControllerIndexAtPosition(begIdx,false);
+				while (ctrlrBegIdx <= ctrlrEndIdx)
+				{
+					var controller:IContainerController = flowRoot.flowComposer.getControllerAt(ctrlrBegIdx);
+					var newFormat:TextLayoutFormat = new TextLayoutFormat(controller.format);
+					if (applyFormat)
+						newFormat.apply(applyFormat);
+					undefineDefinedFormats(newFormat,undefineFormat);
+					controller.format = newFormat;
+					ctrlrBegIdx++;
+				}
+			}
+		}
+
+		/** obj is created by cacheContainerStyleInformation */
+		public static function setContainerStyleChange(obj:Object):void
+		{
+			obj.container.format = obj.attributes as ITextLayoutFormat;
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/edit/PointFormat.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/edit/PointFormat.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/edit/PointFormat.as
new file mode 100644
index 0000000..d860374
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/edit/PointFormat.as
@@ -0,0 +1,148 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.edit
+{
+	import org.apache.flex.textLayout.elements.IFlowElement;
+	import org.apache.flex.textLayout.elements.FlowElement;
+	import org.apache.flex.textLayout.elements.ILinkElement;
+	import org.apache.flex.textLayout.elements.ITCYElement;
+	import org.apache.flex.textLayout.formats.ITextLayoutFormat;
+	import org.apache.flex.textLayout.formats.TextLayoutFormat;
+
+
+	
+	// [ExcludeClass]
+	/**
+	 * Contains the settings that apply to new text being typed.
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	public class PointFormat extends TextLayoutFormat implements ITextLayoutFormat
+	{
+		private var _id:*;
+		private var _linkElement:ILinkElement;
+		private var _tcyElement:ITCYElement;
+		
+		/** Constructor
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function PointFormat(initialValues:ITextLayoutFormat = null)
+		{
+			super(initialValues);
+		}
+		
+
+		static public function isEqual(p1:ITextLayoutFormat,p2:ITextLayoutFormat):Boolean
+		{
+			if (!TextLayoutFormat.isEqual(p1, p2))
+				return false;
+			if ((p1 is PointFormat) != (p2 is PointFormat))
+				return false;
+			if (p1 is PointFormat)
+			{
+				var pf1:PointFormat = p1 as PointFormat;
+				var pf2:PointFormat = p2 as PointFormat;
+				return pf1.id == pf2.id && isEqualLink(pf1.linkElement, pf2.linkElement) && 
+					(pf1.tcyElement == null) == (pf2.tcyElement == null);
+			}
+			return true;
+		}
+		
+		static private function isEqualLink(l1:ILinkElement, l2:ILinkElement):Boolean
+		{
+			if ((l1 == null) != (l2 == null))
+				return false;
+			if (l1 == null)
+				return true;
+			return l1.href == l2.href && l1.target == l2.target;
+		}
+		
+		
+		public function get linkElement():*
+		{
+			return _linkElement;
+		}
+		public function set linkElement(value:ILinkElement):void
+		{
+			_linkElement = value;
+		}
+
+		public function get tcyElement():*
+		{
+			return _tcyElement;
+		}
+		public function set tcyElement(value:ITCYElement):void
+		{
+			_tcyElement = value;
+		}
+		/**
+		 * Assigns an identifying name to the element, making it possible to set a style for the element
+		 * by referencing the <code>id</code>. 
+		 *
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * 
+		 * @see FlowElement#id
+		 */
+		public function get id():*
+		{
+			return _id;
+		}
+		public function set id(value:*):void
+		{
+			_id = value;
+		}
+ 
+		
+		public static function clone(original:PointFormat):PointFormat
+		{
+			var cloneFormat:PointFormat = new PointFormat(original);
+			cloneFormat.id = original.id;
+			cloneFormat.linkElement = (original.linkElement === undefined || !original.linkElement) ? original.linkElement : original.linkElement.shallowCopy() as ILinkElement;
+			cloneFormat.tcyElement = (original.tcyElement === undefined || !original.tcyElement) ? original.tcyElement : original.tcyElement.shallowCopy() as ITCYElement;
+			return cloneFormat;
+		}
+		
+		public static function createFromFlowElement(element:IFlowElement):PointFormat
+		{
+			if (!element)
+				return new PointFormat();
+			
+			var format:PointFormat = new PointFormat(element.format);
+			
+
+			var linkElement:ILinkElement = element.getParentByType("LinkElement") as ILinkElement;
+			if (linkElement)
+				format.linkElement = linkElement.shallowCopy() as ILinkElement;
+
+			var tcyElement:ITCYElement = element.getParentByType("TCYElement") as ITCYElement;
+			if (tcyElement)
+				format.tcyElement = tcyElement.shallowCopy() as ITCYElement;
+			
+			return format;
+		}
+	}
+}
\ 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/edit/SelectionFormat.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/edit/SelectionFormat.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/edit/SelectionFormat.as
new file mode 100644
index 0000000..a7b4652
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/edit/SelectionFormat.as
@@ -0,0 +1,207 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.edit {
+	
+	/**
+	 * The SelectionFormat class defines the properties of a selection highlight.
+	 * 
+	 * @see org.apache.flex.textLayout.edit.ISelectionManager
+	 * @see org.apache.flex.textLayout.edit.SelectionManager
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+	 */
+	public class SelectionFormat
+	{
+		private var _rangeColor:uint;
+		private var _rangeAlpha:Number;
+		private var _rangeBlendMode:String;
+		
+		private var _pointColor:uint;
+		private var _pointAlpha:Number;
+		private var _pointBlendMode:String;
+		private var _pointBlinkRate:Number;
+		
+		/** 
+		 * Creates a SelectionFormat object with the specified properties.
+		 * 
+		 * <p>A SelectionFormat created with the default values will use black for
+		 * the highlight colors, 1.0 for the alphas, and BlendMode.DIFFERENCE for the blending modes.
+		 * The cursor blink rate is 500 milliseconds.</p>
+		 *
+		 * <p>Setting the <code>pointAlpha</code> and <code>rangeAlpha</code> properties to zero disables selection highlighting.</p>
+		 * 
+		 * <p>Non-zero blink rate is only used when an EditManager is attached to the TextFlow.</p>
+		 * 
+		 * @param rangeColor The color for drawing the highlight.
+		 * @param rangeAlpha The transparency value for drawing the highlight. Valid values are between 0
+		 * (completely transparent) and 1 (completely opaque, which is the default).
+		 * @param rangeBlendMode The blend mode for drawing the highlight. Use constants defined in the BlendMode class
+		 * to set this parameter.
+		 * @param pointColor The color for the drawing cursor.
+		 * @param pointAlpha The transparency value for drawing the cursor. Valid values are between 0
+		 * (completely transparent) and 1 (completely opaque, which is the default).
+		 * @param pointBlendMode The blend mode for drawing the cursor. Use constants defined in the BlendMode class
+		 * to set this parameter.
+		 * @param pointBlinkRate The rate at which the cursor blinks, in milliseconds.
+		 * 
+		 * @see flash.display.BlendMode
+		 * @see #pointAlpha
+		 * @see #rangeAlpha
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function SelectionFormat(rangeColor:uint=0xffffff, rangeAlpha:Number=1.0, rangeBlendMode:String="difference", pointColor:uint=0xffffff, pointAlpha:Number=1.0, pointBlendMode:String="difference", pointBlinkRate:Number = 500)
+		{ 
+			_rangeColor = rangeColor;
+			_rangeAlpha = rangeAlpha;
+			_rangeBlendMode = rangeBlendMode;
+			
+			_pointColor = pointColor;
+			_pointAlpha = pointAlpha;
+			_pointBlendMode = pointBlendMode;
+			_pointBlinkRate = pointBlinkRate;
+		}
+		
+		/**
+		 * The color for drawing the highlight of a range selection. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */		
+		public function get rangeColor():uint
+		{
+			return _rangeColor;
+		}
+
+		/**
+		 * The alpha for drawing the highlight of a range selection. Valid values are between 0
+		 * (completely transparent) and 1 (completely opaque, which is the default).
+		 *
+		 * <p>Setting the <code>pointAlpha</code> and <code>rangeAlpha</code> properties to zero disables selection highlighting.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+ 	 	 *
+ 	 	 * @see #pointAlpha
+		 */						
+		public function get rangeAlpha():Number
+		{
+			return _rangeAlpha;
+		}
+
+		/**
+		 * The blending mode for drawing the highlight of a range selection. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 * @see flash.display.BlendMode
+		 */						
+		public function get rangeBlendMode():String
+		{
+			return _rangeBlendMode;
+		}
+		
+		/**
+		 * The color for drawing the cursor.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */		
+		public function get pointColor():uint
+		{
+			return _pointColor;
+		}
+
+		/**
+		 * The alpha for drawing the cursor. Valid values are between 0
+		 * (completely transparent) and 1 (completely opaque, which is the default).
+		 *
+		 * <p>Setting the <code>pointAlpha</code> and <code>rangeAlpha</code> properties to zero disables selection highlighting.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+ 	 	 *
+ 	 	 * @see #rangeAlpha
+		 */						
+		public function get pointAlpha():Number
+		{
+			return _pointAlpha;
+		}
+		
+		/**
+		 * The rate at which the cursor blinks, in milliseconds.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */						
+		public function get pointBlinkRate():Number
+		{
+			return _pointBlinkRate;
+		}		
+
+		/**
+		 * The blend mode for drawing the cursor.
+		 * 
+		 * @see flash.display.BlendMode
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */						
+		public function get pointBlendMode():String
+		{
+			return _pointBlendMode;
+		}
+
+		/**
+		 * Determines whether this SelectionFormat object has the same property values
+		 * as another SelectionFormat object.
+		 *  
+		 * @return <code>true</code>, if the property values are identical; <code>false</code>, otherwise.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 * 
+		 * @param selectionFormat	the SelectionFormat to compare against.
+		 */								
+		public function equals(selectionFormat:SelectionFormat):Boolean
+		{
+			if ((_rangeBlendMode == selectionFormat.rangeBlendMode) &&
+				(_rangeAlpha == selectionFormat.rangeAlpha) &&
+				(_rangeColor == selectionFormat.rangeColor) &&
+				(_pointColor == selectionFormat.pointColor) &&
+				(_pointAlpha == selectionFormat.pointAlpha) &&
+				(_pointBlendMode == selectionFormat.pointBlendMode) &&
+				(_pointBlinkRate == selectionFormat.pointBlinkRate))
+				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/edit/SelectionFormatState.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/edit/SelectionFormatState.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/edit/SelectionFormatState.as
new file mode 100644
index 0000000..f07356b
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/edit/SelectionFormatState.as
@@ -0,0 +1,38 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.edit
+{
+	// [ExcludeClass]
+	/**
+	 *  Values for the selection background state
+	 *
+	 *  @see text.edit.SelectionFormat
+	 */
+ 	public final class SelectionFormatState 
+ 	{
+		/** default selection format state */
+    	public static const FOCUSED:String = "focused";
+    
+		/** selection state when selection doesn't have focus */    
+    	public static const UNFOCUSED:String = "unfocused";
+    
+		/** selection state when SelectionManager is inactive */        
+    	public static const INACTIVE:String = "inactive";
+	}
+}