flex-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ha...@apache.org
Subject [04/42] flex-asjs git commit: And here’s TLF…
Date Thu, 16 Mar 2017 13:37:24 GMT
http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/CreateListOperation.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/CreateListOperation.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/CreateListOperation.as
new file mode 100644
index 0000000..1cb5011
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/CreateListOperation.as
@@ -0,0 +1,288 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.operations
+{
+	import org.apache.flex.textLayout.debug.assert;
+	import org.apache.flex.textLayout.edit.ElementMark;
+	import org.apache.flex.textLayout.edit.MementoList;
+	import org.apache.flex.textLayout.edit.ModelEdit;
+	import org.apache.flex.textLayout.edit.SelectionState;
+	import org.apache.flex.textLayout.elements.ElementHelper;
+	import org.apache.flex.textLayout.elements.IFlowGroupElement;
+	import org.apache.flex.textLayout.elements.IListElement;
+	import org.apache.flex.textLayout.elements.IListItemElement;
+	import org.apache.flex.textLayout.elements.IParagraphElement;
+	import org.apache.flex.textLayout.elements.ISubParagraphGroupElementBase;
+	import org.apache.flex.textLayout.formats.ITextLayoutFormat;
+
+	/**
+	 * The CreateListOperation class encapsulates creating list
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class CreateListOperation extends FlowTextOperation
+	{
+		// describes the target
+		private var _listParentMarker:ElementMark;
+		private var _mementoList:MementoList;
+
+		private var _listFormat:ITextLayoutFormat;
+		private var _listElement:IListElement;		// the element that gets created
+		
+		private var _postOpSelectionState:SelectionState;
+		
+		/** 
+		 * Creates an CreateListOperation object.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function CreateListOperation(operationState:SelectionState, parent:IFlowGroupElement = null, listFormat:ITextLayoutFormat = null)
+		{
+			super(operationState);
+			
+			this.parent = parent;
+			_listFormat = listFormat;
+			_mementoList = new MementoList(operationState.textFlow);
+		}
+		
+		/** 
+		 * Specifies the element this operation adds a new IListElement to.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 * @flexjsignorecoercion org.apache.flex.textLayout.elements.IFlowGroupElement
+		 */
+		public function get parent():IFlowGroupElement
+		{
+			return _listParentMarker ? _listParentMarker.findElement(originalSelectionState.textFlow) as IFlowGroupElement : null;
+		}
+		
+		/**
+		 * @flexjsignorecoercion org.apache.flex.textLayout.elements.IFlowGroupElement
+		 */
+		public function set parent(value:IFlowGroupElement):void
+		{
+			if (!value)
+			{
+				// descend to the lowest level non-paragraph element that contains both positions
+				// effectively make the new list as close to the spans as possible
+				value = textFlow;
+				
+				var begPos:int = this.absoluteStart;
+				var endPos:int = this.absoluteEnd;
+				for (;;)
+				{
+					var begChildIdx:int = value.findChildIndexAtPosition(begPos);
+					var elem:IFlowGroupElement = value.getChildAt(begChildIdx) as IFlowGroupElement;
+					if (elem is IParagraphElement)
+						break;
+					begPos -= elem.parentRelativeStart;
+					endPos -= elem.parentRelativeStart;
+					if (endPos >= elem.textLength)	// end pos is in the next element
+						break;
+					value = elem;
+				}
+			}
+			else if (value is ISubParagraphGroupElementBase)
+				value = value.getParagraph().parent;
+			
+			_listParentMarker = new ElementMark(value,0);
+		}
+
+		/** TextLayoutFormat to be applied to the new IListElement. 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */	
+		public function get listFormat():ITextLayoutFormat
+		{ return _listFormat; }
+		public function set listFormat(value:ITextLayoutFormat):void
+		{ _listFormat = value; }
+		
+		/** The new IListElement. 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */	
+		public function get newListElement():IListElement
+		{ return _listElement; }
+		
+		/**
+		 *  @private
+		 * @flexjsignorecoercion org.apache.flex.textLayout.elements.IFlowGroupElement
+		 */
+		public override function doOperation():Boolean
+		{
+			var target:IFlowGroupElement = parent;
+			
+			// find the starting child that's going to be in the list and 
+			var begChildIndex:int = 0;
+			var begStart:int = absoluteStart - target.getAbsoluteStart();
+			CONFIG::debug { assert(begStart >= 0 && begStart < target.textLength,"CreateListOperation: bad target"); }
+			
+			var endChildIndex:int;
+			var endStart:int = absoluteEnd - target.getAbsoluteStart();
+			CONFIG::debug { assert(endStart >= 0 && endStart <= target.textLength,"CreateListOperation: bad target"); }
+			
+			// scratch vars
+			var child:IFlowGroupElement;
+			
+			if (begStart > 0)
+			{
+				// figure out the starting child
+				begChildIndex = target.findChildIndexAtPosition(begStart);
+				child = target.getChildAt(begChildIndex) as IFlowGroupElement;
+				if (child.parentRelativeStart != begStart)
+				{					
+					_mementoList.push(ModelEdit.splitElement(textFlow,child,begStart-child.parentRelativeStart));
+					
+					if (child is IParagraphElement)
+						endStart++;
+					begChildIndex++;
+				}
+			}
+			
+			if (endStart >= 0)
+			{
+				if (endStart >= target.textLength - 1)
+					endChildIndex = target.numChildren;
+				else
+				{
+					// figure out the starting child
+					endChildIndex = target.findChildIndexAtPosition(endStart);
+					child = target.getChildAt(endChildIndex) as IFlowGroupElement;
+					if (child.parentRelativeStart != endStart)			
+					{
+						_mementoList.push(ModelEdit.splitElement(textFlow,child,endStart-child.parentRelativeStart));
+						endChildIndex++;
+					}
+				}
+			}
+			else
+				endChildIndex = begChildIndex+1;
+			
+			_listElement = ElementHelper.getList();
+			_listElement.format = listFormat;
+			
+			var listItem:IListItemElement;
+			
+			if (begChildIndex == target.numChildren)
+			{
+				// new list at the end of target
+				child = target.getChildAt(target.numChildren-1) as IFlowGroupElement;
+				
+				_mementoList.push(ModelEdit.splitElement(textFlow,child,child.textLength));
+				_mementoList.push(ModelEdit.addElement(textFlow,_listElement,target,target.numChildren));
+
+				if (!(child is IListItemElement))
+				{
+					listItem = ElementHelper.getListItem();	// NO PMD
+					_mementoList.push(ModelEdit.addElement(textFlow,listItem,_listElement,_listElement.numChildren));
+					_mementoList.push(ModelEdit.moveElement(textFlow,child,listItem,listItem.numChildren));
+					// normalize does this
+					if (listItem.normalizeNeedsInitialParagraph())
+						_mementoList.push(ModelEdit.addElement(textFlow,ElementHelper.getParagraph(),listItem,0));
+				}
+				else
+					_mementoList.push(ModelEdit.moveElement(textFlow,child,_listElement,_listElement.numChildren));
+			}
+			else
+			{
+				_mementoList.push(ModelEdit.addElement(textFlow,_listElement,target,endChildIndex));
+				
+				// normalize does this
+				if ((target is IListItemElement) && (target as IListItemElement).normalizeNeedsInitialParagraph())
+				{
+					_mementoList.push(ModelEdit.addElement(textFlow,ElementHelper.getParagraph(),target,0));
+					begChildIndex++;
+					endChildIndex++;
+				}
+
+				if (begChildIndex == endChildIndex)
+				{
+					listItem = ElementHelper.getListItem();	// No PMD
+					_mementoList.push(ModelEdit.addElement(textFlow,listItem,_listElement,0));
+					_mementoList.push(ModelEdit.addElement(textFlow,ElementHelper.getParagraph(),listItem,0));					
+				}
+				else
+				{
+					while (begChildIndex < endChildIndex)
+					{
+						child = target.getChildAt(begChildIndex) as IFlowGroupElement;
+						if (child is IListItemElement)
+						{
+							listItem = child as IListItemElement;
+							_mementoList.push(ModelEdit.moveElement(textFlow,listItem,_listElement,_listElement.numChildren));
+							if (!(listItem.getChildAt(0) is IParagraphElement))
+								_mementoList.push(ModelEdit.addElement(textFlow,ElementHelper.getParagraph(),listItem,0));
+						}
+						else
+						{
+							listItem = ElementHelper.getListItem();	// No PMD
+							_mementoList.push(ModelEdit.addElement(textFlow,listItem,_listElement,_listElement.numChildren));
+							_mementoList.push(ModelEdit.moveElement(textFlow,child,listItem,listItem.numChildren));
+							// normalize does this
+							if (listItem.normalizeNeedsInitialParagraph())
+								_mementoList.push(ModelEdit.addElement(textFlow,ElementHelper.getParagraph(),listItem,0));
+	
+							child = listItem;
+						}
+						child.normalizeRange(0,child.textLength);
+						endChildIndex--;
+					}
+				}
+				// normalize does this
+				var testListItem:IListItemElement = target as IListItemElement;
+				if (testListItem && testListItem.normalizeNeedsInitialParagraph())
+					_mementoList.push(ModelEdit.addElement(textFlow,ElementHelper.getParagraph(),testListItem,0));
+				testListItem = target.parent as IListItemElement;
+				if (testListItem && testListItem.normalizeNeedsInitialParagraph())
+					_mementoList.push(ModelEdit.addElement(textFlow,ElementHelper.getParagraph(),testListItem,0));
+			}
+			
+			if (originalSelectionState.selectionManagerOperationState && textFlow.interactionManager)
+			{
+				textFlow.normalize();
+				_postOpSelectionState = new SelectionState(textFlow,_listElement.getAbsoluteStart(),_listElement.getAbsoluteStart()+_listElement.textLength-1);
+				textFlow.interactionManager.setSelectionState(_postOpSelectionState);
+			}
+			
+			return true;
+		}
+
+		/** @private */
+		public override function undo():SelectionState
+		{
+			_mementoList.undo();
+			return originalSelectionState; 
+		}
+		
+		/** @private */
+		public override function redo():SelectionState
+		{
+			_mementoList.redo();
+			return _postOpSelectionState; 
+			
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/CreateSubParagraphGroupOperation.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/CreateSubParagraphGroupOperation.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/CreateSubParagraphGroupOperation.as
new file mode 100644
index 0000000..e33450b
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/CreateSubParagraphGroupOperation.as
@@ -0,0 +1,271 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.operations {
+	import org.apache.flex.textLayout.debug.assert;
+	import org.apache.flex.textLayout.edit.ElementMark;
+	import org.apache.flex.textLayout.edit.MementoList;
+	import org.apache.flex.textLayout.edit.ModelEdit;
+	import org.apache.flex.textLayout.edit.SelectionState;
+	import org.apache.flex.textLayout.elements.IFlowGroupElement;
+	import org.apache.flex.textLayout.elements.IFlowElement;
+	import org.apache.flex.textLayout.elements.IParagraphElement;
+	import org.apache.flex.textLayout.elements.ISpanElement;
+	import org.apache.flex.textLayout.elements.SubParagraphGroupElement;
+	import org.apache.flex.textLayout.elements.ISubParagraphGroupElementBase;
+	import org.apache.flex.textLayout.formats.ITextLayoutFormat;
+
+
+
+
+	/**
+	 * The CreateSPGEOperation class encapsulates creating a SubPargraphGroupElement
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class CreateSubParagraphGroupOperation extends FlowTextOperation
+	{
+		// describes the target
+		private var _spgeParentMarker:ElementMark;
+		private var _format:ITextLayoutFormat;
+
+		private var _mementoList:MementoList;
+
+		// the element that gets created
+		private var _spgeElement:SubParagraphGroupElement;		
+		private var _postOpSelectionState:SelectionState;
+		
+		/** 
+		 * Constructor.
+		 * 
+		 * This operation creates a single SubParagraphGroupElement in the first paragraph of the selection range.  That paragraph must have at least one character selected the paragraph terminator does not count towards that selection.
+		 * Specifying the spgeParent creates an SubParagraphGroupElement int he part of the selection range included by that spgeParent.
+		 * 
+		 * @param operationState selection over which to apply the operation.  
+		 * @param spgeParent optional parent for the spge element.  If not specified one is chosen based on the selection
+		 * @param spgeFormat optional format to set in the new spge element.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function CreateSubParagraphGroupOperation(operationState:SelectionState, parent:IFlowGroupElement = null, format:ITextLayoutFormat = null)
+		{
+			super(operationState);
+			
+			_format = format;
+			this.parent = parent;
+			_mementoList = new MementoList(operationState.textFlow);
+		}
+		
+		/** 
+		 * Specifies the element this operation modifies.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 * @flexjsignorecoercion org.apache.flex.textLayout.elements.IFlowGroupElement
+		 */
+		public function get parent():IFlowGroupElement
+		{
+			return _spgeParentMarker ? _spgeParentMarker.findElement(originalSelectionState.textFlow) as IFlowGroupElement : null;
+		}
+		public function set parent(value:IFlowGroupElement):void
+		{
+			if (!value)
+			{
+				// descend to the lowest level non-paragraph element that contains both positions
+				// effectively make the new spge as close to the spans as possible
+				
+				var begPos:int = this.absoluteStart;
+				var endPos:int = this.absoluteEnd;
+				
+				// start with the ParagraphElement
+				var para:IParagraphElement = textFlow.findLeaf(begPos).getParagraph();
+				var paraStart:int = para.getAbsoluteStart();
+				
+				// can't be just the terminator
+				if (begPos < paraStart+para.textLength-1)
+				{
+					// Only work in this ParagraphElement - include the terminator if it was excluded
+					if (endPos >= paraStart+para.textLength-1)
+						endPos = paraStart+para.textLength;
+					
+					value = para;
+					
+					for (;;)
+					{
+						var begChildIdx:int = value.findChildIndexAtPosition(begPos);
+						var elem:IFlowGroupElement = value.getChildAt(begChildIdx) as IFlowGroupElement;
+						if (elem == null)
+							break;
+						begPos -= elem.parentRelativeStart;
+						endPos -= elem.parentRelativeStart;
+						if (endPos > elem.textLength)	// end pos is in the next element.  can be at the beginning
+							break;
+						value = elem;
+					}
+				}
+			}
+			else if (!(value is ISubParagraphGroupElementBase) || !(value is IParagraphElement))
+				value = null;
+			
+			_spgeParentMarker = value ? new ElementMark(value,0) : null;
+		}
+		
+		/** Format to be applied to the new SubParagraphGroupElement
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */		
+		public function get format():ITextLayoutFormat
+		{ return _format; }
+		public function set format(value:ITextLayoutFormat):void
+		{ _format = value; }
+		
+		/** The new SubParagraphGroupElement. 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */	
+		public function get newSubParagraphGroupElement():SubParagraphGroupElement
+		{ return _spgeElement; }
+		
+		/**
+		 *  @private
+		 * @flexjsignorecoercion org.apache.flex.textLayout.elements.IFlowGroupElement
+		 * @flexjsignorecoercion org.apache.flex.textLayout.elements.ISpanElement
+		 */
+		public override function doOperation():Boolean
+		{
+			if (absoluteStart == absoluteEnd)
+				return false;
+			
+			var target:IFlowGroupElement = this.parent;
+			if (!target)
+				return false;
+			
+			// find the starting child that's going to be in the list and 
+			var begChildIndex:int = 0;
+			var begStart:int = absoluteStart - target.getAbsoluteStart();
+			CONFIG::debug { assert(begStart >= 0 && begStart < target.textLength,"CreateSPGEOperation: bad target"); }
+			
+			var endChildIndex:int;
+			var endStart:int = absoluteEnd - target.getAbsoluteStart();
+			if (endStart >= target.getAbsoluteStart()+target.textLength-1)
+				endStart = target.getAbsoluteStart()+target.textLength;
+			
+			// scratch vars
+			var child:IFlowElement;
+			
+			if (begStart > 0)
+			{
+				// figure out the starting child
+				begChildIndex = target.findChildIndexAtPosition(begStart);
+				child = target.getChildAt(begChildIndex);
+				if (child.parentRelativeStart != begStart)
+				{				
+					if (child is IFlowGroupElement)
+						_mementoList.push(ModelEdit.splitElement(textFlow,child as IFlowGroupElement,begStart-child.parentRelativeStart));
+					else
+						child.splitAtPosition(begStart-child.parentRelativeStart);
+					begChildIndex++;
+				}
+			}
+			
+			if (endStart >= 0)
+			{
+				if (endStart >= target.textLength - 1)
+				{
+					endChildIndex = target.numChildren;
+					// if last element in target is a span with just a terminator than go before it
+					if (endChildIndex != 0)
+					{
+						var lastChild:IFlowElement = target.getChildAt(endChildIndex-1);
+						if (lastChild is ISpanElement && lastChild.textLength == 1 && (lastChild as ISpanElement).hasParagraphTerminator)
+							endChildIndex--;
+					}
+				}
+				else
+				{
+					// figure out the starting child
+					endChildIndex = target.findChildIndexAtPosition(endStart);
+					child = target.getChildAt(endChildIndex);
+					if (child.parentRelativeStart != endStart)			
+					{
+						if (child is IFlowGroupElement)
+							_mementoList.push(ModelEdit.splitElement(textFlow,child as IFlowGroupElement,endStart-child.parentRelativeStart));
+						else
+							child.splitAtPosition(endStart-child.parentRelativeStart);
+						endChildIndex++;
+					}
+				}
+			}
+			else
+				endChildIndex = begChildIndex+1;
+			
+			_spgeElement = new SubParagraphGroupElement;
+			_spgeElement.format = format;
+			
+			
+			CONFIG::debug { assert(begChildIndex != target.numChildren,"Invalid begChildIndex in CreateSPGEOperation"); }
+
+			_mementoList.push(ModelEdit.addElement(textFlow,_spgeElement,target,endChildIndex));
+			{
+				while (begChildIndex < endChildIndex)
+				{
+					child = target.getChildAt(begChildIndex);
+					if (child.textLength == 0)
+					{
+						// skip it
+						begChildIndex++;
+					}
+					else
+					{
+						_mementoList.push(ModelEdit.moveElement(textFlow,child,_spgeElement,_spgeElement.numChildren));
+						endChildIndex--;
+					}
+				}
+			}
+			
+			if (originalSelectionState.selectionManagerOperationState && textFlow.interactionManager)
+			{
+				textFlow.normalize();
+				_postOpSelectionState = new SelectionState(textFlow,_spgeElement.getAbsoluteStart(),_spgeElement.getAbsoluteStart()+_spgeElement.textLength);
+				textFlow.interactionManager.setSelectionState(_postOpSelectionState);
+			}
+			
+			return true;
+		}
+
+		/** @private */
+		public override function undo():SelectionState
+		{
+			_mementoList.undo();
+			return originalSelectionState; 
+		}
+		
+		/** @private */
+		public override function redo():SelectionState
+		{
+			_mementoList.redo();
+			return _postOpSelectionState; 
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/CutOperation.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/CutOperation.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/CutOperation.as
new file mode 100644
index 0000000..1844cce
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/CutOperation.as
@@ -0,0 +1,98 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.operations {
+	import org.apache.flex.textLayout.edit.SelectionState;
+	import org.apache.flex.textLayout.edit.TextScrap;
+
+
+
+
+	
+	/**
+	 * The CutOperation class encapsulates a cut operation.
+	 *
+	 * <p>The specified range is removed from the text flow.</p>
+	 * 
+	 * <p><b>Note:</b> The edit manager is responsible for copying the 
+	 * text scrap to the clipboard. Undoing a cut operation does not restore
+	 * the original clipboard state.</p>
+	 * 
+	 * @see org.apache.flex.textLayout.edit.EditManager
+	 * @see org.apache.flex.textLayout.events.FlowOperationEvent
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class CutOperation extends FlowTextOperation
+	{
+		private var _tScrap:TextScrap;
+		private var _deleteTextOperation:DeleteTextOperation;
+		
+		/** 
+		 * Creates a CutOperation object.
+		 * 
+		 * @param operationState The range of text to be cut.
+		 * @param scrapToCut A copy of the deleted text.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		function CutOperation(operationState:SelectionState, scrapToCut:TextScrap)
+		{
+			super(operationState);
+			if (absoluteStart < absoluteEnd)
+				_tScrap = scrapToCut;
+		}
+		
+		
+		/** @private */
+		public override function doOperation():Boolean
+		{
+			_deleteTextOperation = new DeleteTextOperation(originalSelectionState);
+			return _deleteTextOperation.doOperation();
+		}
+		
+		/** @private */
+		public override function undo():SelectionState
+		{
+			return _deleteTextOperation.undo();
+		}
+	
+		/** @private */
+		public override function redo():SelectionState
+		{
+			return _deleteTextOperation.redo();
+		}
+		
+		/** 
+		 * scrapToCut the original removed text
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function get scrapToCut():TextScrap
+		{ return _tScrap; }
+		public function set scrapToCut(val:TextScrap):void
+		{ _tScrap = val; }
+		
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/DeleteTextOperation.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/DeleteTextOperation.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/DeleteTextOperation.as
new file mode 100644
index 0000000..ccaf729
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/DeleteTextOperation.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.operations {
+	import org.apache.flex.textLayout.edit.IMemento;
+	import org.apache.flex.textLayout.edit.ModelEdit;
+	import org.apache.flex.textLayout.edit.PointFormat;
+	import org.apache.flex.textLayout.edit.SelectionState;
+
+	
+
+
+	/**
+	 * The DeleteTextOperation class encapsulates the deletion of a range of text.
+	 *
+	 * @see org.apache.flex.textLayout.edit.EditManager
+	 * @see org.apache.flex.textLayout.events.FlowOperationEvent
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class DeleteTextOperation extends FlowTextOperation
+	{
+		private var _memento:IMemento;
+		private var _allowMerge:Boolean;
+		private var _pendingFormat:PointFormat;
+		
+		private var _deleteSelectionState:SelectionState = null;
+		/** 
+		 * Creates a DeleteTextOperation operation.
+		 * 
+		 * @param operationState The original range of text.
+		 * @param deleteSelectionState The range of text to delete, if different from the range 
+		 * described by <code>operationState</code>. (Set to <code>null</code> to delete the range
+		 * described by <code>operationState</code>.)
+		 * @param allowMerge Set to <code>true</code> if this operation can be merged with the next or previous operation.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function DeleteTextOperation(operationState:SelectionState, deleteSelectionState:SelectionState = null, allowMerge:Boolean = false)
+		{
+			_deleteSelectionState = deleteSelectionState ? deleteSelectionState : operationState;				
+			
+			super(_deleteSelectionState);
+			originalSelectionState = operationState;
+			_allowMerge = allowMerge;
+		}
+		
+		/** 
+		 * Indicates whether this operation can be merged with operations executed before or after it.
+		 * 
+		 * <p>Some delete operations, for example, a sequence of backspace keystrokes, can be fruitfully 
+		 * merged into one operation so that undoing the operation reverses the entire sequence.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get allowMerge():Boolean
+		{
+			return _allowMerge;
+		}
+		public function set allowMerge(value:Boolean):void
+		{
+			_allowMerge = value;
+		}
+		
+		/** 
+		 * deleteSelectionState The range of text to delete
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get deleteSelectionState():SelectionState
+		{
+			return _deleteSelectionState;
+		}
+		public function set deleteSelectionState(value:SelectionState):void
+		{
+			_deleteSelectionState = value;
+		}
+		
+		/** @private */
+		public override function doOperation():Boolean
+		{
+			// Nothing to delete
+			if (absoluteStart == absoluteEnd)
+				return false;
+				
+			_pendingFormat = PointFormat.createFromFlowElement(textFlow.findLeaf(absoluteStart));
+			if (_pendingFormat.linkElement)		// don't propagate links or tcy from deleted text
+				_pendingFormat.linkElement = null;
+			if (_pendingFormat.tcyElement)		// don't propagate links or tcy from deleted text
+				_pendingFormat.tcyElement = null;
+						
+			_memento = ModelEdit.deleteText(textFlow, absoluteStart, absoluteEnd, true);
+			
+			if (originalSelectionState.selectionManagerOperationState && textFlow.interactionManager)
+			{
+				// set pointFormat from leafFormat
+				var state:SelectionState = textFlow.interactionManager.getSelectionState();
+				if (state.anchorPosition == state.activePosition)
+				{
+					state.pointFormat = PointFormat.clone(_pendingFormat);
+					textFlow.interactionManager.setSelectionState(state);
+				}
+			}
+
+			return true;	
+		}
+		
+		/** @private */
+		public override function undo():SelectionState
+		{
+			if (_memento)
+				_memento.undo();
+			return originalSelectionState;				
+		}
+	
+		/** @private */
+		public override function redo():SelectionState
+		{
+			if (_memento)
+				_memento.redo();
+			return new SelectionState(textFlow,absoluteStart,absoluteStart,_pendingFormat);	
+		}
+
+		/** @private */
+		public override function merge(op2:FlowOperation):FlowOperation
+		{
+			if (this.endGeneration != op2.beginGeneration)
+					return null;
+			var delOp:DeleteTextOperation = op2 as DeleteTextOperation;
+			if ((delOp == null) || !delOp.allowMerge || !_allowMerge)
+				return null;
+				
+			return new CompositeOperation([this, op2]);
+		}	
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/FlowElementOperation.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/FlowElementOperation.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/FlowElementOperation.as
new file mode 100644
index 0000000..444cf65
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/FlowElementOperation.as
@@ -0,0 +1,236 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.operations {
+	import org.apache.flex.textLayout.debug.assert;
+	import org.apache.flex.textLayout.edit.SelectionState;
+	import org.apache.flex.textLayout.elements.FlowGroupElement;
+	import org.apache.flex.textLayout.elements.IFlowElement;
+	import org.apache.flex.textLayout.elements.SpanElement;
+	
+	/**
+	 * The FlowElementOperation class is the base class for operations that transform a FlowElement.
+	 *
+	 * @see org.apache.flex.textLayout.formats.TextLayoutFormat
+	 * @see org.apache.flex.textLayout.edit.EditManager
+	 * @see org.apache.flex.textLayout.events.FlowOperationEvent
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class FlowElementOperation extends FlowTextOperation
+	{	
+		private var nestLevel:int;
+		private var absStart:int;
+		private var absEnd:int;
+		
+		private var origAbsStart:int;
+		private var origAbsEnd:int;
+		
+		private var firstTime:Boolean = true;
+		private var splitAtStart:Boolean = false;
+		private var splitAtEnd:Boolean = false;
+		
+		private var _relStart:int = 0;
+		private var _relEnd:int = -1;
+		
+		/** 
+		 * Creates a FlowElementOperation object.
+		 *  
+		 * @param operationState Specifies the TextFlow object this operation acts upon.
+		 * @param targetElement Specifies the element this operation modifies.
+		 * @param relativeStart An offset from the beginning of the <code>targetElement</code>.
+		 * @param relativeEnd An offset from the end of the <code>targetElement</code>.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function FlowElementOperation(operationState:SelectionState, targetElement:IFlowElement, relativeStart:int = 0, relativeEnd:int = -1)
+		{
+			super(operationState);
+			initialize(targetElement,relativeStart,relativeEnd);
+			
+			CONFIG::debug { assert(targetElement.getTextFlow() == operationState.textFlow, "ChangeElementIdOperation element is not part of selectionState TextFlow"); }
+		}
+		
+		
+		private function initialize(targetElement:IFlowElement, relativeStart:int, relativeEnd:int ):void
+		{
+			this.targetElement = targetElement;
+			this.relativeEnd = relativeEnd;
+			this.relativeStart = relativeStart;
+			
+			if (relativeEnd == -1)
+				relativeEnd = targetElement.textLength;
+				
+			CONFIG::debug { assert(relativeStart >= 0 && relativeStart <= targetElement.textLength,"ChangeElementIdOperation bad relativeStart"); } 
+			CONFIG::debug { assert(relativeEnd >= 0 && relativeEnd <= targetElement.textLength,"ChangeElementIdOperation bad relativeEnd"); } 
+			CONFIG::debug { assert(relativeStart <= relativeEnd,"ChangeElementIdOperation relativeStart not before relativeEnd"); } 
+
+			// If we're changing the format of the text right before the terminator, change the terminator to match.
+			// This will make it so that when the format change is undone, the terminator will be restored to previous state. Also
+			// prevents unnecessary split & join of spans (split for apply, joined during normalize).
+			if (targetElement is SpanElement && SpanElement(targetElement).hasParagraphTerminator && relativeEnd == targetElement.textLength - 1)
+				relativeEnd += 1;
+				
+			origAbsStart = absStart = targetElement.getAbsoluteStart() + relativeStart;
+			origAbsEnd   = absEnd   = absStart - relativeStart + relativeEnd;
+
+			
+		}
+		
+		/** 
+		 * Specifies the element this operation modifies.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get targetElement():IFlowElement
+		{
+			var element:IFlowElement = originalSelectionState.textFlow;
+			for (var i:int = nestLevel; i > 0; i--)
+			{
+				var groupElement:FlowGroupElement = element as FlowGroupElement;
+				element = groupElement.getChildAt(groupElement.findChildIndexAtPosition(absStart - element.getAbsoluteStart()));
+			}
+			return element;
+		}
+		public function set targetElement(value:IFlowElement):void
+		{
+			nestLevel = 0;
+			for (var element:IFlowElement = value; element.parent != null; element = element.parent)
+				++nestLevel;
+		}
+		
+	
+		/** 
+		 * An offset from the beginning of the <code>targetElement</code>.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get relativeStart():int
+		{
+			return _relStart;
+		}
+		public function set relativeStart(value:int):void
+		{
+			_relStart = value;
+		}
+		
+		/** 
+		 * An offset from the start of the <code>targetElement</code>.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get relativeEnd():int
+		{
+			return _relEnd;
+		}
+		public function set relativeEnd(value:int):void
+		{
+			_relEnd = value;
+		}
+		
+		
+		/** @private */
+		protected function getTargetElement():IFlowElement
+		{
+			var element:IFlowElement = this.targetElement;
+			
+			var elemStart:int = element.getAbsoluteStart();
+			var splitElement:IFlowElement;	// scratch
+			// split at the back and then split at the start - that way paragraph terminators don't get in the way
+			if (absEnd != elemStart + element.textLength)
+			{
+				splitElement = element.splitAtPosition(absEnd - elemStart);
+				if (firstTime && splitElement != element)
+					splitAtEnd = true;
+			}
+				
+			if (absStart != elemStart)
+			{
+				splitElement = element.splitAtPosition(absStart-elemStart);
+				if (splitElement != element)
+				{
+					if (firstTime)
+						splitAtStart = true;
+					element = splitElement;
+				}
+			}
+			
+			firstTime = false;	
+			return element;
+		}
+		
+		
+		/** @private */
+		protected function adjustForDoOperation(targetElement:IFlowElement):void
+		{
+			// adjust for undo
+			absStart = targetElement.getAbsoluteStart();
+			absEnd   = absStart + targetElement.textLength;
+		}	
+		
+		/** @private */
+		protected function adjustForUndoOperation(targetElement:IFlowElement):void
+		{
+			// need to do manual merging
+			if ((splitAtEnd || splitAtStart) && (targetElement is FlowGroupElement))
+			{
+				var targetIdx:int = targetElement.parent.getChildIndex(targetElement);
+				var workElem:FlowGroupElement;
+				var child:IFlowElement;
+				
+				if (splitAtEnd)
+				{
+					// merge next to targetElement
+					workElem = targetElement.parent.getChildAt(targetIdx+1) as FlowGroupElement;
+					while (workElem.numChildren)
+					{
+						child = workElem.getChildAt(0);
+						workElem.removeChildAt(0);
+						FlowGroupElement(targetElement).addChild(child);
+					}
+					targetElement.parent.removeChildAt(targetIdx+1);
+				}
+				if (splitAtStart)
+				{
+					// merge targetElement to prevElement
+					workElem = targetElement.parent.getChildAt(targetIdx-1) as FlowGroupElement;
+					while (FlowGroupElement(targetElement).numChildren)
+					{
+						child = FlowGroupElement(targetElement).getChildAt(0);
+						FlowGroupElement(targetElement).removeChildAt(0);
+						workElem.addChild(child);
+					}
+					targetElement.parent.removeChildAt(targetIdx);
+				}
+			}
+			
+			absStart = origAbsStart;
+			absEnd   = origAbsEnd;
+		}
+	}
+}
\ 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/operations/FlowOperation.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/FlowOperation.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/FlowOperation.as
new file mode 100644
index 0000000..249ca60
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/FlowOperation.as
@@ -0,0 +1,241 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.operations
+{
+	import org.apache.flex.utils.undo.IOperation;
+	import org.apache.flex.textLayout.edit.SelectionState;
+
+
+
+
+	//
+	// Considered several ways of doing undo/redo
+	// 1 - object model level - stashing copies of all changed objects in the model and restoring them
+	// 2 - cookies - saving an audit trail of every modified property of the model objects
+	// 3 - operations - each operation creates an object that knows how to do/undo/redo itself
+	// going with # 3 for now
+	//
+	import org.apache.flex.textLayout.elements.ITextFlow;
+	import org.apache.flex.textLayout.edit.IEditManager;
+
+	/** 
+	 * The FlowOperation class is the base class for all Text Layout Framework operations. 
+	 * 
+	 * <p>Operations are transformations of a text flow. An Operation class defines the
+	 * logic for performing and undoing the transformation. Operations are executed by an
+	 * edit manager. Most applications do not need to create or manage operations directly
+	 * (unless implementing a custom edit manager).</p>
+	 * 
+	 * <p>When an operation is performed, the edit manager dispatches an Operation object 
+	 * within the FlowOperationEvent object. You can query 
+	 * this Operation object to decide whether or not to allow the operation, to decide whether 
+	 * to perform some other operation as well, or to update related user-interface elements.</p>
+	 * 
+	 * @see org.apache.flex.textLayout.events.FlowOperationEvent
+	 * @see org.apache.flex.textLayout.edit.EditManager
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class FlowOperation implements IOperation
+	{
+		/** 
+		 * Arbitrary data associated with an element. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public var userData:*;
+		
+		// uint or null
+		private var _beginGeneration:uint;
+		private var _endGeneration:uint;
+		
+		private var _textFlow:ITextFlow;		// target of the operation
+
+		/** 
+		 * Creates the FlowOperation object.
+		 * 
+		 * @param textFlow	The text flow to which this operation is applied.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function FlowOperation(textFlow:ITextFlow)
+		{
+			_textFlow = textFlow;
+		}
+		
+		/** 
+		 * The ITextFlow object to which this operation is applied.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function get textFlow():ITextFlow
+		{ return _textFlow; }
+		public function set textFlow(value:ITextFlow):void
+		{ _textFlow = value; }
+		
+		/** 
+		 * Executes the operation. 
+		 * 
+		 * <p>This method must be overridden in derived classes. The base class method does nothing.
+		 * You should not call <code>doOperation()</code> directly. The edit manager 
+		 * calls the method when it executes the operation. </p>
+		 * 
+		 * @return Boolean <code>true</code>, if the operation succeeded. Otherwise, <code>false</code>.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function doOperation():Boolean
+		{
+			return false;
+		}
+		
+		/**	
+		 * Reverses the operation. 
+		 * 
+		 * <p>This method must be overridden in derived classes. The base class method does nothing.
+		 * You should not call <code>undo()</code> directly. The edit manager 
+		 * calls the method when it reverses the operation. </p>
+		 * 
+		 * @return The SelectionState object passed to the operation when it was performed. This
+		 * SelectionState object can be the current selection or a selection created specifically
+		 * for the operation. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function undo():SelectionState
+		{
+			return null;
+		}
+		
+		/**	
+		 * Test if this operation be placed on the undo stack.
+		 * 
+		 * @return true means to push the operation onto the undo stack.  false means do not push this operation.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		public function canUndo():Boolean
+		{ return true; }
+		
+		/**	
+		 * Re-executes the operation. 
+		 * 
+		 * <p>This method must be overridden in derived classes. The base class method does nothing.
+		 * You should not call <code>redo()</code> directly. The edit manager 
+		 * calls the method when it re-executes the operation. </p>
+		 * 
+		 * @return The SelectionState object passed to the operation when it was performed. This
+		 * SelectionState object can be the current selection or a selection created specifically
+		 * for the operation. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function redo():SelectionState
+		{
+			return null;
+		}
+		
+		// Generation numbers
+		
+		/**
+		 * The text flow generation before the operation.
+		 *   
+		 * <p>A generation of 0 indicates that the operation did not complete.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get beginGeneration():uint
+		{ return _beginGeneration; }
+		/** 
+		 * The text flow generation after the operation.
+		 * 
+		 * <p>A generation of 0 indicates that the operation did not complete.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get endGeneration():uint
+		{ return _endGeneration; }
+
+		/** @private */
+		public function performUndo():void
+		{
+			var editManager:IEditManager = textFlow ? textFlow.interactionManager as IEditManager : null;
+			if (editManager != null)
+			{
+				editManager.performUndo(this);
+			}
+		}
+
+		/** @private */
+		public function performRedo():void
+		{
+			var editManager:IEditManager = textFlow ? textFlow.interactionManager as IEditManager : null;
+			if (editManager != null)
+			{
+				editManager.performRedo(this);
+			}
+		}
+		
+		/** @private -- Sets the generation numbers into the operation.  */
+		public function setGenerations(beginGeneration:uint,endGeneration:uint):void
+		{
+			_beginGeneration = beginGeneration;
+			_endGeneration   = endGeneration;
+		}
+		
+		/**
+		 * @private
+		 * 
+		 *  Combine this operation with another operation if the result can 
+		 *  be represented as a single operation.  In general, operations cannot be 
+		 *  merged. But sequential inserts or deletes may be mergeable.
+		 * 
+		 *  Merging may occur through updating the properties of the operation
+		 *  on which this method is called, by creating a new operation.
+		 * 
+		 *  @param operation 	The FlowOperation to merge against
+		 *  @return A FlowOperation representing the combined operation if 
+		 *  the merge was successful, null otherwise.
+		 */
+		public function merge(operation:FlowOperation):FlowOperation	// No PMD
+		{
+			return null;
+		}
+	}
+}
\ 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/operations/FlowTextOperation.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/FlowTextOperation.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/FlowTextOperation.as
new file mode 100644
index 0000000..7e21be2
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/FlowTextOperation.as
@@ -0,0 +1,122 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.operations {
+	import org.apache.flex.textLayout.edit.SelectionState;
+
+
+
+
+	//
+	// Considered several ways of doing undo/redo
+	// 1 - object model level - stashing copies of all changed objects in the model and restoring them
+	// 2 - cookies - saving an audit trail of every modified property of the model objects
+	// 3 - operations - each operation creates an object that knows how to do/undo/redo itself
+	// going with # 3 for now
+	//
+
+	/** 
+	 * The FlowTextOperation is the base class for operations that transform a range of text.
+	 * 
+	 * @see org.apache.flex.textLayout.edit.EditManager
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class FlowTextOperation extends FlowOperation
+	{
+		private var _originalSelectionState:SelectionState;
+		private var _absoluteStart:int;
+		private var _absoluteEnd:int;
+
+		/** 
+		 * Creates the FlowTextOperation object.
+		 * 
+		 * @param operationState Specifies the relevant selection. If relevant to the operation, the 
+		 * <code>operationState</code> describes the text range to which this operation applies.
+		 * Otherwise, <code>operationState</code> is used to save the current selection state so that
+		 * it can be restored when the operation is undone.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function FlowTextOperation(operationState:SelectionState)
+		{
+			super(operationState.textFlow);
+			_absoluteStart = operationState.absoluteStart;
+			_absoluteEnd = operationState.absoluteEnd;
+			_originalSelectionState = operationState;
+		}
+				
+		/** 
+		 * The absolute start point of the range of text to which this operation is applied.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get absoluteStart():int
+		{ return _absoluteStart; }
+		public function set absoluteStart(value:int):void
+		{ _absoluteStart = value; }
+		
+		/** 
+		 * The absolute end point of the range of text to which this operation is applied. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get absoluteEnd():int
+		{ return _absoluteEnd; }
+		public function set absoluteEnd(value:int):void
+		{ _absoluteEnd = value; }
+		
+		/** 
+		 * The selection state at the start of the operation. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get originalSelectionState():SelectionState
+		{
+			return _originalSelectionState;
+		}
+		public function set originalSelectionState(value:SelectionState):void
+		{
+			_originalSelectionState = value;
+		}
+		
+		/**	
+		 * @inheritDoc
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		override public function redo():SelectionState
+		{
+			doOperation();
+			return _originalSelectionState;
+		}
+		
+	}
+}
\ 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/operations/InsertInlineGraphicOperation.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/InsertInlineGraphicOperation.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/InsertInlineGraphicOperation.as
new file mode 100644
index 0000000..bb5d9f5
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/InsertInlineGraphicOperation.as
@@ -0,0 +1,232 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.operations {
+	import org.apache.flex.textLayout.edit.ElementRange;
+	import org.apache.flex.textLayout.edit.ParaEdit;
+	import org.apache.flex.textLayout.edit.PointFormat;
+	import org.apache.flex.textLayout.edit.SelectionState;
+	import org.apache.flex.textLayout.elements.IFlowGroupElement;
+	import org.apache.flex.textLayout.elements.IFlowElement;
+	import org.apache.flex.textLayout.elements.IFlowLeafElement;
+	import org.apache.flex.textLayout.elements.IInlineGraphicElement;
+	import org.apache.flex.textLayout.elements.ISubParagraphGroupElementBase;
+	import org.apache.flex.textLayout.formats.ITextLayoutFormat;
+
+
+
+
+	
+
+	/**
+	 * The InsertInlineGraphicOperation class encapsulates the insertion of an inline
+	 * graphic into a text flow.
+	 *
+	 * @see org.apache.flex.textLayout.elements.IInlineGraphicElement
+	 * @see org.apache.flex.textLayout.edit.EditManager
+	 * @see org.apache.flex.textLayout.events.FlowOperationEvent
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class InsertInlineGraphicOperation extends FlowTextOperation
+	{
+		private var delSelOp:DeleteTextOperation; 
+		private var _source:Object;
+		private var imageWidth:Object;
+		private var imageHeight:Object;
+		private var _options:Object;
+		private var selPos:int = 0;
+		private var _inlineGraphicElement:IInlineGraphicElement;
+		
+		/** 
+		 * Creates an InsertInlineGraphicsOperation object.
+		 * 
+		 * @param operationState Describes the insertion point. 
+		 * If a range is selected, the operation deletes the contents of that range.
+		 * @param	source	The graphic source (uri string, URLRequest, DisplayObject, or Class of an embedded asset). 
+		 * @param	width	The width to assign (number of pixels, percent, or the string 'auto')
+		 * @param	height	The height to assign (number of pixels, percent, or the string 'auto')
+		 * @param	options	The float to assign (String value, none for inline with text, left/right/start/end for float)
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function InsertInlineGraphicOperation(operationState:SelectionState, source:Object, width:Object, height:Object, options:Object = null)
+		{
+			super(operationState);
+			
+			if (absoluteStart != absoluteEnd)
+				delSelOp = new DeleteTextOperation(operationState);
+				
+			_source = source;
+			_options = options;
+			imageWidth = width;
+			imageHeight = height;
+		}
+		
+		/**	
+		 * @copy org.apache.flex.textLayout.elements.IInlineGraphicElement#source
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+ 		 */
+		public function get source():Object
+		{
+			return _source;
+		}
+		public function set source(value:Object):void
+		{
+			_source = value;
+		}
+
+		/** 
+		 * @copy org.apache.flex.textLayout.elements.IInlineGraphicElement#width
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function get width():Object
+		{
+			return imageWidth;
+		}
+		public function set width(value:Object):void
+		{
+			imageWidth = value;
+		}
+
+		/** 
+		 * @copy org.apache.flex.textLayout.elements.IInlineGraphicElement#height
+		 * 
+		 * @see org.apache.flex.textLayout.IInlineGraphicElement#height
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get height():Object
+		{
+			return imageHeight;
+		}
+		public function set height(value:Object):void
+		{
+			imageHeight = value;
+		}
+		
+		/** 
+		 * @copy org.apache.flex.textLayout.elements.IInlineGraphicElement#float
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get options():Object
+		{
+			return _options;
+		}
+		public function set options(value:Object):void
+		{
+			_options = value;
+		}
+
+		/** 
+		 * The IInlineGraphicElement that was created by doOperation.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		public function get newInlineGraphicElement():IInlineGraphicElement
+		{
+			return _inlineGraphicElement;
+		}
+		
+		/** @private */
+		public override function doOperation():Boolean
+		{
+			var pointFormat:ITextLayoutFormat;
+			
+			selPos = absoluteStart;
+			if (delSelOp) 
+			{
+				var leafEl:IFlowLeafElement = textFlow.findLeaf(absoluteStart);
+				var deleteFormat:PointFormat = new PointFormat(textFlow.findLeaf(absoluteStart).format);
+				if (delSelOp.doOperation())
+					pointFormat = deleteFormat;
+			}
+			else
+				pointFormat = originalSelectionState.pointFormat;
+				
+			// lean left logic included
+			var range:ElementRange = ElementRange.createElementRange(textFlow,selPos, selPos);		
+			var leafNode:IFlowElement = range.firstLeaf;
+			var leafNodeParent:IFlowGroupElement = leafNode.parent;
+			while (leafNodeParent is ISubParagraphGroupElementBase)
+			{
+				var subParInsertionPoint:int = selPos - leafNodeParent.getAbsoluteStart();
+				if (((subParInsertionPoint == 0) && (!(leafNodeParent as ISubParagraphGroupElementBase).acceptTextBefore())) ||
+					((subParInsertionPoint == leafNodeParent.textLength) && (!(leafNodeParent as ISubParagraphGroupElementBase).acceptTextAfter())))
+				{
+					leafNodeParent = leafNodeParent.parent;
+				} else {
+					break;
+				}
+			}
+			
+			_inlineGraphicElement = ParaEdit.createImage(leafNodeParent, selPos - leafNodeParent.getAbsoluteStart(), _source, imageWidth, imageHeight, options, pointFormat);
+			if (textFlow.interactionManager)
+				textFlow.interactionManager.notifyInsertOrDelete(absoluteStart, 1);
+			
+			return true;
+		}
+	
+		/** @private */
+		public override function undo():SelectionState
+		{
+			var leafNode:IFlowElement = textFlow.findLeaf(selPos);
+			var leafNodeParent:IFlowGroupElement = leafNode.parent;
+			var elementIdx:int = leafNode.parent.getChildIndex(leafNode);
+			leafNodeParent.replaceChildren(elementIdx, elementIdx + 1, null);			
+					
+			if (textFlow.interactionManager)
+				textFlow.interactionManager.notifyInsertOrDelete(absoluteStart, -1);
+
+			return delSelOp ? delSelOp.undo() : originalSelectionState; 
+		}
+
+		/**
+		 * Re-executes the operation after it has been undone.
+		 * 
+		 * <p>This function is called by the edit manager, when necessary.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public override function redo():SelectionState
+		{ 
+			doOperation();
+			return new SelectionState(textFlow,selPos+1,selPos+1,null);
+		}
+
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/InsertTableElementOperation.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/InsertTableElementOperation.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/InsertTableElementOperation.as
new file mode 100644
index 0000000..81e487e
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/InsertTableElementOperation.as
@@ -0,0 +1,134 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.operations {
+	import org.apache.flex.textLayout.elements.IFlowGroupElement;
+	import org.apache.flex.textLayout.edit.MementoList;
+	import org.apache.flex.textLayout.edit.ModelEdit;
+	import org.apache.flex.textLayout.edit.PointFormat;
+	import org.apache.flex.textLayout.edit.SelectionState;
+	import org.apache.flex.textLayout.elements.FlowGroupElement;
+	import org.apache.flex.textLayout.elements.ITableElement;
+	import org.apache.flex.textLayout.formats.ITextLayoutFormat;
+
+	
+
+	
+	public class InsertTableElementOperation extends FlowTextOperation
+	{
+//		private var delSelOp:DeleteTextOperation; 
+		private var _table:ITableElement;
+		private var selPos:int = 0;
+		private var _mementoList:MementoList;
+		private var _postOpSelectionState:SelectionState;
+//		private var _listParentMarker:ElementMark;
+		
+		public function InsertTableElementOperation(operationState:SelectionState, table:ITableElement)
+		{
+			super(operationState);
+			
+			_mementoList = new MementoList(operationState.textFlow);
+			_table = table;
+		}
+		
+		/** @private */
+		public override function doOperation():Boolean
+		{
+			var pointFormat:ITextLayoutFormat;
+			
+			selPos = absoluteStart;
+			if (absoluteStart != absoluteEnd) 
+			{
+//				var leafEl:FlowLeafElement = textFlow.findLeaf(absoluteStart);
+				var deleteFormat:PointFormat = new PointFormat(textFlow.findLeaf(absoluteStart).format);
+				
+				_mementoList.push(ModelEdit.deleteText(textFlow,absoluteStart,absoluteEnd,true));
+				pointFormat = deleteFormat;
+			}
+			else
+				pointFormat = originalSelectionState.pointFormat;
+			
+			
+			var target:IFlowGroupElement = textFlow;
+			
+			var begStart:int = absoluteStart;
+			var begChildIndex:int = 0;
+			var endChildIndex:int;
+			
+			// scratch vars
+			var child:FlowGroupElement;
+			
+			if(begStart >= 0)
+			{
+				// figure out the starting child
+				begChildIndex = target.findChildIndexAtPosition(begStart);
+				child = target.getChildAt(begChildIndex) as FlowGroupElement;
+				_mementoList.push(ModelEdit.splitElement(textFlow,child,begStart-child.parentRelativeStart));
+			}
+			
+			if (begStart >= target.textLength - 1)
+				endChildIndex = target.numChildren;
+			else
+				endChildIndex = begChildIndex+1;
+			
+			
+			if (begChildIndex == target.numChildren)
+			{
+				// new list at the end of target
+				child = target.getChildAt(target.numChildren-1) as FlowGroupElement;
+				
+				_mementoList.push(ModelEdit.addElement(textFlow,_table,target,target.numChildren));
+			}
+			else
+			{
+				_mementoList.push(ModelEdit.addElement(textFlow,_table,target,endChildIndex));
+			}
+			
+			if (originalSelectionState.selectionManagerOperationState && textFlow.interactionManager)
+			{
+				textFlow.normalize();
+				_postOpSelectionState = new SelectionState(textFlow,_table.getAbsoluteStart(),_table.getAbsoluteStart()+_table.textLength-1);
+				textFlow.interactionManager.setSelectionState(_postOpSelectionState);
+			}
+			
+			return true;
+		}
+		
+		/** @private */
+		public override function undo():SelectionState
+		{
+			_mementoList.undo();
+			return originalSelectionState;  
+		}
+		
+		/**
+		 * Re-executes the operation after it has been undone.
+		 * 
+		 * <p>This function is called by the edit manager, when necessary.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		public override function redo():SelectionState
+		{ 
+			_mementoList.redo();
+			return _postOpSelectionState;
+		}
+	}
+}
\ 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/operations/InsertTextOperation.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/InsertTextOperation.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/InsertTextOperation.as
new file mode 100644
index 0000000..9ac121c
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/InsertTextOperation.as
@@ -0,0 +1,299 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.operations {
+	import org.apache.flex.textLayout.elements.IFlowElement;
+	import org.apache.flex.textLayout.elements.IFlowLeafElement;
+	import org.apache.flex.textLayout.edit.ModelEdit;
+	import org.apache.flex.textLayout.edit.ParaEdit;
+	import org.apache.flex.textLayout.edit.PointFormat;
+	import org.apache.flex.textLayout.edit.SelectionState;
+	import org.apache.flex.textLayout.edit.TextFlowEdit;
+	import org.apache.flex.textLayout.elements.ISpanElement;
+	import org.apache.flex.textLayout.formats.ITextLayoutFormat;
+	import org.apache.flex.textLayout.formats.TextLayoutFormat;
+
+
+
+
+
+	/**
+	 * The InsertTextOperation class encapsulates a text insertion operation.
+	 *
+	 * @see org.apache.flex.textLayout.edit.EditManager
+	 * @see org.apache.flex.textLayout.events.FlowOperationEvent
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class InsertTextOperation extends FlowTextOperation
+	{
+		private var _deleteSelectionState:SelectionState;
+		private var delSelOp:DeleteTextOperation = null; 
+		/** @private - this should be private but too late for code changes on Labs */
+		public var _text:String;
+		
+		private var _pointFormat:ITextLayoutFormat;
+			
+		/** 
+		 * Creates an InsertTextOperation object.
+		 * 
+		 * @param operationState Describes the insertion point or range of text.
+		 * @param text The string to insert.
+		 * @param deleteSelectionState Describes the range of text to delete before doing insertion, 
+		 * if different than the range described by <code>operationState</code>.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */	
+		public function InsertTextOperation(operationState:SelectionState, text:String, deleteSelectionState:SelectionState = null)
+		{
+			super(operationState);
+			
+			_pointFormat = operationState.pointFormat;
+			_text = text;
+			
+			initialize(deleteSelectionState);
+		}
+		
+		private function initialize(deleteSelectionState:SelectionState):void
+		{	
+			if (deleteSelectionState == null)
+				deleteSelectionState = originalSelectionState;
+			if (deleteSelectionState.anchorPosition != deleteSelectionState.activePosition)
+			{
+				_deleteSelectionState = deleteSelectionState;
+				delSelOp = new DeleteTextOperation(_deleteSelectionState);
+			}
+		}
+		
+		/** 
+		 * The text inserted by this operation. 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get text():String
+		{
+			return _text;
+		}
+		public function set text(value:String):void
+		{
+			_text = value;
+		}
+		
+		/** 
+		 * The text deleted by this operation, if any.
+		 * 
+		 * <p><code>null</code> if no text is deleted.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get deleteSelectionState():SelectionState
+		{
+			return _deleteSelectionState;
+		}
+		public function set deleteSelectionState(value:SelectionState):void
+		{
+			_deleteSelectionState = value;
+		}
+		
+		/** 
+		 * The character format applied to the inserted text.
+		 *  
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get characterFormat():ITextLayoutFormat
+		{
+			return _pointFormat;
+		}
+		public function set characterFormat(value:ITextLayoutFormat):void
+		{
+			_pointFormat = new PointFormat(value);
+		}
+		
+		private function doDelete(leaf:IFlowLeafElement):ITextLayoutFormat
+		{			
+			// User selected a range of text and is replacing it. We're doing the delete here.
+			// We preserve the format from the deleted text, and apply it to the text insert,
+			// unless the user has specified an alternate format.
+			var deleteFormat:PointFormat = PointFormat.createFromFlowElement(textFlow.findLeaf(absoluteStart));
+			var beforeDeleteFormat:PointFormat = absoluteStart == leaf.getParagraph().getAbsoluteStart() ? null : PointFormat.createFromFlowElement(textFlow.findLeaf(absoluteStart - 1));
+
+			if (delSelOp.doOperation())		// figure out what to do here
+			{
+				//do not change characterFormat if user specified one already, or if its the same as in the surrounding text.
+				// If the surrounding text is the same, forcing the point format requires more composition because it inserts
+				// the text in its own span.
+				if (!_pointFormat && (absoluteStart < absoluteEnd) && PointFormat.isEqual(deleteFormat, beforeDeleteFormat))
+					deleteFormat = null;
+				else 
+				{
+					// If the leaf element is empty, remove it now
+					if (leaf.textLength == 0) 
+						leaf.parent.removeChild(leaf);
+				}
+			} 
+			return deleteFormat;
+		}
+				
+		private function applyPointFormat(span:ISpanElement, pointFormat:ITextLayoutFormat):void
+		{
+			if (!TextLayoutFormat.isEqual(pointFormat, span.format))
+			{
+				var spanFormat:TextLayoutFormat = new TextLayoutFormat(span.format);
+				spanFormat.apply(pointFormat);
+				span.format = spanFormat;
+			}
+			if (pointFormat is PointFormat)
+			{
+				var pf:PointFormat = pointFormat as PointFormat;
+				if (pf.linkElement)
+				{
+					if (pf.linkElement.href)
+					{
+						TextFlowEdit.makeLink(textFlow, absoluteStart, absoluteStart + _text.length, pf.linkElement.href, pf.linkElement.target);
+						var linkLeaf:IFlowLeafElement = textFlow.findLeaf(absoluteStart);
+						var linkElement:IFlowElement = linkLeaf.getParentByType("LinkElement");
+						linkElement.format = pf.linkElement.format;
+					}
+				}
+				if (pf.tcyElement)
+				{
+						TextFlowEdit.makeTCY(textFlow, absoluteStart, absoluteStart + _text.length);
+						var tcyLeaf:IFlowLeafElement = textFlow.findLeaf(absoluteStart);
+						var tcyElement:IFlowElement = tcyLeaf.getParentByType("TCYElement");
+						tcyElement.format = pf.tcyElement.format;
+				}
+				else if (span.getParentByType("TCYElement"))
+					TextFlowEdit.removeTCY(textFlow, absoluteStart, absoluteStart + _text.length);
+			}
+		}
+		private function doInternal():void
+		{
+			var deleteFormat:ITextLayoutFormat;
+			
+			if (delSelOp != null) 
+				deleteFormat = doDelete(textFlow.findLeaf(absoluteStart));
+						
+			var span:ISpanElement = ParaEdit.insertText(textFlow, absoluteStart, _text, _pointFormat != null || deleteFormat != null/* createNewSpan */);
+			if (textFlow.interactionManager)
+				textFlow.interactionManager.notifyInsertOrDelete(absoluteStart, _text.length);
+			
+			if (span != null)
+			{
+				if (deleteFormat)
+				{
+					span.format = deleteFormat;
+					applyPointFormat(span, deleteFormat);
+					if ((deleteFormat is PointFormat) && PointFormat(deleteFormat).linkElement && PointFormat(deleteFormat).linkElement.href && originalSelectionState.selectionManagerOperationState && textFlow.interactionManager)
+					{
+						// set pointFormat from leafFormat, to insure link attributes are propagated from replaced text to next insertion
+						// if I select a range of text in a link, and type over it to replace, the new text should be in a link with the same settings.
+						var state:SelectionState = textFlow.interactionManager.getSelectionState();
+						state.pointFormat = PointFormat.clone(deleteFormat as PointFormat);
+						textFlow.interactionManager.setSelectionState(state);
+					}
+				}
+				if (_pointFormat)
+					applyPointFormat(span, _pointFormat);
+			}
+		}
+		
+		/** @private */
+		public override function doOperation():Boolean
+		{
+			doInternal();
+			return true;
+		}
+	
+		/** @private */
+		public override function undo():SelectionState
+		{ 
+			ModelEdit.deleteText(textFlow, absoluteStart, absoluteStart + _text.length, false);
+			
+			var newSelectionState:SelectionState = originalSelectionState;
+			if (delSelOp != null)
+				newSelectionState = delSelOp.undo();
+			
+			return originalSelectionState;
+		}
+		
+		/**
+		 * Re-executes the operation after it has been undone.
+		 * 
+		 * <p>This function is called by the edit manager, when necessary.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public override function redo():SelectionState
+		{ 
+			doInternal();
+			return new SelectionState(textFlow,absoluteStart+_text.length,absoluteStart+_text.length,null);
+		}
+
+		/** @private */
+		public override function merge(op2:FlowOperation):FlowOperation
+		{
+			if (absoluteStart < absoluteEnd)
+				return null;
+			if (this.endGeneration != op2.beginGeneration)
+				return null;
+			// We are assuming here that these operations are contiguous, because
+			// SelectionManager doesn't try to merge operations if the selection
+			// has changed
+			var insertOp:InsertTextOperation = null;
+			if (op2 is InsertTextOperation)
+				insertOp = op2 as InsertTextOperation;
+			if (insertOp)
+			{
+				if (insertOp.deleteSelectionState != null || deleteSelectionState != null)
+					return null;
+				if ((insertOp.originalSelectionState.pointFormat == null) && (originalSelectionState.pointFormat != null))
+					return null;
+				if ((originalSelectionState.pointFormat == null) && (insertOp.originalSelectionState.pointFormat != null))
+					return null;
+				if (originalSelectionState.absoluteStart + _text.length != insertOp.originalSelectionState.absoluteStart)
+					return null;
+				if (((originalSelectionState.pointFormat == null) && (insertOp.originalSelectionState.pointFormat == null)) ||
+					(PointFormat.isEqual(originalSelectionState.pointFormat, insertOp.originalSelectionState.pointFormat)))
+				{
+					_text += insertOp.text;
+					setGenerations(beginGeneration,insertOp.endGeneration);
+				}
+				else
+					return null;
+				setGenerations(beginGeneration,insertOp.endGeneration);
+				return this;
+			}
+			
+			if (op2 is SplitParagraphOperation)
+				return new CompositeOperation([this,op2]);
+
+			return null;
+		}
+	}
+}
\ 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/operations/ModifyInlineGraphicOperation.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/ModifyInlineGraphicOperation.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/ModifyInlineGraphicOperation.as
new file mode 100644
index 0000000..ca73633
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/ModifyInlineGraphicOperation.as
@@ -0,0 +1,166 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.operations {
+	import org.apache.flex.textLayout.edit.SelectionState;
+	import org.apache.flex.textLayout.elements.IFlowElement;
+	import org.apache.flex.textLayout.elements.IFlowGroupElement;
+	import org.apache.flex.textLayout.elements.InlineGraphicElement;
+
+	/**
+	 * The InsertInlineGraphicOperation class encapsulates the modification of an existing inline graphic.
+	 *
+	 * @see org.apache.flex.textLayout.elements.InlineGraphicElement
+	 * @see org.apache.flex.textLayout.edit.EditManager
+	 * @see org.apache.flex.textLayout.events.FlowOperationEvent
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class ModifyInlineGraphicOperation extends FlowTextOperation
+	{ 
+		private var _source:Object;
+		private var imageWidth:Object;
+		private var imageHeight:Object;
+		private var _options:Object;
+		private var oldImage:IFlowElement;
+		private var selPos:int = 0;
+		
+		/** 
+		 * Creates a ModifyInlineGraphicsOperation object.
+		 * 
+		 * @param operationState Describes the insertion point. 
+		 * If a range is selected, the operation deletes the contents of that range.
+		 * @param	source	The graphic source (uri string, URLRequest, DisplayObject, or Class of an embedded asset). 
+		 * @param	width	The width to assign (number of pixels, percent, or the string 'auto')
+		 * @param	height	The height to assign (number of pixels, percent, or the string 'auto')
+		 * @param	options	None supported
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		function ModifyInlineGraphicOperation(operationState:SelectionState, source:Object, width:Object, height:Object, options:Object = null)
+		{
+			super(operationState);
+							
+			_source = source;
+			_options = options;
+			imageWidth = width;
+			imageHeight = height;
+		}
+		
+		/**	
+		 * @copy org.apache.flex.textLayout.elements.InlineGraphicElement#source
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+ 		 */
+		public function get source():Object
+		{
+			return _source;
+		}
+		public function set source(value:Object):void
+		{
+			_source = value;
+		}
+
+		/** 
+		 * @copy org.apache.flex.textLayout.elements.InlineGraphicElement#width
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get width():Object
+		{
+			return imageWidth;
+		}
+		public function set width(value:Object):void
+		{
+			imageWidth = value;
+		}
+
+		/** 
+		 * @copy org.apache.flex.textLayout.elements.InlineGraphicElement#height
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get height():Object
+		{
+			return imageHeight;
+		}
+		public function set height(value:Object):void
+		{
+			imageHeight = value;
+		}
+		
+		/** 
+		 * options are not supported
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get options():Object
+		{
+			return _options;
+		}
+		public function set options(value:Object):void
+		{
+			_options = value;
+		}
+		
+		/** @private */
+		public override function doOperation():Boolean
+		{
+			selPos = absoluteStart;
+			var img:InlineGraphicElement = textFlow.findLeaf(selPos) as InlineGraphicElement;
+			if (img)
+			{
+				oldImage = img.shallowCopy(0,1);
+				// only update changed things
+				if (img.width != imageWidth)
+					img.width = imageWidth;
+				if (img.height != imageHeight)
+					img.height = imageHeight;
+				if (img.source != _source)
+					img.source = _source;
+				if (options && img.float != options.toString())
+					img.float = options.toString();
+			}
+			
+			return true;	
+		}
+	
+		/** @private */
+		public override function undo():SelectionState
+		{
+			var leafNode:IFlowElement = textFlow.findLeaf(selPos);
+			var leafNodeParent:IFlowGroupElement = leafNode.parent;
+			var elementIdx:int = leafNode.parent.getChildIndex(leafNode);
+			leafNodeParent.replaceChildren(elementIdx, elementIdx + 1, oldImage);			
+
+			return originalSelectionState; 
+		}
+	}
+}
\ No newline at end of file


Mime
View raw message