blob: 58694037b2ee383c40c76b5270ee07db6d20201b [file] [log] [blame]
////////////////////////////////////////////////////////////////////////////////
//
// 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 {
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.InteractiveObject;
import flash.text.TextField;
import flash.events.MouseEvent;
import flash.geom.Point;
import mx.core.mx_internal;
use namespace mx_internal;
/**
* The test step that fakes a mouse event
* MXML attributes:
* target
* type
* ctrlKey (optional)
* delta (optional)
* localX
* localY
* relatedObject (optional)
* shiftKey (optional)
* stageX
* stageY
* waitTarget (optional)
* waitEvent (optional)
* timeout (optional);
*/
public class DispatchMouseEvent extends TestStep
{
private static var mouseX:QName = new QName(mx_internal, "_mouseX");
private static var mouseY:QName = new QName(mx_internal, "_mouseY");
/**
* @private
*/
override public function execute(root:DisplayObject, context:UnitTester, testCase:TestCase, testResult:TestResult):Boolean
{
if (waitEvent && waitTarget == null)
waitTarget = target;
return super.execute(root, context, testCase, testResult);
}
/**
* Set the target's property to the specified value
*/
override protected function doStep():void
{
UnitTester.blockFocusEvents = false;
var actualTarget:Object = context.stringToObject(target);
if (!actualTarget)
{
testResult.doFail("Target " + target + " not found");
UnitTester.blockFocusEvents = false;
return;
}
var event:MouseEvent = new MouseEvent(type, true); // all mouse events bubble
event.ctrlKey = ctrlKey;
event.shiftKey = shiftKey;
event.buttonDown = buttonDown || type == "mouseDown";
event.delta = delta;
if (relatedObject && relatedObject.length > 0)
{
event.relatedObject = InteractiveObject(context.stringToObject(relatedObject));
if (!event.relatedObject)
{
testResult.doFail("RelatedObject " + relatedObject + " not found");
UnitTester.blockFocusEvents = false;
return;
}
}
var stagePt:Point;
if (!isNaN(localX) && !isNaN(localY))
{
stagePt = actualTarget.localToGlobal(new Point(localX, localY));
}
else if (!isNaN(stageX) && !isNaN(stageY))
{
stagePt = new Point(stageX, stageY);
}
else
{
stagePt = actualTarget.localToGlobal(new Point(0, 0));
}
try {
root[mouseX] = stagePt.x;
root[mouseY] = stagePt.y;
UnitTester.setMouseXY(stagePt);
if (root["topLevelSystemManager"] != root)
{
root["topLevelSystemManager"][mouseX] = stagePt.x;
root["topLevelSystemManager"][mouseY] = stagePt.y;
}
} catch (e:Error) {}; // some scenarios don't support this
if (actualTarget is DisplayObjectContainer)
{
var targets:Array = actualTarget.stage.getObjectsUnderPoint(stagePt);
var arr:Array = UnitTester.getObjectsUnderPoint(DisplayObject(actualTarget), stagePt);
targets = targets.concat(arr);
for (var i:int = targets.length - 1; i >= 0; i--)
{
if (targets[i] is InteractiveObject)
{
if (targets[i] is TextField && !targets[i].selectable)
{
actualTarget = targets[i].parent;
break;
}
if (isMouseTarget(InteractiveObject(targets[i])))
{
actualTarget = targets[i];
break;
}
}
/* else
{
try
{
actualTarget = targets[i].parent;
while (actualTarget)
{
if (actualTarget is InteractiveObject)
{
if (isMouseTarget(InteractiveObject(actualTarget)))
{
break;
}
}
actualTarget = actualTarget.parent;
}
if (actualTarget && actualTarget != root)
break;
}
catch (e:Error)
{
if (actualTarget)
break;
}
}
*/ }
}
var localPt:Point = actualTarget.globalToLocal(stagePt);
event.localX = localPt.x;
event.localY = localPt.y;
if (actualTarget is TextField)
{
if (type == "mouseDown")
{
var charIndex:int = actualTarget.getCharIndexAtPoint(event.localX, event.localY);
actualTarget.setSelection(charIndex + 1, charIndex + 1);
}
}
try
{
actualTarget.dispatchEvent(event);
}
catch (e2:Error)
{
TestOutput.logResult("Exception thrown in DispatchMouseClickEvent.");
testResult.doFail (e2.getStackTrace());
}
UnitTester.blockFocusEvents = true;
}
/**
* The object that receives the mouse event
*/
public var target:String;
/**
* The type of the event to send (mouseUp, mouseDown, etc).
*/
public var type:String;
/**
* The buttonDown property on the MouseEvent (optional)
*/
public var buttonDown:Boolean;
/**
* The ctrlKey property on the MouseEvent (optional)
*/
public var ctrlKey:Boolean;
/**
* The delta property on the MouseEvent (optional)
*/
public var delta:int;
/**
* The localX property on the MouseEvent (optional)
* Either set stageX/stageY or localX/localY, but not both.
*/
public var localX:Number;
/**
* The localY property on the MouseEvent (optional)
* Either set stageX/stageY or localX/localY, but not both.
*/
public var localY:Number;
/**
* The stageX property on the MouseEvent (optional)
* Either set stageX/stageY or localX/localY, but not both.
*/
public var stageX:Number;
/**
* The stageY property on the MouseEvent (optional)
* Either set stageX/stageY or localX/localY, but not both.
*/
public var stageY:Number;
/**
* The shiftKey property on the MouseEvent (optional)
*/
public var shiftKey:Boolean;
/**
* The relatedObject property on the MouseEvent (optional)
*/
public var relatedObject:String;
private function isMouseTarget(target:InteractiveObject):Boolean
{
if (!target.mouseEnabled)
return false;
// Examine parent chain for "mouseChildren" set to false:
try
{
var parent:DisplayObjectContainer = target.parent;
while (parent)
{
if (!parent.mouseChildren)
return false;
parent = parent.parent;
}
}
catch (e1:Error)
{
}
return true;
}
/**
* customize string representation
*/
override public function toString():String
{
var s:String = "DispatchMouseEvent: target = ";
s += target;
if (type)
s += ", type = " + type;
if (!isNaN(localX))
s += ", localX = " + localX.toString();
if (!isNaN(localY))
s += ", localY = " + localY.toString();
if (!isNaN(stageX))
s += ", stageX = " + stageX.toString();
if (!isNaN(stageY))
s += ", stageY = " + stageY.toString();
if (shiftKey)
s += ", shiftKey = " + shiftKey.toString();
if (ctrlKey)
s += ", ctrlKey = " + ctrlKey.toString();
if (relatedObject)
s += ", relatedObject = " + relatedObject.toString();
if (delta)
s += ", delta = " + delta.toString();
return s;
}
}
}