//////////////////////////////////////////////////////////////////////////////// // // 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 UnitTest.Tests { import UnitTest.ExtendedClasses.TestDescriptor; import UnitTest.ExtendedClasses.TestSuiteExtended; import UnitTest.ExtendedClasses.VellumTestCase; import UnitTest.Fixtures.TestConfig; import flash.display.DisplayObject; import flash.display.DisplayObjectContainer; import flash.display.Graphics; import flash.display.Sprite; import flash.events.*; import flash.geom.Point; import flash.utils.Dictionary; import flash.geom.Rectangle; import flash.text.engine.TextLine; import flashx.textLayout.*; import flashx.textLayout.container.ContainerController; import flashx.textLayout.edit.*; import flashx.textLayout.elements.*; import flashx.textLayout.events.FlowElementMouseEvent; import flashx.textLayout.formats.*; import flashx.textLayout.utils.GeometryUtil; import mx.containers.Canvas; use namespace tlf_internal; public class LinkTest extends VellumTestCase { private var direction:String=""; public function LinkTest(methodName:String, testID:String, testConfig:TestConfig, testXML:XML = null) { super(methodName, testID, testConfig); // Note: These must correspond to a Watson product area (case-sensitive) metaData.productArea = "Links"; var customConfig:TestConfig = testConfig.copyTestConfig(); if ( customConfig.writingDirection[0] == "rl") direction = "vertical"; else direction = "honrizontal"; } public static function suite(testConfig:TestConfig, ts:TestSuiteExtended):void { ts.addTestDescriptor (new TestDescriptor (LinkTest, "performLinkTest", testConfig ) ); //HBS ts.addTestDescriptor (new TestDescriptor (LinkTest, "changeLinkColor", testConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "changeHoverColor", testConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "changeActiveColor", testConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "splitRejoinLinkTest", testConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "splitRejoinTargetTest", testConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "extendToOverlappingLinksTest", testConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "removeLinkTest", testConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "adjacentLinkAttributesTest", testConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "nestedLinkAttributesTest", testConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "splitLinkAttributesTest", testConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "defaultConfigAttributesTest", testConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "textAdditionTest", testConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "nestedLinkTargetTest", testConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "nestedLinkMergeTest", testConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "linkCrossingParagraphTest", testConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "linkWithCustomListenerTest", testConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "applyLinkAndRemoveAllTest", testConfig ) ); //ts.addTestDescriptor (new TestDescriptor (LinkTest, "applyLinkAndRemoveFormerTest", testConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "applyLinkAndRemoveLatterTest", testConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "applyLinkAndRemoveMiddleTest", testConfig ) ); // the descriptors added above should have a testConfig with a containerType of "sprite" // When the TestDescriptor is created it makes a new testConfig and copies over the // properties, so changing the containerType here should not affect the TestDescriptors // already created. But it does - when the tests above run it goes through the "custom" code. var customTestConfig:TestConfig = testConfig.copyTestConfig(); customTestConfig.containerType = "custom"; ts.addTestDescriptor (new TestDescriptor (LinkTest, "linkWithInlineTest", customTestConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "linkWithNullInlineTest", customTestConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "linkWithDisplayObjectTest", customTestConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "launchLinkTest", customTestConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "linkEventMirrorTest", customTestConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "spanMouseDownEventMirrorTest", customTestConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "spanMouseClickEventMirrorTest", customTestConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "spanMouseMoveEventMirrorTest", customTestConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "spanMouseUpEventMirrorTest", customTestConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "spanRollOverEventMirrorTest", customTestConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "spanRollOutEventMirrorTest", customTestConfig ) ); ts.addTestDescriptor (new TestDescriptor (LinkTest, "spanMouseEventMirrorTest", customTestConfig ) ); } override public function setUp() : void { if (containerType == "custom") { cleanUpTestApp(); } else { super.setUp(); } } /** * Selects the characters between the 30th and 50th characters and turns the selected area into a link. * Verifies that the 40th character is underneath a link. * Selects the 40th character and splits at that location. * Verifies that the first character in the new paragraph is underneath a link with the proper uri. * Undo the split operation. * Verfifies that the link is recreated in the first paragraph and is of length 20 with the proper uri. * Undo the "make link" operation. * Verifies that the 40th character is no longer underneath a link. */ public function performLinkTest():void // HBS { var startIndx:int = 30; var endIndx:int = 50; SelManager.selectRange(startIndx, endIndx); SelManager.applyLink("http://www.google.com", "_self", false); var fl:FlowElement = SelManager.textFlow.findLeaf((startIndx + endIndx) / 2) as FlowElement; var linkEl:LinkElement = fl.getParentByType(LinkElement) as LinkElement; assertTrue("link element is null", (linkEl != null)); assertTrue("expected link length of " + (endIndx - startIndx) + " but found " + linkEl.textLength, (linkEl.textLength == (endIndx - startIndx))); assertTrue("expected http://www.google.com, but found " + linkEl.href, (linkEl.href == "http://www.google.com")); //if down here, the link element was created correctly. //Now, split the linkElement in the middle, which should be //at position 40 SelManager.selectRange((startIndx + endIndx)/2, (startIndx + endIndx)/2); SelManager.splitParagraph(); //get the next paragraph and then get the first FlowElement of that paragraph. It //should be a link element var curPar:ParagraphElement = fl.getParagraph(); var curParIndex:int = curPar.parent.getChildIndex(curPar); assertTrue(true, ((curParIndex + 1) < curPar.parent.numChildren)); //if here, the split occurred fine. var newPar:ParagraphElement = curPar.parent.getChildAt(curParIndex + 1) as ParagraphElement; assertTrue(true, newPar != null); var firstFlEl:FlowElement = newPar.getChildAt(0); assertTrue(true, firstFlEl is LinkElement); var newLinkEl:LinkElement = firstFlEl as LinkElement; var expectedLength:int = (endIndx - startIndx) / 2; //check to see if new link element is expected length or expected length + 1 (since //a newline could have been appended to it. assertTrue(true, ((expectedLength == newLinkEl.textLength) || (expectedLength == newLinkEl.textLength - 1))); assertTrue(true, (newLinkEl.href == "http://www.google.com")); //undoing the split operation. SelManager.undo(); assertTrue(true, (linkEl != null)); assertTrue(true, (linkEl.textLength == (endIndx - startIndx))); assertTrue(true, (linkEl.href == "http://www.google.com")); //undo the make link operation. SelManager.undo(); fl = SelManager.textFlow.findLeaf((startIndx + endIndx) / 2) as FlowElement; linkEl = fl.getParentByType(LinkElement) as LinkElement; assertTrue(true, (linkEl == null)); } /** * Selects the text between 30 and 50 and makes it a link to google. * Then inverts the link's color. */ public function changeLinkColor():void { var startIndx:int = 30; var endIndx:int = 50; SelManager.selectRange(startIndx, endIndx); SelManager.applyLink("http://www.google.com", "_self", false); var fl:FlowElement = SelManager.textFlow.findLeaf((startIndx + endIndx) / 2) as FlowElement; var linkEl:LinkElement = fl.getParentByType(LinkElement) as LinkElement; var newColor:uint = ~(linkEl.effectiveLinkElementTextLayoutFormat.color as uint) as uint; var d:Dictionary = new Dictionary(); d[TextLayoutFormat.colorProperty.name] = newColor; linkEl.linkNormalFormat = d; assertTrue(linkEl.linkNormalFormat != null && linkEl.linkNormalFormat[TextLayoutFormat.colorProperty.name] == newColor); } /** * Selects the text between 30 and 50 and makes it a link to google. * Then inverts the link's hover color. */ public function changeHoverColor():void { var startIndx:int = 30; var endIndx:int = 50; SelManager.selectRange(startIndx, endIndx); SelManager.applyLink("http://www.google.com", "_self", false); var fl:FlowElement = SelManager.textFlow.findLeaf((startIndx + endIndx) / 2) as FlowElement; var linkEl:LinkElement = fl.getParentByType(LinkElement) as LinkElement; var newColor:uint = ~(linkEl.effectiveLinkElementTextLayoutFormat.color as uint) as uint; var d:Dictionary = new Dictionary(); d[TextLayoutFormat.colorProperty.name] = newColor; linkEl.linkHoverFormat = d; assertTrue(linkEl.linkHoverFormat != null && linkEl.linkHoverFormat[TextLayoutFormat.colorProperty.name] == newColor); } /** * Selects the text between 30 and 50 and makes it a link to google. * Then inverts the link's active color. */ public function changeActiveColor():void { var startIndx:int = 30; var endIndx:int = 50; SelManager.selectRange(startIndx, endIndx); SelManager.applyLink("http://www.google.com", "_self", false); var fl:FlowElement = SelManager.textFlow.findLeaf((startIndx + endIndx) / 2) as FlowElement; var linkEl:LinkElement = fl.getParentByType(LinkElement) as LinkElement; var newColor:uint = ~(linkEl.effectiveLinkElementTextLayoutFormat.color as uint) as uint; var d:Dictionary = new Dictionary(); d[TextLayoutFormat.colorProperty.name] = newColor; linkEl.linkActiveFormat = d; assertTrue(linkEl.linkActiveFormat != null && linkEl.linkActiveFormat[TextLayoutFormat.colorProperty.name] == newColor); } /** * Creates a link in the first line, then turns a portion of that link * into a different link. Then splits the two links on the border between them * and undoes the opperation. Subsequently checks to see that both link * exist and point to their respective destinations. */ public function splitRejoinLinkTest():void { var startIndx:int = 10; var endIndx:int = 50; SelManager.selectRange(startIndx, endIndx); SelManager.applyLink("http://www.google.com", "_self", false); SelManager.selectRange(startIndx + 15, endIndx - 15); SelManager.applyLink("http://maps.google.com", "_self", false); SelManager.selectRange(startIndx + 16, startIndx + 16); SelManager.splitParagraph(); //undoing the split operation. SelManager.undo(); var first:FlowElement = SelManager.textFlow.findLeaf(startIndx); var second:FlowElement = SelManager.textFlow.findLeaf((startIndx + endIndx) / 2); var linkOne:LinkElement = first.getParentByType(LinkElement) as LinkElement; var linkTwo:LinkElement = second.getParentByType(LinkElement) as LinkElement; assertTrue(linkOne != linkTwo); assertTrue(linkOne.href != linkTwo.href); } /** * Creates a link in the first line, then changes a portion of the link to * have a different target. Then splits the two links on the border between * them and undoes the opperation. Subsequently checks to see that both link * exist and point to their respective destinations. */ public function splitRejoinTargetTest():void { var startIndx:int = 10; var endIndx:int = 50; SelManager.selectRange(startIndx, endIndx); SelManager.applyLink("http://www.google.com", "_self", false); SelManager.selectRange(startIndx + 15, endIndx - 15); SelManager.applyLink("http://www.google.com", "_top", false); SelManager.selectRange(startIndx + 16, startIndx + 16); SelManager.splitParagraph(); //undoing the split operation. SelManager.undo(); var first:FlowElement = SelManager.textFlow.findLeaf(startIndx); var second:FlowElement = SelManager.textFlow.findLeaf((startIndx + endIndx) / 2); var linkOne:LinkElement = first.getParentByType(LinkElement) as LinkElement; var linkTwo:LinkElement = second.getParentByType(LinkElement) as LinkElement; assertTrue(linkOne != linkTwo); assertTrue(linkOne.target != linkTwo.target); } /** * Selects the characters between the 30th and 50th characters and turns the selected area into a link. * Selects the characters between the 35th and 45th charactets and applies a new link with extendToOverlappingLinks set to true * Verifies that the 30th character is underneath a link with the second URL * Undo the "make link" operations. * Turns the selected area into a link. * Selects the characters between the 35th and 45th charactets and applies a new link (blank target, extendToOverlappingLinks set to true) * Verifies that the 30th character is no longer underneath a link. */ public function extendToOverlappingLinksTest():void // HBS { var startIndx:int = 30; var endIndx:int = 50; SelManager.selectRange(startIndx, endIndx); SelManager.applyLink("http://www.google.com", "_self", false); SelManager.selectRange(startIndx+5, endIndx-5); SelManager.applyLink("http://www.live.com", "_self", true); var fl:FlowElement = SelManager.textFlow.findLeaf(startIndx) as FlowElement; var linkEl:LinkElement = fl.getParentByType(LinkElement) as LinkElement; assertTrue("link element is null", (linkEl != null)); assertTrue("expected link length of " + (endIndx - startIndx) + " but found " + linkEl.textLength, (linkEl.textLength == (endIndx - startIndx))); assertTrue("expected http://www.live.com, but found " + linkEl.href, (linkEl.href == "http://www.live.com")); //undo the make link operations. SelManager.undo(); SelManager.undo(); SelManager.selectRange(startIndx, endIndx); SelManager.applyLink("http://www.google.com", "_self", false); SelManager.selectRange(startIndx+5, endIndx-5); SelManager.applyLink("", "_self", true); fl = SelManager.textFlow.findLeaf(startIndx) as FlowElement; linkEl = fl.getParentByType(LinkElement) as LinkElement; assertTrue(true, (linkEl == null)); } /** * Determines where there is a paragraph break and tries to create a link * across it. Since links are sub paragraph blocks, this shouldn't happen. * Instead there should be two different links with the same attributes. */ public function linkCrossingParagraphTest():void { var startIndx:int = 30; var endIndx:int = 50; var splitIndx:int = 40; SelManager.selectRange(splitIndx, splitIndx); SelManager.splitParagraph(); SelManager.flushPendingOperations() SelManager.selectRange(startIndx, endIndx); var firstLinkCreated:LinkElement = SelManager.applyLink("http://www.google.com", "_self", false); var start:FlowElement = SelManager.textFlow.findLeaf(splitIndx-2) as FlowElement; var linkStart:LinkElement = start.getParentByType(LinkElement) as LinkElement; assertTrue("EditManager.applyLink not returning firstLinkCreated", firstLinkCreated == linkStart); var end:FlowElement = SelManager.textFlow.findLeaf(splitIndx+2) as FlowElement; var linkEnd:LinkElement = end.getParentByType(LinkElement) as LinkElement; assertTrue("Link not created correctly!",linkStart != null && linkEnd != null); assertTrue("Link spans paragraph!",linkStart != linkEnd); assertTrue("Link hrefs not identical!",linkStart.href == linkEnd.href); assertTrue("Link targets not identical!",linkStart.target == linkEnd.target); } /** * First make a link, then shift the select and set the link to null. Verify * that the link is removed in the new selection. */ public function removeLinkTest():void { var startIndx:int = 30; var endIndx:int = 50; SelManager.selectRange(startIndx, endIndx); SelManager.applyLink("http://www.google.com", "_self", false); var fl:FlowElement = SelManager.textFlow.findLeaf((startIndx + endIndx) / 2) as FlowElement; var linkEl:LinkElement = fl.getParentByType(LinkElement) as LinkElement; assertTrue("Link not set! Value is " + linkEl.href, linkEl.href == "http://www.google.com"); assertTrue("Target not set! Value is " + linkEl.target, linkEl.target == "_self"); startIndx = 40; endIndx = 60; SelManager.selectRange(startIndx, endIndx); SelManager.applyLink(null, null, false); // remove by passing null // Check that it was removed fl = SelManager.textFlow.findLeaf((startIndx + endIndx) / 2) as FlowElement; linkEl = fl.getParentByType(LinkElement) as LinkElement; assertTrue("Link not removed!", !linkEl); SelManager.selectRange(startIndx, endIndx); SelManager.applyLink("http://www.google.com", "_self", false); SelManager.selectRange(startIndx, endIndx); SelManager.applyLink("", null, false); // remove by passing empty string // Check that it was removed fl = SelManager.textFlow.findLeaf((startIndx + endIndx) / 2) as FlowElement; linkEl = fl.getParentByType(LinkElement) as LinkElement; assertTrue("Link not removed!", !linkEl); } /** * Create two adjacent links with the same target then change their active color * attributes to be different. Ensure that they don't get merged. */ public function adjacentLinkAttributesTest():void { var startIndx:int = 30; var midIndx:int = 40; var endIndx:int = 50; SelManager.selectRange(startIndx, midIndx); SelManager.applyLink("http://www.google.com", "_self", false); var fl:FlowElement = SelManager.textFlow.findLeaf((startIndx + midIndx) / 2) as FlowElement; var linkEl:LinkElement = fl.getParentByType(LinkElement) as LinkElement; var d:Dictionary = new Dictionary(); d[TextLayoutFormat.colorProperty.name] = 0x0000FF; linkEl.linkActiveFormat = d; SelManager.selectRange(midIndx, endIndx); SelManager.applyLink("http://www.google.com", "_parent", false); var fl2:FlowElement = SelManager.textFlow.findLeaf((midIndx + endIndx) / 2) as FlowElement; var linkEl2:LinkElement = fl2.getParentByType(LinkElement) as LinkElement; d = new Dictionary(); d[TextLayoutFormat.colorProperty.name] = 0xFFFF00; linkEl2.linkActiveFormat = d; SelManager.flushPendingOperations(); fl = SelManager.textFlow.findLeaf((startIndx + midIndx) / 2) as FlowElement; linkEl = fl.getParentByType(LinkElement) as LinkElement; fl2 = SelManager.textFlow.findLeaf((midIndx + endIndx) / 2) as FlowElement; linkEl2 = fl2.getParentByType(LinkElement) as LinkElement; assertTrue("Link elements with different active link formats were merged", linkEl != linkEl2 ); var linkElColor:* = linkEl.linkActiveFormat == null ? undefined : linkEl.linkActiveFormat[TextLayoutFormat.colorProperty.name]; var linkEl2Color:* = linkEl2.linkActiveFormat == null ? undefined : linkEl2.linkActiveFormat[TextLayoutFormat.colorProperty.name]; assertTrue("Link elements with different active link colors did not preserve their colors",linkEl2Color === 0xFFFF00 && linkElColor === 0xff); } /** * Create two nested links with the same target then change their active color * attributes to be different. Ensure that they don't get merged. */ public function nestedLinkAttributesTest():void { var startIndx:int = 30; var startIndx2:int = 35; var endIndx2:int = 45; var endIndx:int = 50; SelManager.selectRange(startIndx, endIndx); SelManager.applyLink("http://www.google.com", "_self", false); var fl:FlowElement = SelManager.textFlow.findLeaf((startIndx + endIndx) / 2) as FlowElement; var linkEl:LinkElement = fl.getParentByType(LinkElement) as LinkElement; var firstCharForm:Dictionary = new Dictionary(); firstCharForm[TextLayoutFormat.colorProperty.name] = 0x0000FF; linkEl.linkActiveFormat = firstCharForm; SelManager.selectRange(startIndx2, endIndx2); SelManager.applyLink("http://www.google.com", "_top", false); var fl2:FlowElement = SelManager.textFlow.findLeaf((startIndx2 + endIndx2) / 2) as FlowElement; var linkEl2:LinkElement = fl2.getParentByType(LinkElement) as LinkElement; var secondCharForm:Dictionary = new Dictionary(); secondCharForm[TextLayoutFormat.colorProperty.name] = 0xFFFF00; linkEl2.linkActiveFormat = secondCharForm; SelManager.flushPendingOperations(); fl = SelManager.textFlow.findLeaf((startIndx + startIndx2) / 2) as FlowElement; linkEl = fl.getParentByType(LinkElement) as LinkElement; fl2 = SelManager.textFlow.findLeaf((startIndx2 + endIndx2) / 2) as FlowElement; linkEl2 = fl2.getParentByType(LinkElement) as LinkElement; var fl3:FlowElement = SelManager.textFlow.findLeaf((endIndx2 + endIndx) / 2) as FlowElement; var linkEl3:LinkElement = fl3.getParentByType(LinkElement) as LinkElement; assertTrue("Link elements with different active link formats were merged", (linkEl != linkEl2) && (linkEl2 != linkEl3) ); var linkElColor:* = linkEl.linkActiveFormat == null ? undefined : linkEl.linkActiveFormat[TextLayoutFormat.colorProperty.name]; var linkEl2Color:* = linkEl2.linkActiveFormat == null ? undefined : linkEl2.linkActiveFormat[TextLayoutFormat.colorProperty.name]; assertTrue("Link elements with different active link colors did not preserve their colors",linkEl2Color === 0xFFFF00 && linkElColor === 0xff); } /** * Create a link, then set the color attributes. * Split the link and change the color attributes of the first half. * Ensure that the second half doesn't get the new attributes. */ public function splitLinkAttributesTest():void { var startIndx:int = 30; var midIndx:int = 40; var endIndx:int = 50; SelManager.selectRange(startIndx, endIndx); SelManager.applyLink("http://www.google.com", "_self", false); var fl:FlowElement = SelManager.textFlow.findLeaf((startIndx + endIndx) / 2) as FlowElement; var linkEl:LinkElement = fl.getParentByType(LinkElement) as LinkElement; var firstCharForm:Dictionary = new Dictionary(); firstCharForm[TextLayoutFormat.colorProperty.name] = 0x0000FF; linkEl.linkActiveFormat = firstCharForm; SelManager.selectRange(midIndx, midIndx); SelManager.splitParagraph(); SelManager.flushPendingOperations(); fl = SelManager.textFlow.findLeaf((startIndx + midIndx) / 2) as FlowElement; linkEl = fl.getParentByType(LinkElement) as LinkElement; var fl2:FlowElement = SelManager.textFlow.findLeaf((midIndx + endIndx) / 2) as FlowElement; var linkEl2:LinkElement = fl2.getParentByType(LinkElement) as LinkElement; var secondCharForm:Dictionary = new Dictionary(); secondCharForm[TextLayoutFormat.colorProperty.name] = 0xFFFF00; linkEl2.linkActiveFormat = secondCharForm; SelManager.flushPendingOperations(); assertTrue("Link elements with different active link formats were merged", linkEl != linkEl2 ); var linkElColor:* = linkEl.linkActiveFormat == null ? undefined : linkEl.linkActiveFormat[TextLayoutFormat.colorProperty.name]; var linkEl2Color:* = linkEl2.linkActiveFormat == null ? undefined : linkEl2.linkActiveFormat[TextLayoutFormat.colorProperty.name]; assertTrue("Link elements with different active link colors did not preserve their colors",linkEl2Color === 0xFFFF00 && linkElColor === 0xff); } /** * Change the DefaultConfiguration in TextFlow. * Create a new TextFlow. * Verify that the new flow has the new default configuration. */ public function defaultConfigAttributesTest():void { var actColor:uint = 0x0000FF; var hovColor:uint = 0x00FF00; var linkColor:uint = 0xFF0000; /* var actFormat:Dictionary = new Dictionary(); actFormat[TextLayoutFormat.colorProperty.name] = actColor; var hovFormat:Dictionary = new Dictionary(); hovFormat[TextLayoutFormat.colorProperty.name] = hovColor; var linkFormat:Dictionary = new Dictionary(); linkFormat[TextLayoutFormat.colorProperty.name] = linkColor; */ var actFormat:TextLayoutFormat = new TextLayoutFormat(); actFormat.color = actColor; var hovFormat:TextLayoutFormat = new TextLayoutFormat(); hovFormat.color = hovColor; var linkFormat:TextLayoutFormat = new TextLayoutFormat(); linkFormat.color = linkColor; var testConfig:Configuration = new Configuration(); testConfig.defaultLinkActiveFormat = actFormat; testConfig.defaultLinkNormalFormat = linkFormat; testConfig.defaultLinkHoverFormat = hovFormat; var newFlow:TextFlow = new TextFlow(testConfig); assertTrue("Active format was not applied.",TextLayoutFormat.isEqual(newFlow.configuration.defaultLinkActiveFormat,actFormat)); assertTrue("Hover format was not applied.",TextLayoutFormat.isEqual(newFlow.configuration.defaultLinkHoverFormat,hovFormat)); assertTrue("Link format was not applied.",TextLayoutFormat.isEqual(newFlow.configuration.defaultLinkNormalFormat,linkFormat)); } /** * Insert text at the end of a link. * Verify that the new text is not a link. */ public function textAdditionTest():void { var startIndx:int = 30; var endIndx:int = 50; SelManager.selectRange(startIndx, endIndx); SelManager.applyLink("http://www.google.com", "_self", false); SelManager.flushPendingOperations(); SelManager.selectRange(endIndx, endIndx); SelManager.insertText("I should not be a link."); var fl:FlowElement = SelManager.textFlow.findLeaf(endIndx + 2) as FlowElement; assertTrue("Inserted text became a link!",!(fl is LinkElement)); SelManager.selectRange(startIndx, startIndx); SelManager.insertText("I should not be a link."); fl = SelManager.textFlow.findLeaf(startIndx + 2) as FlowElement; assertTrue("Inserted text became a link!",!(fl is LinkElement)); } /** * Create two nested links with the same target. * Change the outer link's target. * Verify that the inner link doesn't change it's target. * Verify that both sides of the outer link change. */ public function nestedLinkTargetTest():void { var startIndx:int = 30; var startIndx2:int = 35; var endIndx2:int = 45; var endIndx:int = 50; SelManager.selectRange(startIndx, endIndx); SelManager.applyLink("http://www.google.com", "_self", false); var fl:FlowElement = SelManager.textFlow.findLeaf((startIndx + endIndx) / 2) as FlowElement; var linkEl:LinkElement = fl.getParentByType(LinkElement) as LinkElement; SelManager.selectRange(startIndx2, endIndx2); SelManager.applyLink("http://www.google.com", "_none", false); var fl2:FlowElement = SelManager.textFlow.findLeaf((startIndx2 + endIndx2) / 2) as FlowElement; var linkEl2:LinkElement = fl2.getParentByType(LinkElement) as LinkElement; linkEl2.target = "http://slashdot.org"; SelManager.flushPendingOperations(); fl = SelManager.textFlow.findLeaf((startIndx + startIndx2) / 2) as FlowElement; linkEl = fl.getParentByType(LinkElement) as LinkElement; fl2 = SelManager.textFlow.findLeaf((startIndx2 + endIndx2) / 2) as FlowElement; linkEl2 = fl2.getParentByType(LinkElement) as LinkElement; var fl3:FlowElement = SelManager.textFlow.findLeaf((endIndx2 + endIndx) / 2) as FlowElement; var linkEl3:LinkElement = fl3.getParentByType(LinkElement) as LinkElement; assertTrue("Link elements with different targets were merged.", (linkEl != linkEl2) && (linkEl2 != linkEl3) ); assertTrue("Link elements with different targets didn't preserve their targets", (linkEl.target != linkEl2.target) && (linkEl2.target != linkEl.target) && (linkEl3.target == linkEl.target) ); } /** * Create two nested links with the same target. * Change the outer link's target. * Verify that the inner link doesn't change it's target. * Verify that both sides of the outer link change. */ public function nestedLinkMergeTest():void { var startIndx:int = 30; var startIndx2:int = 35; var endIndx2:int = 45; var endIndx:int = 50; SelManager.selectRange(startIndx, endIndx); SelManager.applyLink("http://www.google.com", "_self", false); var fl:FlowElement = SelManager.textFlow.findLeaf((startIndx + endIndx) / 2) as FlowElement; var linkEl:LinkElement = fl.getParentByType(LinkElement) as LinkElement; SelManager.selectRange(startIndx2, endIndx2); SelManager.applyLink("http://www.google.com", "_self", false); var fl2:FlowElement = SelManager.textFlow.findLeaf((startIndx2 + endIndx2) / 2) as FlowElement; var linkEl2:LinkElement = fl2.getParentByType(LinkElement) as LinkElement; linkEl2.target = "http://slashdot.org"; SelManager.flushPendingOperations(); fl = SelManager.textFlow.findLeaf((startIndx + startIndx2) / 2) as FlowElement; linkEl = fl.getParentByType(LinkElement) as LinkElement; fl2 = SelManager.textFlow.findLeaf((startIndx2 + endIndx2) / 2) as FlowElement; linkEl2 = fl2.getParentByType(LinkElement) as LinkElement; var fl3:FlowElement = SelManager.textFlow.findLeaf((endIndx2 + endIndx) / 2) as FlowElement; var linkEl3:LinkElement = fl3.getParentByType(LinkElement) as LinkElement; assertTrue("Link elements were not merged.", (linkEl === linkEl2) ); } private static function listener(e:Event):void { } public function linkWithCustomListenerTest():void { var tf:TextFlow = new TextFlow(); tf.flowComposer.addController(new ContainerController(new Sprite())); var p:ParagraphElement = new ParagraphElement(); tf.addChild(p); // first link var span1:SpanElement = new SpanElement(); span1.text = "span1"; var link1:LinkElement = new LinkElement(); link1.addChild(span1); p.addChild(link1); // second link var span2:SpanElement = new SpanElement(); span2.text = "span2"; var link2:LinkElement = new LinkElement(); link2.addChild(span2); p.addChild(link2); link2.getEventMirror().addEventListener("test",listener); tf.flowComposer.updateAllControllers(); assertTrue("Links with custom mirror events should not merge", link1.parent == p && link2.parent == p); } public function linkWithInlineTest():void { doLinkWithInlineTest("http://www.adobe.com/shockwave/download/images/flashplayer_100x100.jpg"); } public function linkWithNullInlineTest():void { doLinkWithInlineTest(null); } public function linkWithDisplayObjectTest():void { // Create a simple rectangular display object for the float var displayObject:Sprite = new Sprite(); var g:Graphics = displayObject.graphics; g.beginFill(0xFF00FF); g.drawRect(0, 0, 100, 100); g.endFill(); doLinkWithInlineTest(displayObject); } private function doLinkWithInlineTest(source:Object):void { var s:Sprite = new Sprite(); var TestCanvas:Canvas = testApp.getDisplayObject(); TestCanvas.rawChildren.addChild(s); var _textFlow:TextFlow = new TextFlow(); _textFlow.fontSize = 48; var p:ParagraphElement = new ParagraphElement(); _textFlow.addChild(p); var span:SpanElement = new SpanElement(); span.text = "Hello "; p.addChild(span); var link:LinkElement = new LinkElement(); link.href = "http://www.adobe.com"; // graphic doesn't load var inlineGraphic:InlineGraphicElement = new InlineGraphicElement(); if (source) inlineGraphic.source = source; inlineGraphic.width = 100; inlineGraphic.height = 100; link.addChild(inlineGraphic); p.addChild(link); var span2:SpanElement = new SpanElement(); span2.text = " World"; p.addChild(span2); _textFlow.flowComposer.addController(new ContainerController(s,400,200)); // this call compose but the graphic hasn't been loaded from the source URL yet. _textFlow.flowComposer.updateAllControllers(); var inline:DisplayObject = inlineGraphic.graphic; if (inline.width > 0 && inline.height > 0) // try simulating a click { var eventCount:int = 0; link.href = "event:customEvent"; link.getEventMirror().addEventListener(FlowElementMouseEvent.CLICK,listener); _textFlow.flowComposer.updateAllControllers(); var controller:ContainerController = _textFlow.flowComposer.getControllerAt(0); var x:Number = inline.x + inline.width / 2; var y:Number = inline.y + inline.height / 2; var pt:Point = new Point(x, y); pt = inline.localToGlobal(pt); pt = controller.container.globalToLocal(pt); controller.container.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_DOWN, true, false, pt.x, pt.y)); controller.container.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_UP, true, false, pt.x, pt.y)); assertTrue("Custom listener should have received click", eventCount == 1); } function listener(e:Event):void { eventCount++; } } private function applyLink(startIndx:int,endIndx:int):void { /* apply the link from startIndx to endIndx then calling applyLink(null) to remove the selection */ SelManager.selectRange(startIndx, endIndx); SelManager.applyLink("http://www.google.com", "_self", false); var fl:FlowElement = SelManager.textFlow.findLeaf((startIndx + endIndx) / 2) as FlowElement; var linkEl:LinkElement = fl.getParentByType(LinkElement) as LinkElement; //check that the link and target are set assertTrue("Link not set! Value is " + linkEl.href, linkEl.href == "http://www.google.com"); assertTrue("Target not set! Value is " + linkEl.target, linkEl.target == "_self"); } private function removeLink(startIndx:int,endIndx:int):void { //remove the link from startIndx to endIndx SelManager.selectRange(startIndx, endIndx); SelManager.applyLink(null, null, false); // remove by passing null } public function applyLinkAndRemoveAllTest():void { //apply the link from 30 to 50 applyLink(30,50); //remove the link from 30 to 50 removeLink(30,50); // Check that it was removed var fl:FlowElement = SelManager.textFlow.findLeaf((30 + 50) / 2) as FlowElement; var linkEl:LinkElement = fl.getParentByType(LinkElement) as LinkElement; assertTrue("Link not removed when applyLink(null) called!", !linkEl); } /** apply the link from 30 to 50 then remove the selection of 25, 40 check no link element parent for index 35, but the link remains at index 45 */ public function applyLinkAndRemoveFormerTest():void { applyLink(30,50); //remove a selection of 25, 40 removeLink(25,40); //Check that no link element parent for index 35, but the link remains at index 45 var fl:FlowElement = SelManager.textFlow.findLeaf(35) as FlowElement; var linkEl:LinkElement = fl.getParentByType(LinkElement) as LinkElement; assertTrue("Link element parent for index 35 not removed when applyLink(null) called",!linkEl ); fl = SelManager.textFlow.findLeaf(45) as FlowElement; linkEl = fl.getParentByType(LinkElement) as LinkElement; assertTrue("Link element parent for index 45 not remain when applyLink(null) called",linkEl ); } /** apply the link from 30 to 50 then remove the selection of 40, 55 check the link remains at index 35, but is not present at index 45 */ public function applyLinkAndRemoveLatterTest():void { applyLink(30,50); //remove a selection of 40, 55 removeLink(40,55); //Check that the link remains at index 35, but is not present at index 45 var fl:FlowElement = SelManager.textFlow.findLeaf(35) as FlowElement; var linkEl:LinkElement = fl.getParentByType(LinkElement) as LinkElement; assertTrue("Link element parent for index 35 not ramain when applyLink(null) called",linkEl ); fl = SelManager.textFlow.findLeaf(45) as FlowElement; linkEl = fl.getParentByType(LinkElement) as LinkElement; assertTrue("Link element parent for index 45 not removed when applyLink(null) called",!linkEl ); } /** apply the link from 30 to 50 then remove the selection of 35, 45 check no link at index 40, but there should be two separate link elements now */ public function applyLinkAndRemoveMiddleTest():void { applyLink(30,50); //remove a selection of 35, 45 removeLink(35,45); //Check that no link at index 40, but there should be two separate link elements now var fl:FlowElement = SelManager.textFlow.findLeaf(40) as FlowElement; var linkEl:LinkElement = fl.getParentByType(LinkElement) as LinkElement; assertTrue("Link element parent for index 40 not removed when applyLink(null) called",!linkEl ); fl = SelManager.textFlow.findLeaf(30) as FlowElement; linkEl = fl.getParentByType(LinkElement) as LinkElement; assertTrue("Link element parent for index 30 not remain when applyLink(null) called",linkEl ); fl = SelManager.textFlow.findLeaf(49) as FlowElement; linkEl = fl.getParentByType(LinkElement) as LinkElement; assertTrue("Link element parent for index 49 not remain when applyLink(null) called",linkEl ); } private var tf:TextFlow = new TextFlow(); public function launchLinkTest():void { if (direction == "vertical") { var format:TextLayoutFormat = new TextLayoutFormat(); format.fontFamily = "Arial"; format.fontSize = 16; format.direction = "ltr"; format.blockProgression = "rl"; tf.hostFormat = format; } var p:ParagraphElement = new ParagraphElement(); tf.addChild(p); var link:LinkElement = new LinkElement(); link.href = "event:customEvent"; var span:SpanElement = new SpanElement(); span.text = "Hello world"; span.fontSize = 16; link.addChild(span); p.addChild(link); var container:Sprite = new Sprite(); var TestCanvas:Canvas = testApp.getDisplayObject(); TestCanvas.rawChildren.addChild(container); var cc:ContainerController = new ContainerController(container,100,50); tf.flowComposer.addController(cc); tf.flowComposer.updateAllControllers(); var editmanager:EditManager = new EditManager(); tf.interactionManager = editmanager; editmanager.selectRange(2, 6); // Get the bounds of the link in TextLine coordinates var boundsInfo:Object = GeometryUtil.getHighlightBounds(editmanager.getSelectionState())[0]; var bounds:Rectangle = boundsInfo.rect as Rectangle; var textLine:TextLine = boundsInfo.textLine; tf.addEventListener("customEvent", addAsync(checkEvent,2500,null),false,0,true); tf.flowComposer.updateAllControllers(); tf.interactionManager = null; textLine.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_DOWN, true, false, (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine)); textLine.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_UP, true, false, (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine)); tf.interactionManager = editmanager; editmanager.selectRange(0, 0); } public function linkEventMirrorTest():void { if (direction == "vertical") { var format:TextLayoutFormat = new TextLayoutFormat(); format.fontFamily = "Arial"; format.fontSize = 16; format.direction = "ltr"; format.blockProgression = "rl"; tf.hostFormat = format; } var p:ParagraphElement = new ParagraphElement(); tf.addChild(p); var link:LinkElement = new LinkElement(); link.href = "event:customEvent"; var span:SpanElement = new SpanElement(); span.text = "Hello world"; span.fontSize = 16; link.addChild(span); p.addChild(link); var container:Sprite = new Sprite(); var TestCanvas:Canvas = testApp.getDisplayObject(); TestCanvas.rawChildren.addChild(container); var cc:ContainerController = new ContainerController(container,100,50); tf.flowComposer.addController(cc); tf.flowComposer.updateAllControllers(); link.getEventMirror().addEventListener("customEvent", addAsync(checkEvent,2500,null),false,0,true); tf.flowComposer.updateAllControllers(); var editmanager:EditManager = new EditManager(); tf.interactionManager = editmanager; editmanager.selectRange(2, 6); // Get the bounds of the link in TextLine coordinates var boundsInfo:Object = GeometryUtil.getHighlightBounds(editmanager.getSelectionState())[0]; var bounds:Rectangle = boundsInfo.rect as Rectangle; var textLine:TextLine = boundsInfo.textLine; tf.interactionManager = null; textLine.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_DOWN, true, false, (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine)); textLine.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_UP, true, false, (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine)); tf.interactionManager = editmanager; editmanager.selectRange(0, 0); } public function spanMouseDownEventMirrorTest():void { if (direction == "vertical") { var format:TextLayoutFormat = new TextLayoutFormat(); format.fontFamily = "Arial"; format.fontSize = 16; format.direction = "ltr"; format.blockProgression = "rl"; tf.hostFormat = format; } var p:ParagraphElement = new ParagraphElement(); tf.addChild(p); var span:SpanElement = new SpanElement(); span.text = "Hello world"; span.fontSize = 16; span.getEventMirror().addEventListener(FlowElementMouseEvent.MOUSE_DOWN, addAsync(checkMouseDownEvent,2500,null),false,0,true); p.addChild(span); var container:Sprite = new Sprite(); var TestCanvas:Canvas = testApp.getDisplayObject(); TestCanvas.rawChildren.addChild(container); var cc:ContainerController = new ContainerController(container,100,50); tf.flowComposer.addController(cc); tf.flowComposer.updateAllControllers(); var editmanager:EditManager = new EditManager(); tf.interactionManager = editmanager; editmanager.selectRange(2, 4); tf.flowComposer.addController(new ContainerController(container,200,100)); tf.flowComposer.updateAllControllers(); // Get the bounds of the link in TextLine coordinates var boundsInfo:Object = GeometryUtil.getHighlightBounds(editmanager.getSelectionState())[0]; var bounds:Rectangle = boundsInfo.rect as Rectangle; var textLine:TextLine = boundsInfo.textLine; tf.interactionManager = null; textLine.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_DOWN, true, false, (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine)); tf.interactionManager = editmanager; editmanager.selectRange(0, 0); } public function spanMouseClickEventMirrorTest():void { if (direction == "vertical") { var format:TextLayoutFormat = new TextLayoutFormat(); format.fontFamily = "Arial"; format.fontSize = 16; format.direction = "ltr"; format.blockProgression = "rl"; tf.hostFormat = format; } var p:ParagraphElement = new ParagraphElement(); tf.addChild(p); var span:SpanElement = new SpanElement(); span.text = "Hello world"; span.fontSize = 16; span.getEventMirror().addEventListener(FlowElementMouseEvent.CLICK, addAsync(checkMouseClickEvent,2500,null),false,0,true); p.addChild(span); var container:Sprite = new Sprite(); var TestCanvas:Canvas = testApp.getDisplayObject(); TestCanvas.rawChildren.addChild(container); var cc:ContainerController = new ContainerController(container,100,50); tf.flowComposer.addController(cc); tf.flowComposer.updateAllControllers(); var editmanager:EditManager = new EditManager(); tf.interactionManager = editmanager; editmanager.selectRange(2, 4); tf.flowComposer.addController(new ContainerController(container,200,100)); tf.flowComposer.updateAllControllers(); // Get the bounds of the link in TextLine coordinates var boundsInfo:Object = GeometryUtil.getHighlightBounds(editmanager.getSelectionState())[0]; var bounds:Rectangle = boundsInfo.rect as Rectangle; var textLine:TextLine = boundsInfo.textLine; tf.interactionManager = null; //dispatch mouse events textLine.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_DOWN, true, false, (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine)); textLine.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_UP, true, false, (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine)); textLine.dispatchEvent(new MouseEvent(MouseEvent.CLICK, true, false, (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine)); tf.interactionManager = editmanager; editmanager.selectRange(0, 0); } public function spanMouseMoveEventMirrorTest():void { if (direction == "vertical") { var format:TextLayoutFormat = new TextLayoutFormat(); format.fontFamily = "Arial"; format.fontSize = 16; format.direction = "ltr"; format.blockProgression = "rl"; tf.hostFormat = format; } var p:ParagraphElement = new ParagraphElement(); tf.addChild(p); var span:SpanElement = new SpanElement(); span.text = "Hello world"; span.fontSize = 16; span.getEventMirror().addEventListener(FlowElementMouseEvent.MOUSE_MOVE, addAsync(checkMouseMoveEvent,2500,null),false,0,true); p.addChild(span); var container:Sprite = new Sprite(); var TestCanvas:Canvas = testApp.getDisplayObject(); TestCanvas.rawChildren.addChild(container); var cc:ContainerController = new ContainerController(container,100,50); tf.flowComposer.addController(cc); tf.flowComposer.updateAllControllers(); var editmanager:EditManager = new EditManager(); tf.interactionManager = editmanager; editmanager.selectRange(2, 4); tf.flowComposer.addController(new ContainerController(container,200,100)); tf.flowComposer.updateAllControllers(); // Get the bounds of the link in TextLine coordinates var boundsInfo:Object = GeometryUtil.getHighlightBounds(editmanager.getSelectionState())[0]; var bounds:Rectangle = boundsInfo.rect as Rectangle; var textLine:TextLine = boundsInfo.textLine; tf.interactionManager = null; textLine.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_MOVE, true, false, (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine)); tf.interactionManager = editmanager; editmanager.selectRange(0, 0); } public function spanMouseUpEventMirrorTest():void { if (direction == "vertical") { var format:TextLayoutFormat = new TextLayoutFormat(); format.fontFamily = "Arial"; format.fontSize = 16; format.direction = "ltr"; format.blockProgression = "rl"; tf.hostFormat = format; } var p:ParagraphElement = new ParagraphElement(); tf.addChild(p); var span:SpanElement = new SpanElement(); span.text = "Hello world"; span.fontSize = 16; span.getEventMirror().addEventListener(FlowElementMouseEvent.MOUSE_UP, addAsync(checkMouseUpEvent,2500,null),false,0,true); p.addChild(span); var container:Sprite = new Sprite(); var TestCanvas:Canvas = testApp.getDisplayObject(); TestCanvas.rawChildren.addChild(container); var cc:ContainerController = new ContainerController(container,100,50); tf.flowComposer.addController(cc); tf.flowComposer.updateAllControllers(); var editmanager:EditManager = new EditManager(); tf.interactionManager = editmanager; editmanager.selectRange(2, 4); var boundsInfo:Object = GeometryUtil.getHighlightBounds(editmanager.getSelectionState())[0]; var bounds:Rectangle = boundsInfo.rect as Rectangle; var textLine:TextLine = boundsInfo.textLine; tf.interactionManager = null; textLine.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_UP, true, false, (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine)); tf.interactionManager = editmanager; editmanager.selectRange(0, 0); } public function spanRollOverEventMirrorTest():void { if (direction == "vertical") { var format:TextLayoutFormat = new TextLayoutFormat(); format.fontFamily = "Arial"; format.fontSize = 16; format.direction = "ltr"; format.blockProgression = "rl"; tf.hostFormat = format; } var p:ParagraphElement = new ParagraphElement(); tf.addChild(p); var span:SpanElement = new SpanElement(); span.text = "Hello world"; span.fontSize = 16; span.getEventMirror().addEventListener(FlowElementMouseEvent.ROLL_OVER, addAsync(checkMouseRollOverEvent,2500,null),false,0,true); p.addChild(span); var container:Sprite = new Sprite(); var TestCanvas:Canvas = testApp.getDisplayObject(); TestCanvas.rawChildren.addChild(container); var cc:ContainerController = new ContainerController(container,100,50); tf.flowComposer.addController(cc); tf.flowComposer.updateAllControllers(); var editmanager:EditManager = new EditManager(); tf.interactionManager = editmanager; editmanager.selectRange(2, 4); var boundsInfo:Object = GeometryUtil.getHighlightBounds(editmanager.getSelectionState())[0]; var bounds:Rectangle = boundsInfo.rect as Rectangle; var textLine:TextLine = boundsInfo.textLine; tf.interactionManager = null; textLine.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_MOVE, true, false, (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine)); textLine.dispatchEvent(new MouseEvent(MouseEvent.ROLL_OVER, true, false, (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine)); tf.interactionManager = editmanager; editmanager.selectRange(0, 0); } public function spanRollOutEventMirrorTest():void { if (direction == "vertical") { var format:TextLayoutFormat = new TextLayoutFormat(); format.fontFamily = "Arial"; format.fontSize = 16; format.direction = "ltr"; format.blockProgression = "rl"; tf.hostFormat = format; } var p:ParagraphElement = new ParagraphElement(); tf.addChild(p); var span:SpanElement = new SpanElement(); span.text = "Hello world"; span.fontSize = 16; span.getEventMirror().addEventListener(FlowElementMouseEvent.ROLL_OUT, addAsync(checkMouseRollOutEvent,2500,null),false,0,true); p.addChild(span); var container:Sprite = new Sprite(); var TestCanvas:Canvas = testApp.getDisplayObject(); TestCanvas.rawChildren.addChild(container); var cc:ContainerController = new ContainerController(container,100,50); tf.flowComposer.addController(cc); tf.flowComposer.updateAllControllers(); var editmanager:EditManager = new EditManager(); tf.interactionManager = editmanager; editmanager.selectRange(2, 4); var boundsInfo:Object = GeometryUtil.getHighlightBounds(editmanager.getSelectionState())[0]; var bounds:Rectangle = boundsInfo.rect as Rectangle; var textLine:TextLine = boundsInfo.textLine; tf.interactionManager = null; textLine.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_MOVE, true, false, (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine)); textLine.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_OUT, true, false, bounds.right + 1, bounds.bottom + 1, textLine)); textLine.dispatchEvent(new MouseEvent(MouseEvent.ROLL_OUT, true, false, (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine)); tf.interactionManager = editmanager; editmanager.selectRange(0, 0); } public function spanMouseEventMirrorTest():void { if (direction == "vertical") { var format:TextLayoutFormat = new TextLayoutFormat(); format.fontFamily = "Arial"; format.fontSize = 16; format.direction = "ltr"; format.blockProgression = "rl"; tf.hostFormat = format; } var textFlow:TextFlow = new TextFlow(); textFlow.fontSize = 24; var p:ParagraphElement = new ParagraphElement(); textFlow.addChild(p); var span:SpanElement = new SpanElement(); span.text = "Hello world"; span.fontSize = 16; p.addChild(span); var editmanager:EditManager = new EditManager(); textFlow.interactionManager = editmanager; var container:Sprite = new Sprite(); var TestCanvas:Canvas = testApp.getDisplayObject(); TestCanvas.rawChildren.addChild(container); textFlow.flowComposer.addController(new ContainerController(container,200,100)); textFlow.flowComposer.updateAllControllers(); //listen for all FlowElementMouseEvents span.getEventMirror().addEventListener(FlowElementMouseEvent.MOUSE_DOWN,traceEvent); span.getEventMirror().addEventListener(FlowElementMouseEvent.MOUSE_UP,traceEvent); span.getEventMirror().addEventListener(FlowElementMouseEvent.MOUSE_MOVE,traceEvent); span.getEventMirror().addEventListener(FlowElementMouseEvent.ROLL_OVER,traceEvent); span.getEventMirror().addEventListener(FlowElementMouseEvent.ROLL_OUT,traceEvent); span.getEventMirror().addEventListener(FlowElementMouseEvent.CLICK,traceEvent); editmanager.selectRange(2, 4); // Get the bounds of the link in TextLine coordinates var boundsInfo:Object = GeometryUtil.getHighlightBounds(editmanager.getSelectionState())[0]; var bounds:Rectangle = boundsInfo.rect as Rectangle; var textLine:TextLine = boundsInfo.textLine; textFlow.interactionManager = null; //dispatch all mouse events textLine.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_DOWN, true, false, (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine)); textLine.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_UP, true, false, (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine)); textLine.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_MOVE, true, false, (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine)); textLine.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_OUT, true, false, bounds.right + 1, bounds.bottom + 1, textLine)); textLine.dispatchEvent(new MouseEvent(MouseEvent.ROLL_OVER, true, false, (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine)); textLine.dispatchEvent(new MouseEvent(MouseEvent.ROLL_OUT, true, false, (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine)); textLine.dispatchEvent(new MouseEvent(MouseEvent.CLICK, true, false, (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine)); textFlow.interactionManager = editmanager; editmanager.selectRange(0, 0); } private function checkEvent(e:Event):void { assertTrue("mouseClickEvent is not fired when launch a link.", !(e is ErrorEvent)); tf.removeEventListener("customEvent", checkEvent); } public function traceEvent(e:FlowElementMouseEvent):void { assertTrue("mouseEvent not fired correctly", !(e is ErrorEvent)); tf.removeEventListener(FlowElementMouseEvent.MOUSE_DOWN, checkMouseDownEvent); tf.removeEventListener(FlowElementMouseEvent.MOUSE_UP, checkMouseUpEvent); tf.removeEventListener(FlowElementMouseEvent.CLICK, checkMouseClickEvent); tf.removeEventListener(FlowElementMouseEvent.MOUSE_MOVE, checkMouseMoveEvent); tf.removeEventListener(FlowElementMouseEvent.ROLL_OVER, checkMouseRollOverEvent); tf.removeEventListener(FlowElementMouseEvent.ROLL_OUT, checkMouseRollOutEvent); } private function checkMouseDownEvent(e:Event):void { assertTrue("mouseDown event is not fired", !(e is ErrorEvent)); tf.removeEventListener(FlowElementMouseEvent.MOUSE_DOWN, checkMouseDownEvent); } private function checkMouseUpEvent(e:Event):void { assertTrue("mouseUp event is not fired", !(e is ErrorEvent)); tf.removeEventListener(FlowElementMouseEvent.MOUSE_UP, checkMouseUpEvent); } private function checkMouseClickEvent(e:Event):void { assertTrue("mouseClick event is not fired", !(e is ErrorEvent)); tf.removeEventListener(FlowElementMouseEvent.CLICK, checkMouseClickEvent); } private function checkMouseMoveEvent(e:Event):void { assertTrue("mouseMove event is not fired", !(e is ErrorEvent)); tf.removeEventListener(FlowElementMouseEvent.MOUSE_MOVE, checkMouseMoveEvent); } private function checkMouseRollOverEvent(e:Event):void { assertTrue("mouseRollOver event is not fired", !(e is ErrorEvent)); tf.removeEventListener(FlowElementMouseEvent.ROLL_OVER, checkMouseRollOverEvent); } private function checkMouseRollOutEvent(e:Event):void { assertTrue("mouseRollOut event is not fired", !(e is ErrorEvent)); tf.removeEventListener(FlowElementMouseEvent.ROLL_OUT, checkMouseRollOutEvent); } } }