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";
+ }
+}