mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-25 11:15:34 +00:00
2df3e475b4
https://github.com/w3c/uievents/issues/112 This is supported by all other UAs. In the past we had compatibility problems when trying to add support, but it seems these might be fixed if we make all arguments optional beyond the first. The interface chosen for the method is from the spec, which has been updated to match Chrome. This is also very similar to WebKit, but the final four arguments are different from IE. MozReview-Commit-ID: 36AeX1JwJTt --HG-- extra : rebase_source : 28b298d370f0f9a5ab4090a71a2aae91f1d90025
382 lines
9.8 KiB
C++
382 lines
9.8 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "mozilla/dom/KeyboardEvent.h"
|
|
#include "mozilla/TextEvents.h"
|
|
#include "prtime.h"
|
|
|
|
namespace mozilla {
|
|
namespace dom {
|
|
|
|
KeyboardEvent::KeyboardEvent(EventTarget* aOwner,
|
|
nsPresContext* aPresContext,
|
|
WidgetKeyboardEvent* aEvent)
|
|
: UIEvent(aOwner, aPresContext,
|
|
aEvent ? aEvent :
|
|
new WidgetKeyboardEvent(false, eVoidEvent, nullptr))
|
|
, mInitializedByCtor(false)
|
|
, mInitializedWhichValue(0)
|
|
{
|
|
if (aEvent) {
|
|
mEventIsInternal = false;
|
|
}
|
|
else {
|
|
mEventIsInternal = true;
|
|
mEvent->mTime = PR_Now();
|
|
mEvent->AsKeyboardEvent()->mKeyNameIndex = KEY_NAME_INDEX_USE_STRING;
|
|
}
|
|
}
|
|
|
|
NS_IMPL_ADDREF_INHERITED(KeyboardEvent, UIEvent)
|
|
NS_IMPL_RELEASE_INHERITED(KeyboardEvent, UIEvent)
|
|
|
|
NS_INTERFACE_MAP_BEGIN(KeyboardEvent)
|
|
NS_INTERFACE_MAP_ENTRY(nsIDOMKeyEvent)
|
|
NS_INTERFACE_MAP_END_INHERITING(UIEvent)
|
|
|
|
bool
|
|
KeyboardEvent::AltKey()
|
|
{
|
|
return mEvent->AsKeyboardEvent()->IsAlt();
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
KeyboardEvent::GetAltKey(bool* aIsDown)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aIsDown);
|
|
*aIsDown = AltKey();
|
|
return NS_OK;
|
|
}
|
|
|
|
bool
|
|
KeyboardEvent::CtrlKey()
|
|
{
|
|
return mEvent->AsKeyboardEvent()->IsControl();
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
KeyboardEvent::GetCtrlKey(bool* aIsDown)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aIsDown);
|
|
*aIsDown = CtrlKey();
|
|
return NS_OK;
|
|
}
|
|
|
|
bool
|
|
KeyboardEvent::ShiftKey()
|
|
{
|
|
return mEvent->AsKeyboardEvent()->IsShift();
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
KeyboardEvent::GetShiftKey(bool* aIsDown)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aIsDown);
|
|
*aIsDown = ShiftKey();
|
|
return NS_OK;
|
|
}
|
|
|
|
bool
|
|
KeyboardEvent::MetaKey()
|
|
{
|
|
return mEvent->AsKeyboardEvent()->IsMeta();
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
KeyboardEvent::GetMetaKey(bool* aIsDown)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aIsDown);
|
|
*aIsDown = MetaKey();
|
|
return NS_OK;
|
|
}
|
|
|
|
bool
|
|
KeyboardEvent::Repeat()
|
|
{
|
|
return mEvent->AsKeyboardEvent()->mIsRepeat;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
KeyboardEvent::GetRepeat(bool* aIsRepeat)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aIsRepeat);
|
|
*aIsRepeat = Repeat();
|
|
return NS_OK;
|
|
}
|
|
|
|
bool
|
|
KeyboardEvent::IsComposing()
|
|
{
|
|
return mEvent->AsKeyboardEvent()->mIsComposing;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
KeyboardEvent::GetModifierState(const nsAString& aKey,
|
|
bool* aState)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aState);
|
|
|
|
*aState = GetModifierState(aKey);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
KeyboardEvent::GetKey(nsAString& aKeyName)
|
|
{
|
|
mEvent->AsKeyboardEvent()->GetDOMKeyName(aKeyName);
|
|
return NS_OK;
|
|
}
|
|
|
|
void
|
|
KeyboardEvent::GetCode(nsAString& aCodeName)
|
|
{
|
|
mEvent->AsKeyboardEvent()->GetDOMCodeName(aCodeName);
|
|
}
|
|
|
|
void KeyboardEvent::GetInitDict(KeyboardEventInit& aParam)
|
|
{
|
|
GetKey(aParam.mKey);
|
|
GetCode(aParam.mCode);
|
|
aParam.mLocation = Location();
|
|
aParam.mRepeat = Repeat();
|
|
aParam.mIsComposing = IsComposing();
|
|
|
|
// legacy attributes
|
|
aParam.mKeyCode = KeyCode();
|
|
aParam.mCharCode = CharCode();
|
|
aParam.mWhich = Which();
|
|
|
|
// modifiers from EventModifierInit
|
|
aParam.mCtrlKey = CtrlKey();
|
|
aParam.mShiftKey = ShiftKey();
|
|
aParam.mAltKey = AltKey();
|
|
aParam.mMetaKey = MetaKey();
|
|
|
|
WidgetKeyboardEvent* internalEvent = mEvent->AsKeyboardEvent();
|
|
aParam.mModifierAltGraph = internalEvent->IsAltGraph();
|
|
aParam.mModifierCapsLock = internalEvent->IsCapsLocked();
|
|
aParam.mModifierFn = internalEvent->IsFn();
|
|
aParam.mModifierFnLock = internalEvent->IsFnLocked();
|
|
aParam.mModifierNumLock = internalEvent->IsNumLocked();
|
|
aParam.mModifierOS = internalEvent->IsOS();
|
|
aParam.mModifierScrollLock = internalEvent->IsScrollLocked();
|
|
aParam.mModifierSymbol = internalEvent->IsSymbol();
|
|
aParam.mModifierSymbolLock = internalEvent->IsSymbolLocked();
|
|
|
|
// EventInit
|
|
aParam.mBubbles = internalEvent->mFlags.mBubbles;
|
|
aParam.mCancelable = internalEvent->mFlags.mCancelable;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
KeyboardEvent::GetCharCode(uint32_t* aCharCode)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aCharCode);
|
|
*aCharCode = CharCode();
|
|
return NS_OK;
|
|
}
|
|
|
|
uint32_t
|
|
KeyboardEvent::CharCode()
|
|
{
|
|
// If this event is initialized with ctor, we shouldn't check event type.
|
|
if (mInitializedByCtor) {
|
|
return mEvent->AsKeyboardEvent()->mCharCode;
|
|
}
|
|
|
|
switch (mEvent->mMessage) {
|
|
case eKeyDown:
|
|
case eKeyDownOnPlugin:
|
|
case eKeyUp:
|
|
case eKeyUpOnPlugin:
|
|
return 0;
|
|
case eKeyPress:
|
|
case eAccessKeyNotFound:
|
|
return mEvent->AsKeyboardEvent()->mCharCode;
|
|
default:
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
KeyboardEvent::GetKeyCode(uint32_t* aKeyCode)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aKeyCode);
|
|
*aKeyCode = KeyCode();
|
|
return NS_OK;
|
|
}
|
|
|
|
uint32_t
|
|
KeyboardEvent::KeyCode()
|
|
{
|
|
// If this event is initialized with ctor, we shouldn't check event type.
|
|
if (mInitializedByCtor) {
|
|
return mEvent->AsKeyboardEvent()->mKeyCode;
|
|
}
|
|
|
|
if (mEvent->HasKeyEventMessage()) {
|
|
return mEvent->AsKeyboardEvent()->mKeyCode;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
uint32_t
|
|
KeyboardEvent::Which()
|
|
{
|
|
// If this event is initialized with ctor, which can have independent value.
|
|
if (mInitializedByCtor) {
|
|
return mInitializedWhichValue;
|
|
}
|
|
|
|
switch (mEvent->mMessage) {
|
|
case eKeyDown:
|
|
case eKeyDownOnPlugin:
|
|
case eKeyUp:
|
|
case eKeyUpOnPlugin:
|
|
return KeyCode();
|
|
case eKeyPress:
|
|
//Special case for 4xp bug 62878. Try to make value of which
|
|
//more closely mirror the values that 4.x gave for RETURN and BACKSPACE
|
|
{
|
|
uint32_t keyCode = mEvent->AsKeyboardEvent()->mKeyCode;
|
|
if (keyCode == NS_VK_RETURN || keyCode == NS_VK_BACK) {
|
|
return keyCode;
|
|
}
|
|
return CharCode();
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
KeyboardEvent::GetLocation(uint32_t* aLocation)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aLocation);
|
|
|
|
*aLocation = Location();
|
|
return NS_OK;
|
|
}
|
|
|
|
uint32_t
|
|
KeyboardEvent::Location()
|
|
{
|
|
return mEvent->AsKeyboardEvent()->mLocation;
|
|
}
|
|
|
|
// static
|
|
already_AddRefed<KeyboardEvent>
|
|
KeyboardEvent::Constructor(const GlobalObject& aGlobal,
|
|
const nsAString& aType,
|
|
const KeyboardEventInit& aParam,
|
|
ErrorResult& aRv)
|
|
{
|
|
nsCOMPtr<EventTarget> target = do_QueryInterface(aGlobal.GetAsSupports());
|
|
RefPtr<KeyboardEvent> newEvent =
|
|
new KeyboardEvent(target, nullptr, nullptr);
|
|
newEvent->InitWithKeyboardEventInit(target, aType, aParam, aRv);
|
|
|
|
return newEvent.forget();
|
|
}
|
|
|
|
void
|
|
KeyboardEvent::InitWithKeyboardEventInit(EventTarget* aOwner,
|
|
const nsAString& aType,
|
|
const KeyboardEventInit& aParam,
|
|
ErrorResult& aRv)
|
|
{
|
|
bool trusted = Init(aOwner);
|
|
InitKeyEvent(aType, aParam.mBubbles, aParam.mCancelable,
|
|
aParam.mView, false, false, false, false,
|
|
aParam.mKeyCode, aParam.mCharCode);
|
|
InitModifiers(aParam);
|
|
SetTrusted(trusted);
|
|
mDetail = aParam.mDetail;
|
|
mInitializedByCtor = true;
|
|
mInitializedWhichValue = aParam.mWhich;
|
|
|
|
WidgetKeyboardEvent* internalEvent = mEvent->AsKeyboardEvent();
|
|
internalEvent->mLocation = aParam.mLocation;
|
|
internalEvent->mIsRepeat = aParam.mRepeat;
|
|
internalEvent->mIsComposing = aParam.mIsComposing;
|
|
internalEvent->mKeyNameIndex =
|
|
WidgetKeyboardEvent::GetKeyNameIndex(aParam.mKey);
|
|
if (internalEvent->mKeyNameIndex == KEY_NAME_INDEX_USE_STRING) {
|
|
internalEvent->mKeyValue = aParam.mKey;
|
|
}
|
|
internalEvent->mCodeNameIndex =
|
|
WidgetKeyboardEvent::GetCodeNameIndex(aParam.mCode);
|
|
if (internalEvent->mCodeNameIndex == CODE_NAME_INDEX_USE_STRING) {
|
|
internalEvent->mCodeValue = aParam.mCode;
|
|
}
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
KeyboardEvent::InitKeyEvent(const nsAString& aType,
|
|
bool aCanBubble,
|
|
bool aCancelable,
|
|
mozIDOMWindow* aView,
|
|
bool aCtrlKey,
|
|
bool aAltKey,
|
|
bool aShiftKey,
|
|
bool aMetaKey,
|
|
uint32_t aKeyCode,
|
|
uint32_t aCharCode)
|
|
{
|
|
NS_ENSURE_TRUE(!mEvent->mFlags.mIsBeingDispatched, NS_OK);
|
|
|
|
UIEvent::InitUIEvent(aType, aCanBubble, aCancelable, aView, 0);
|
|
|
|
WidgetKeyboardEvent* keyEvent = mEvent->AsKeyboardEvent();
|
|
keyEvent->InitBasicModifiers(aCtrlKey, aAltKey, aShiftKey, aMetaKey);
|
|
keyEvent->mKeyCode = aKeyCode;
|
|
keyEvent->mCharCode = aCharCode;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
void
|
|
KeyboardEvent::InitKeyboardEvent(const nsAString& aType,
|
|
bool aCanBubble,
|
|
bool aCancelable,
|
|
nsGlobalWindow* aView,
|
|
const nsAString& aKey,
|
|
uint32_t aLocation,
|
|
bool aCtrlKey,
|
|
bool aAltKey,
|
|
bool aShiftKey,
|
|
bool aMetaKey,
|
|
ErrorResult& aRv)
|
|
{
|
|
NS_ENSURE_TRUE_VOID(!mEvent->mFlags.mIsBeingDispatched);
|
|
|
|
UIEvent::InitUIEvent(aType, aCanBubble, aCancelable, aView, 0);
|
|
|
|
WidgetKeyboardEvent* keyEvent = mEvent->AsKeyboardEvent();
|
|
keyEvent->InitBasicModifiers(aCtrlKey, aAltKey, aShiftKey, aMetaKey);
|
|
keyEvent->mLocation = aLocation;
|
|
keyEvent->mKeyNameIndex = KEY_NAME_INDEX_USE_STRING;
|
|
keyEvent->mKeyValue = aKey;
|
|
}
|
|
|
|
} // namespace dom
|
|
} // namespace mozilla
|
|
|
|
using namespace mozilla;
|
|
using namespace mozilla::dom;
|
|
|
|
already_AddRefed<KeyboardEvent>
|
|
NS_NewDOMKeyboardEvent(EventTarget* aOwner,
|
|
nsPresContext* aPresContext,
|
|
WidgetKeyboardEvent* aEvent)
|
|
{
|
|
RefPtr<KeyboardEvent> it = new KeyboardEvent(aOwner, aPresContext, aEvent);
|
|
return it.forget();
|
|
}
|