//////////////////////////////////////////////////////////////////////////////// // // Licensed to the Apache Software Foundation (ASF) under one or more // contributor license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright ownership. // The ASF licenses this file to You under the Apache License, Version 2.0 // (the "License"); you may not use this file except in compliance with // the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // //////////////////////////////////////////////////////////////////////////////// package flashx.textLayout.edit { /** * The ElementRange class represents the range of objects selected within a text flow. * *
The beginning elements
* (such as firstLeaf
) are always less than or equal to the end elements (in this case, lastLeaf
)
* for each pair of values in an element range.
If the range spans more than one container, the format of the first container is returned.
* * @playerversion Flash 10 * @playerversion AIR 1.5 * @langversion 3.0 */ public function get containerFormat():ITextLayoutFormat { // see NOTE above before changing!! // This is just wrong - only shows the first container var container:ContainerController; var flowComposer:IFlowComposer = firstParagraph.getTextFlow().flowComposer; if (flowComposer && flowComposer.numControllers > 0) container = flowComposer.getControllerAt(0); if (!container) return ContainerFormattedElement(firstParagraph.getParentByType(ContainerFormattedElement)).computedFormat; return container.computedFormat; } /** * The format attributes of the paragraph containing the range. * *If the range spans more than one paragraph, the format of the first paragraph is returned.
* * @playerversion Flash 10 * @playerversion AIR 1.5 * @langversion 3.0 */ public function get paragraphFormat():ITextLayoutFormat { // see NOTE above before changing!! return firstParagraph.computedFormat; } /** * The format attributes of the characters in the range. * *If the range spans more than one FlowElement object, which means that more than one * character format may exist within the range, the format of the first FlowElement object is returned.
* * @playerversion Flash 10 * @playerversion AIR 1.5 * @langversion 3.0 */ public function get characterFormat():ITextLayoutFormat { // see NOTE above before changing!! return firstLeaf.computedFormat; } /** * Creates an ElementRange object. * * @param textFlow the text flow * @param beginIndex absolute text position of the first character in the text range * @param endIndex one beyond the absolute text position of the last character in the text range * * @playerversion Flash 10 * @playerversion AIR 1.5 * @langversion 3.0 */ static public function createElementRange(textFlow:TextFlow, absoluteStart:int, absoluteEnd:int):ElementRange { var rslt:ElementRange = new ElementRange(); if (absoluteStart == absoluteEnd) { rslt.absoluteStart = rslt.absoluteEnd = absoluteStart; rslt.firstLeaf = rslt.lastLeaf = textFlow.findLeaf(rslt.absoluteStart); rslt.firstParagraph = rslt.lastParagraph = rslt.firstLeaf.getParagraph(); // rslt.begContainer = rslt.endContainer = selState.textFlow.findAbsoluteContainer(rslt.begElemIdx); adjustForLeanLeft(rslt); } else { // order the selection points if (absoluteStart < absoluteEnd) { rslt.absoluteStart = absoluteStart; rslt.absoluteEnd = absoluteEnd; } else { rslt.absoluteStart = absoluteEnd; rslt.absoluteEnd = absoluteStart; } rslt.firstLeaf = textFlow.findLeaf(rslt.absoluteStart); rslt.lastLeaf = textFlow.findLeaf(rslt.absoluteEnd); // back up one element if the end of the selection is the start of an element // otherwise a block selection of a span looks like it includes discreet selection ranges if (((rslt.lastLeaf == null) && (rslt.absoluteEnd == textFlow.textLength)) || (rslt.absoluteEnd == rslt.lastLeaf.getAbsoluteStart())) rslt.lastLeaf = textFlow.findLeaf(rslt.absoluteEnd-1); rslt.firstParagraph = rslt.firstLeaf.getParagraph(); rslt.lastParagraph = rslt.lastLeaf.getParagraph(); // rslt.begContainer = selState.textFlow.findAbsoluteContainer(rslt.begElemIdx); // rslt.endContainer = selState.textFlow.findAbsoluteContainer(rslt.endElemIdx); // if (rslt.endElemIdx == rslt.endContainer.relativeStart) // rslt.endContainer = rslt.endContainer.preventextContainer; // if the end of the range includes the next to last character in a paragraph // expand it to include the paragraph teriminate character if (rslt.absoluteEnd == rslt.lastParagraph.getAbsoluteStart() + rslt.lastParagraph.textLength - 1) { rslt.absoluteEnd++ rslt.lastLeaf = rslt.lastParagraph.getLastLeaf(); } } rslt.textFlow = textFlow; return rslt; } static private function adjustForLeanLeft(rslt:ElementRange):void { // If we're at the start of a leaf element, look to the previous leaf element and see if it shares the same // parent. If so, we're going to move the selection to the end of the previous element so it takes on // the formatting of the character to the left. We don't want to do this if the previous element is in // a different character, across link or tcy boundaries, etc. if (rslt.firstLeaf.getAbsoluteStart() == rslt.absoluteStart) { var previousNode:FlowLeafElement = rslt.firstLeaf.getPreviousLeaf(rslt.firstParagraph); if (previousNode && previousNode.getParagraph() == rslt.firstLeaf.getParagraph()) { if((!(previousNode.parent is SubParagraphGroupElement) || (previousNode.parent as SubParagraphGroupElement).acceptTextAfter()) && (!(rslt.firstLeaf.parent is SubParagraphGroupElement) || previousNode.parent === rslt.firstLeaf.parent)) rslt.firstLeaf = previousNode; } } } } }