Bug 719320 part.9 Implement nsIDOMWindowUtils::sendWheelEvent() for tests r=smaug, sr=jst

This commit is contained in:
Masayuki Nakano 2012-08-12 10:42:36 +09:00
Родитель 19179bc9fe
Коммит 577c0446d5
4 изменённых файлов: 116 добавлений и 93 удалений

Просмотреть файл

@ -583,13 +583,16 @@ nsDOMWindowUtils::SendMouseEventCommon(const nsAString& aType,
}
NS_IMETHODIMP
nsDOMWindowUtils::SendMouseScrollEvent(const nsAString& aType,
float aX,
float aY,
PRInt32 aButton,
PRInt32 aScrollFlags,
PRInt32 aDelta,
PRInt32 aModifiers)
nsDOMWindowUtils::SendWheelEvent(float aX,
float aY,
double aDeltaX,
double aDeltaY,
double aDeltaZ,
PRUint32 aDeltaMode,
PRInt32 aModifiers,
PRInt32 aLineOrPageDeltaX,
PRInt32 aLineOrPageDeltaY,
PRUint32 aOptions)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
@ -598,37 +601,46 @@ nsDOMWindowUtils::SendMouseScrollEvent(const nsAString& aType,
// get the widget to send the event to
nsPoint offset;
nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
if (!widget)
if (!widget) {
return NS_ERROR_NULL_POINTER;
}
PRInt32 msg;
if (aType.EqualsLiteral("DOMMouseScroll"))
msg = NS_MOUSE_SCROLL;
else if (aType.EqualsLiteral("MozMousePixelScroll"))
msg = NS_MOUSE_PIXEL_SCROLL;
else
return NS_ERROR_UNEXPECTED;
widget::WheelEvent wheelEvent(true, NS_WHEEL_WHEEL, widget);
wheelEvent.modifiers = GetWidgetModifiers(aModifiers);
wheelEvent.deltaX = aDeltaX;
wheelEvent.deltaY = aDeltaY;
wheelEvent.deltaZ = aDeltaZ;
wheelEvent.deltaMode = aDeltaMode;
wheelEvent.isMomentum =
(aOptions & WHEEL_EVENT_CAUSED_BY_MOMENTUM) != 0;
wheelEvent.isPixelOnlyDevice =
(aOptions & WHEEL_EVENT_CAUSED_BY_PIXEL_ONLY_DEVICE) != 0;
NS_ENSURE_TRUE(
!wheelEvent.isPixelOnlyDevice ||
aDeltaMode == nsIDOMWheelEvent::DOM_DELTA_PIXEL,
NS_ERROR_INVALID_ARG);
wheelEvent.customizedByUserPrefs =
(aOptions & WHEEL_EVENT_CUSTOMIZED_BY_USER_PREFS) != 0;
wheelEvent.lineOrPageDeltaX = aLineOrPageDeltaX;
wheelEvent.lineOrPageDeltaY = aLineOrPageDeltaY;
wheelEvent.widget = widget;
nsMouseScrollEvent event(true, msg, widget);
event.modifiers = GetWidgetModifiers(aModifiers);
event.button = aButton;
event.widget = widget;
event.delta = aDelta;
event.scrollFlags = aScrollFlags;
event.time = PR_IntervalNow();
wheelEvent.time = PR_Now() / 1000;
nsPresContext* presContext = GetPresContext();
if (!presContext)
return NS_ERROR_FAILURE;
NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
event.refPoint = ToWidgetPoint(aX, aY, offset, presContext);
wheelEvent.refPoint = ToWidgetPoint(aX, aY, offset, presContext);
nsEventStatus status;
return widget->DispatchEvent(&event, status);
nsresult rv = widget->DispatchEvent(&wheelEvent, status);
NS_ENSURE_SUCCESS(rv, rv);
// ESM must not return negative values for overflow.
NS_ENSURE_TRUE(wheelEvent.overflowDeltaX >= 0.0, NS_ERROR_FAILURE);
NS_ENSURE_TRUE(wheelEvent.overflowDeltaY >= 0.0, NS_ERROR_FAILURE);
return rv;
}
NS_IMETHODIMP
nsDOMWindowUtils::SendTouchEvent(const nsAString& aType,
PRUint32 *aIdentifiers,

Просмотреть файл

@ -40,7 +40,7 @@ interface nsIDOMTouch;
interface nsIDOMClientRect;
interface mozIDOMApplication;
[scriptable, uuid(b276a71e-21ee-4be6-894d-4039523e1ad8)]
[scriptable, uuid(97548ee0-9def-421a-ab2a-c6c98efa9a3c)]
interface nsIDOMWindowUtils : nsISupports {
/**
@ -275,10 +275,8 @@ interface nsIDOMWindowUtils : nsISupports {
in long aModifiers,
[optional] in boolean aIgnoreRootScrollFrame);
/** Synthesize a mouse scroll event for a window. The event types supported
* are:
* DOMMouseScroll
* MozMousePixelScroll
/** Synthesize a wheel event for a window. The event types supported is only
* wheel.
*
* Events are sent in coordinates offset by aX and aY from the window.
*
@ -286,22 +284,38 @@ interface nsIDOMWindowUtils : nsISupports {
* Will throw a DOM security error if called without UniversalXPConnect
* privileges.
*
* @param aType event type
* @param aX x offset in CSS pixels
* @param aY y offset in CSS pixels
* @param aButton button to synthesize
* @param aScrollFlags flag bits --- see nsMouseScrollFlags in nsGUIEvent.h
* @param aDelta the direction and amount to scroll (in lines or pixels,
* depending on the event type)
* @param aModifiers modifiers pressed, using constants defined as MODIFIER_*
* @param aX x offset in CSS pixels
* @param aY y offset in CSS pixels
* @param aDeltaX deltaX value.
* @param aDeltaY deltaY value.
* @param aDeltaZ deltaZ value.
* @param aDeltaMode deltaMode value which must be one of
* nsIDOMWheelEvent::DOM_DELTA_*.
* @param aModifiers modifiers pressed, using constants defined as
* MODIFIER_*
* @param aLineOrPageDeltaX If you set this value non-zero for
* DOM_DELTA_PIXEL event, nsEventStateManager will
* dispatch NS_MOUSE_SCROLL event for horizontal
* scroll.
* @param aLineOrPageDeltaY If you set this value non-zero for
* DOM_DELTA_PIXEL event, nsEventStateManager will
* dispatch NS_MOUSE_SCROLL event for vertical
* scroll.
* @param aOptions Set following flags.
*/
void sendMouseScrollEvent(in AString aType,
in float aX,
in float aY,
in long aButton,
in long aScrollFlags,
in long aDelta,
in long aModifiers);
const unsigned long WHEEL_EVENT_CAUSED_BY_PIXEL_ONLY_DEVICE = 0x0001;
const unsigned long WHEEL_EVENT_CAUSED_BY_MOMENTUM = 0x0002;
const unsigned long WHEEL_EVENT_CUSTOMIZED_BY_USER_PREFS = 0x0004;
void sendWheelEvent(in float aX,
in float aY,
in double aDeltaX,
in double aDeltaY,
in double aDeltaZ,
in unsigned long aDeltaMode,
in long aModifiers,
in long aLineOrPageDeltaX,
in long aLineOrPageDeltaY,
in unsigned long aOptions);
/**
* Synthesize a key event to the window. The event types supported are:

Просмотреть файл

@ -7,7 +7,7 @@
* sendKey
* synthesizeMouse
* synthesizeMouseAtCenter
* synthesizeMouseScroll
* synthesizeWheel
* synthesizeKey
* synthesizeMouseExpectEvent
* synthesizeKeyExpectEvent
@ -248,60 +248,57 @@ function synthesizeTouchAtCenter(aTarget, aEvent, aWindow)
synthesizeTouch(aTarget, rect.width / 2, rect.height / 2, aEvent,
aWindow);
}
/**
* Synthesize a mouse scroll event on a target. The actual client point is determined
* Synthesize a wheel event on a target. The actual client point is determined
* by taking the aTarget's client box and offseting it by aOffsetX and
* aOffsetY.
*
* aEvent is an object which may contain the properties:
* shiftKey, ctrlKey, altKey, metaKey, accessKey, button, type, axis, delta, hasPixels
* shiftKey, ctrlKey, altKey, metaKey, accessKey, deltaX, deltaY, deltaZ,
* deltaMode, lineOrPageDeltaX, lineOrPageDeltaY, isMomentum, isPixelOnlyDevice,
* isCustomizedByPrefs
*
* If the type is specified, a mouse scroll event of that type is fired. Otherwise,
* "DOMMouseScroll" is used.
*
* If the axis is specified, it must be one of "horizontal" or "vertical". If not specified,
* "vertical" is used.
*
* 'delta' is the amount to scroll by (can be positive or negative). It must
* be specified.
*
* 'hasPixels' specifies whether kHasPixels should be set in the scrollFlags.
*
* 'isMomentum' specifies whether kIsMomentum should be set in the scrollFlags.
* deltaMode must be defined, others are ok even if undefined.
*
* aWindow is optional, and defaults to the current window object.
*/
function synthesizeMouseScroll(aTarget, aOffsetX, aOffsetY, aEvent, aWindow)
function synthesizeWheel(aTarget, aOffsetX, aOffsetY, aEvent, aWindow)
{
var utils = _getDOMWindowUtils(aWindow);
if (utils) {
// See nsMouseScrollFlags in nsGUIEvent.h
const kIsVertical = 0x02;
const kIsHorizontal = 0x04;
const kHasPixels = 0x08;
const kIsMomentum = 0x40;
var button = aEvent.button || 0;
var modifiers = _parseModifiers(aEvent);
var rect = aTarget.getBoundingClientRect();
var left = rect.left;
var top = rect.top;
var type = (("type" in aEvent) && aEvent.type) || "DOMMouseScroll";
var axis = aEvent.axis || "vertical";
var scrollFlags = (axis == "horizontal") ? kIsHorizontal : kIsVertical;
if (aEvent.hasPixels) {
scrollFlags |= kHasPixels;
}
if (aEvent.isMomentum) {
scrollFlags |= kIsMomentum;
}
utils.sendMouseScrollEvent(type, left + aOffsetX, top + aOffsetY, button,
scrollFlags, aEvent.delta, modifiers);
if (!utils) {
return;
}
var modifiers = _parseModifiers(aEvent);
var options = 0;
if (aEvent.isPixelOnlyDevice &&
(aEvent.deltaMode == WheelEvent.DOM_DELTA_PIXEL)) {
options |= utils.WHEEL_EVENT_CAUSED_BY_PIXEL_ONLY_DEVICE;
}
if (aEvent.isMomentum) {
options |= utils.WHEEL_EVENT_CAUSED_BY_MOMENTUM;
}
if (aEvent.isCustomizedByPrefs) {
options |= utils.WHEEL_EVENT_CUSTOMIZED_BY_USER_PREFS;
}
var isPixelOnlyDevice =
aEvent.isPixelOnlyDevice && aEvent.deltaMode == WheelEvent.DOM_DELTA_PIXEL;
var lineOrPageDeltaX =
aEvent.lineOrPageDeltaX != null ? aEvent.lineOrPageDeltaX :
aEvent.deltaX > 0 ? Math.floor(aEvent.deltaX) :
Math.ceil(aEvent.deltaX);
var lineOrPageDeltaY =
aEvent.lineOrPageDeltaY != null ? aEvent.lineOrPageDeltaY :
aEvent.deltaY > 0 ? Math.floor(aEvent.deltaY) :
Math.ceil(aEvent.deltaY);
var rect = aTarget.getBoundingClientRect();
utils.sendWheelEvent(rect.left + aOffsetX, rect.top + aOffsetY,
aEvent.deltaX ? aEvent.deltaX : 0.0,
aEvent.deltaY ? aEvent.deltaY : 0.0,
aEvent.deltaZ ? aEvent.deltaZ : 0.0,
aEvent.deltaMode, modifiers,
lineOrPageDeltaX, lineOrPageDeltaY, options);
}
function _computeKeyCodeFromChar(aChar)

Просмотреть файл

@ -91,13 +91,13 @@ function starttest() {
$("textBoxA").focus();
/**
* TODO: testing synthesizeMouseScroll requires a setTimeout
* TODO: testing synthesizeWheel requires a setTimeout
* since there is delay between the scroll event and a check, so for now just test
* that we can successfully call it to avoid having setTimeout vary the runtime metric.
* Testing of this method is currently done here:
* toolkit/content/tests/chrome/test_mousescroll.xul
*/
synthesizeMouseScroll($("scrollB"), 5, 5, {'delta': 10, 'type': "DOMMouseScroll"});
synthesizeWheel($("scrollB"), 5, 5, {'deltaY': 10.0, deltaMode: WheelEvent.DOM_DELTA_LINE});
/* test synthesizeKey* */
check = false;