Bug 731878 part.1 Implement D3E initMouseEvent() and getModifierState() but they shouldn't be public r=smaug

This commit is contained in:
Masayuki Nakano 2012-04-25 12:00:01 +09:00
parent 7410b4bbd7
commit ef84db57cf
11 changed files with 242 additions and 5 deletions

View File

@ -695,6 +695,7 @@ NS_METHOD nsDOMEvent::DuplicatePrivateData()
mouseEvent->context = oldMouseEvent->context;
mouseEvent->relatedTarget = oldMouseEvent->relatedTarget;
mouseEvent->button = oldMouseEvent->button;
mouseEvent->modifiers = oldMouseEvent->modifiers;
mouseEvent->pressure = oldMouseEvent->pressure;
mouseEvent->inputSource = oldMouseEvent->inputSource;
newEvent = mouseEvent;
@ -712,6 +713,7 @@ NS_METHOD nsDOMEvent::DuplicatePrivateData()
dragEvent->acceptActivation = oldDragEvent->acceptActivation;
dragEvent->relatedTarget = oldDragEvent->relatedTarget;
dragEvent->button = oldDragEvent->button;
dragEvent->modifiers = oldDragEvent->modifiers;
static_cast<nsMouseEvent*>(dragEvent)->inputSource =
static_cast<nsMouseEvent*>(oldDragEvent)->inputSource;
newEvent = dragEvent;
@ -753,6 +755,7 @@ NS_METHOD nsDOMEvent::DuplicatePrivateData()
mouseScrollEvent->delta = oldMouseScrollEvent->delta;
mouseScrollEvent->relatedTarget = oldMouseScrollEvent->relatedTarget;
mouseScrollEvent->button = oldMouseScrollEvent->button;
mouseScrollEvent->modifiers = oldMouseScrollEvent->modifiers;
static_cast<nsMouseEvent_base*>(mouseScrollEvent)->inputSource =
static_cast<nsMouseEvent_base*>(oldMouseScrollEvent)->inputSource;
newEvent = mouseScrollEvent;
@ -863,6 +866,7 @@ NS_METHOD nsDOMEvent::DuplicatePrivateData()
new nsSimpleGestureEvent(false, msg, nsnull, 0, 0.0);
NS_ENSURE_TRUE(simpleGestureEvent, NS_ERROR_OUT_OF_MEMORY);
isInputEvent = true;
simpleGestureEvent->modifiers = oldSimpleGestureEvent->modifiers;
simpleGestureEvent->direction = oldSimpleGestureEvent->direction;
simpleGestureEvent->delta = oldSimpleGestureEvent->delta;
newEvent = simpleGestureEvent;
@ -890,10 +894,14 @@ NS_METHOD nsDOMEvent::DuplicatePrivateData()
}
case NS_MOZTOUCH_EVENT:
{
newEvent = new nsMozTouchEvent(false, msg, nsnull,
static_cast<nsMozTouchEvent*>(mEvent)->streamId);
NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
nsMozTouchEvent* oldMozTouchEvent = static_cast<nsMozTouchEvent*>(mEvent);
nsMozTouchEvent* mozTouchEvent =
new nsMozTouchEvent(false, msg, nsnull,
static_cast<nsMozTouchEvent*>(mEvent)->streamId);
NS_ENSURE_TRUE(mozTouchEvent, NS_ERROR_OUT_OF_MEMORY);
isInputEvent = true;
mozTouchEvent->modifiers = oldMozTouchEvent->modifiers;
newEvent = mozTouchEvent;
break;
}
case NS_TOUCH_EVENT:

View File

@ -43,6 +43,8 @@
#include "nsContentUtils.h"
#include "DictionaryHelpers.h"
using namespace mozilla;
nsDOMMouseEvent::nsDOMMouseEvent(nsPresContext* aPresContext,
nsInputEvent* aEvent)
: nsDOMUIEvent(aPresContext, aEvent ? aEvent :
@ -145,6 +147,45 @@ nsDOMMouseEvent::InitMouseEvent(const nsAString & aType, bool aCanBubble, bool a
return NS_OK;
}
nsresult
nsDOMMouseEvent::InitMouseEvent(const nsAString& aType,
bool aCanBubble,
bool aCancelable,
nsIDOMWindow* aView,
PRInt32 aDetail,
PRInt32 aScreenX,
PRInt32 aScreenY,
PRInt32 aClientX,
PRInt32 aClientY,
PRUint16 aButton,
nsIDOMEventTarget *aRelatedTarget,
const nsAString& aModifiersList)
{
Modifiers modifiers = ComputeModifierState(aModifiersList);
nsresult rv = InitMouseEvent(aType, aCanBubble, aCancelable, aView,
aDetail, aScreenX, aScreenY, aClientX, aClientY,
(modifiers & widget::MODIFIER_CONTROL) != 0,
(modifiers & widget::MODIFIER_ALT) != 0,
(modifiers & widget::MODIFIER_SHIFT) != 0,
(modifiers & widget::MODIFIER_META) != 0,
aButton, aRelatedTarget);
NS_ENSURE_SUCCESS(rv, rv);
switch(mEvent->eventStructType) {
case NS_MOUSE_EVENT:
case NS_MOUSE_SCROLL_EVENT:
case NS_DRAG_EVENT:
case NS_SIMPLE_GESTURE_EVENT:
case NS_MOZTOUCH_EVENT:
static_cast<nsMouseEvent_base*>(mEvent)->modifiers = modifiers;
return NS_OK;
default:
MOZ_NOT_REACHED("There is no space to store the modifiers");
return NS_ERROR_FAILURE;
}
}
nsresult
nsDOMMouseEvent::InitFromCtor(const nsAString& aType,
JSContext* aCx, jsval* aVal)

View File

@ -65,6 +65,19 @@ public:
protected:
// Specific implementation for a mouse event.
virtual nsresult Which(PRUint32* aWhich);
nsresult InitMouseEvent(const nsAString& aType,
bool aCanBubble,
bool aCancelable,
nsIDOMWindow* aView,
PRInt32 aDetail,
PRInt32 aScreenX,
PRInt32 aScreenY,
PRInt32 aClientX,
PRInt32 aClientY,
PRUint16 aButton,
nsIDOMEventTarget *aRelatedTarget,
const nsAString& aModifiersList);
};
#define NS_FORWARD_TO_NSDOMMOUSEEVENT \

View File

@ -51,6 +51,10 @@
#include "nsIFrame.h"
#include "nsIScrollableFrame.h"
#include "DictionaryHelpers.h"
#include "mozilla/Util.h"
#include "mozilla/Assertions.h"
using namespace mozilla;
nsDOMUIEvent::nsDOMUIEvent(nsPresContext* aPresContext, nsGUIEvent* aEvent)
: nsDOMEvent(aPresContext, aEvent ?
@ -447,6 +451,120 @@ nsDOMUIEvent::Deserialize(const IPC::Message* aMsg, void** aIter)
return true;
}
// XXX Following struct and array are used only in
// nsDOMUIEvent::ComputeModifierState(), but if we define them in it,
// we fail to build on Mac at calling mozilla::ArrayLength().
struct nsModifierPair
{
mozilla::widget::Modifier modifier;
const char* name;
};
static const nsModifierPair kPairs[] = {
{ widget::MODIFIER_ALT, NS_DOM_KEYNAME_ALT },
{ widget::MODIFIER_ALTGRAPH, NS_DOM_KEYNAME_ALTGRAPH },
{ widget::MODIFIER_CAPSLOCK, NS_DOM_KEYNAME_CAPSLOCK },
{ widget::MODIFIER_CONTROL, NS_DOM_KEYNAME_CONTROL },
{ widget::MODIFIER_FN, NS_DOM_KEYNAME_FN },
{ widget::MODIFIER_META, NS_DOM_KEYNAME_META },
{ widget::MODIFIER_NUMLOCK, NS_DOM_KEYNAME_NUMLOCK },
{ widget::MODIFIER_SCROLL, NS_DOM_KEYNAME_SCROLL },
{ widget::MODIFIER_SHIFT, NS_DOM_KEYNAME_SHIFT },
{ widget::MODIFIER_SYMBOLLOCK, NS_DOM_KEYNAME_SYMBOLLOCK },
{ widget::MODIFIER_WIN, NS_DOM_KEYNAME_WIN }
};
/* static */
mozilla::widget::Modifiers
nsDOMUIEvent::ComputeModifierState(const nsAString& aModifiersList)
{
if (aModifiersList.IsEmpty()) {
return 0;
}
// Be careful about the performance. If aModifiersList is too long,
// parsing it needs too long time.
// XXX Should we abort if aModifiersList is too long?
Modifiers modifiers = 0;
nsAString::const_iterator listStart, listEnd;
aModifiersList.BeginReading(listStart);
aModifiersList.EndReading(listEnd);
for (PRUint32 i = 0; i < mozilla::ArrayLength(kPairs); i++) {
nsAString::const_iterator start(listStart), end(listEnd);
if (!FindInReadable(NS_ConvertASCIItoUTF16(kPairs[i].name), start, end)) {
continue;
}
if ((start != listStart && !NS_IsAsciiWhitespace(*(--start))) ||
(end != listEnd && !NS_IsAsciiWhitespace(*(end)))) {
continue;
}
modifiers |= kPairs[i].modifier;
}
return modifiers;
}
bool
nsDOMUIEvent::GetModifierStateInternal(const nsAString& aKey)
{
mozilla::widget::Modifiers modifiers = 0;
switch(mEvent->eventStructType) {
case NS_MOUSE_EVENT:
case NS_MOUSE_SCROLL_EVENT:
case NS_DRAG_EVENT:
case NS_SIMPLE_GESTURE_EVENT:
case NS_MOZTOUCH_EVENT:
modifiers = static_cast<nsMouseEvent_base*>(mEvent)->modifiers;
break;
default:
MOZ_NOT_REACHED("There is no space to store the modifiers");
return false;
}
if (aKey.EqualsLiteral(NS_DOM_KEYNAME_SHIFT)) {
return static_cast<nsInputEvent*>(mEvent)->isShift;
}
if (aKey.EqualsLiteral(NS_DOM_KEYNAME_CONTROL)) {
return static_cast<nsInputEvent*>(mEvent)->isControl;
}
if (aKey.EqualsLiteral(NS_DOM_KEYNAME_META)) {
return static_cast<nsInputEvent*>(mEvent)->isMeta;
}
if (aKey.EqualsLiteral(NS_DOM_KEYNAME_ALT)) {
return static_cast<nsInputEvent*>(mEvent)->isAlt;
}
if (aKey.EqualsLiteral(NS_DOM_KEYNAME_ALTGRAPH)) {
return (modifiers & widget::MODIFIER_ALTGRAPH) != 0;
}
if (aKey.EqualsLiteral(NS_DOM_KEYNAME_WIN)) {
return (modifiers & widget::MODIFIER_WIN) != 0;
}
if (aKey.EqualsLiteral(NS_DOM_KEYNAME_CAPSLOCK)) {
return (modifiers & widget::MODIFIER_CAPSLOCK) != 0;
}
if (aKey.EqualsLiteral(NS_DOM_KEYNAME_NUMLOCK)) {
return (modifiers & widget::MODIFIER_NUMLOCK) != 0;
}
if (aKey.EqualsLiteral(NS_DOM_KEYNAME_FN)) {
return (modifiers & widget::MODIFIER_FN) != 0;
}
if (aKey.EqualsLiteral(NS_DOM_KEYNAME_SCROLL)) {
return (modifiers & widget::MODIFIER_SCROLL) != 0;
}
if (aKey.EqualsLiteral(NS_DOM_KEYNAME_SYMBOLLOCK)) {
return (modifiers & widget::MODIFIER_SYMBOLLOCK) != 0;
}
return false;
}
nsresult NS_NewDOMUIEvent(nsIDOMEvent** aInstancePtrResult,
nsPresContext* aPresContext,
nsGUIEvent *aEvent)

View File

@ -42,6 +42,7 @@
#include "nsIDOMUIEvent.h"
#include "nsDOMEvent.h"
#include "nsLayoutUtils.h"
#include "nsEvent.h"
class nsDOMUIEvent : public nsDOMEvent,
public nsIDOMUIEvent
@ -150,6 +151,10 @@ protected:
bool mIsPointerLocked;
nsIntPoint mLastScreenPoint;
nsIntPoint mLastClientPoint;
typedef mozilla::widget::Modifiers Modifiers;
static Modifiers ComputeModifierState(const nsAString& aModifiersList);
bool GetModifierStateInternal(const nsAString& aKey);
};
#define NS_FORWARD_TO_NSDOMUIEVENT \

View File

@ -2008,6 +2008,7 @@ nsEventStateManager::BeginTrackingDragGesture(nsPresContext* aPresContext,
mGestureDownControl = inDownEvent->isControl;
mGestureDownAlt = inDownEvent->isAlt;
mGestureDownMeta = inDownEvent->isMeta;
mGestureModifiers = inDownEvent->modifiers;
if (mClickHoldContextMenu) {
// fire off a timer to track click-hold
@ -2044,6 +2045,7 @@ nsEventStateManager::FillInEventFromGestureDown(nsMouseEvent* aEvent)
aEvent->isControl = mGestureDownControl;
aEvent->isAlt = mGestureDownAlt;
aEvent->isMeta = mGestureDownMeta;
aEvent->modifiers = mGestureModifiers;
}
//
@ -2577,6 +2579,7 @@ nsEventStateManager::SendLineScrollEvent(nsIFrame* aTargetFrame,
event.isControl = aEvent->isControl;
event.isAlt = aEvent->isAlt;
event.isMeta = aEvent->isMeta;
event.modifiers = aEvent->modifiers;
event.scrollFlags = aEvent->scrollFlags;
event.delta = aNumLines;
event.inputSource = static_cast<nsMouseEvent_base*>(aEvent)->inputSource;
@ -2612,6 +2615,7 @@ nsEventStateManager::SendPixelScrollEvent(nsIFrame* aTargetFrame,
event.isControl = aEvent->isControl;
event.isAlt = aEvent->isAlt;
event.isMeta = aEvent->isMeta;
event.modifiers = aEvent->modifiers;
event.scrollFlags = aEvent->scrollFlags;
event.inputSource = static_cast<nsMouseEvent_base*>(aEvent)->inputSource;
event.delta = aPresContext->AppUnitsToIntCSSPixels(aEvent->delta * lineHeight);
@ -3411,6 +3415,7 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
event.isControl = mouseEvent->isControl;
event.isAlt = mouseEvent->isAlt;
event.isMeta = mouseEvent->isMeta;
event.modifiers = mouseEvent->modifiers;
event.inputSource = mouseEvent->inputSource;
nsEventStatus status = nsEventStatus_eIgnore;
@ -3836,6 +3841,7 @@ nsEventStateManager::DispatchMouseEvent(nsGUIEvent* aEvent, PRUint32 aMessage,
event.isControl = ((nsMouseEvent*)aEvent)->isControl;
event.isAlt = ((nsMouseEvent*)aEvent)->isAlt;
event.isMeta = ((nsMouseEvent*)aEvent)->isMeta;
event.modifiers = ((nsMouseEvent*)aEvent)->modifiers;
event.pluginEvent = ((nsMouseEvent*)aEvent)->pluginEvent;
event.relatedTarget = aRelatedContent;
event.inputSource = static_cast<nsMouseEvent*>(aEvent)->inputSource;
@ -4249,6 +4255,7 @@ nsEventStateManager::FireDragEnterOrExit(nsPresContext* aPresContext,
event.isControl = ((nsMouseEvent*)aEvent)->isControl;
event.isAlt = ((nsMouseEvent*)aEvent)->isAlt;
event.isMeta = ((nsMouseEvent*)aEvent)->isMeta;
event.modifiers = ((nsMouseEvent*)aEvent)->modifiers;
event.relatedTarget = aRelatedTarget;
event.inputSource = static_cast<nsMouseEvent*>(aEvent)->inputSource;
@ -4411,6 +4418,7 @@ nsEventStateManager::CheckForAndDispatchClick(nsPresContext* aPresContext,
event.isControl = aEvent->isControl;
event.isAlt = aEvent->isAlt;
event.isMeta = aEvent->isMeta;
event.modifiers = aEvent->modifiers;
event.time = aEvent->time;
event.flags |= flags;
event.button = aEvent->button;
@ -4432,6 +4440,7 @@ nsEventStateManager::CheckForAndDispatchClick(nsPresContext* aPresContext,
event2.isControl = aEvent->isControl;
event2.isAlt = aEvent->isAlt;
event2.isMeta = aEvent->isMeta;
event2.modifiers = aEvent->modifiers;
event2.flags |= flags;
event2.button = aEvent->button;
event2.inputSource = aEvent->inputSource;
@ -5034,6 +5043,7 @@ nsEventStateManager::DoQueryScrollTargetInfo(nsQueryContentEvent* aEvent,
msEvent.isControl = aEvent->mInput.mMouseScrollEvent->isControl;
msEvent.isAlt = aEvent->mInput.mMouseScrollEvent->isAlt;
msEvent.isMeta = aEvent->mInput.mMouseScrollEvent->isMeta;
msEvent.modifiers = aEvent->mInput.mMouseScrollEvent->modifiers;
msEvent.scrollFlags = aEvent->mInput.mMouseScrollEvent->scrollFlags;
msEvent.delta = ComputeWheelDeltaFor(aEvent->mInput.mMouseScrollEvent);

View File

@ -510,6 +510,7 @@ private:
bool mGestureDownControl;
bool mGestureDownAlt;
bool mGestureDownMeta;
mozilla::widget::Modifiers mGestureModifiers;
nsCOMPtr<nsIContent> mLastLeftMouseDownContent;
nsCOMPtr<nsIContent> mLastLeftMouseDownContentParent;

View File

@ -5322,6 +5322,7 @@ PresShell::ProcessSynthMouseMoveEvent(bool aFromScroll)
event.refPoint = refpoint.ToNearestPixels(viewAPD);
event.time = PR_IntervalNow();
// XXX set event.isShift, event.isControl, event.isAlt, event.isMeta ?
// XXX mnakano I think that we should get the latest information from widget.
nsCOMPtr<nsIPresShell> shell = pointVM->GetPresShell();
if (shell) {

View File

@ -114,4 +114,40 @@ class nsAnimationEvent;
class nsUIStateChangeEvent;
class nsPluginEvent;
namespace mozilla {
namespace widget {
// All modifier keys should be defined here. This is used for managing
// modifier states for DOM Level 3 or later.
enum Modifier {
MODIFIER_ALT = 0x0001,
MODIFIER_ALTGRAPH = 0x0002,
MODIFIER_CAPSLOCK = 0x0004,
MODIFIER_CONTROL = 0x0008,
MODIFIER_FN = 0x0010,
MODIFIER_META = 0x0020,
MODIFIER_NUMLOCK = 0x0040,
MODIFIER_SCROLL = 0x0080,
MODIFIER_SHIFT = 0x0100,
MODIFIER_SYMBOLLOCK = 0x0200,
MODIFIER_WIN = 0x0400
};
typedef PRUint16 Modifiers;
} // namespace widget
} // namespace mozilla
#define NS_DOM_KEYNAME_ALT "Alt"
#define NS_DOM_KEYNAME_ALTGRAPH "AltGraph"
#define NS_DOM_KEYNAME_CAPSLOCK "CapsLock"
#define NS_DOM_KEYNAME_CONTROL "Control"
#define NS_DOM_KEYNAME_FN "Fn"
#define NS_DOM_KEYNAME_META "Meta"
#define NS_DOM_KEYNAME_NUMLOCK "NumLock"
#define NS_DOM_KEYNAME_SCROLL "Scroll"
#define NS_DOM_KEYNAME_SHIFT "Shift"
#define NS_DOM_KEYNAME_SYMBOLLOCK "SymbolLock"
#define NS_DOM_KEYNAME_WIN "Win"
#endif // nsEvent_h__

View File

@ -863,14 +863,16 @@ public:
}
nsMouseEvent_base(bool isTrusted, PRUint32 msg, nsIWidget *w, PRUint8 type)
: nsInputEvent(isTrusted, msg, w, type), button(0), pressure(0)
, inputSource(nsIDOMMouseEvent::MOZ_SOURCE_MOUSE) {}
: nsInputEvent(isTrusted, msg, w, type), button(0), modifiers(0),
pressure(0), inputSource(nsIDOMMouseEvent::MOZ_SOURCE_MOUSE) {}
/// The possible related target
nsCOMPtr<nsISupports> relatedTarget;
PRInt16 button;
mozilla::widget::Modifiers modifiers;
// Finger or touch pressure of event
// ranges between 0.0 and 1.0
float pressure;

View File

@ -118,6 +118,7 @@ struct ParamTraits<nsMouseEvent_base>
{
WriteParam(aMsg, static_cast<nsInputEvent>(aParam));
WriteParam(aMsg, aParam.button);
WriteParam(aMsg, aParam.modifiers);
WriteParam(aMsg, aParam.pressure);
WriteParam(aMsg, aParam.inputSource);
}
@ -126,6 +127,7 @@ struct ParamTraits<nsMouseEvent_base>
{
return ReadParam(aMsg, aIter, static_cast<nsInputEvent*>(aResult)) &&
ReadParam(aMsg, aIter, &aResult->button) &&
ReadParam(aMsg, aIter, &aResult->modifiers) &&
ReadParam(aMsg, aIter, &aResult->pressure) &&
ReadParam(aMsg, aIter, &aResult->inputSource);
}