michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "mozilla/dom/KeyboardEvent.h" michael@0: #include "mozilla/TextEvents.h" michael@0: #include "prtime.h" michael@0: michael@0: namespace mozilla { michael@0: namespace dom { michael@0: michael@0: KeyboardEvent::KeyboardEvent(EventTarget* aOwner, michael@0: nsPresContext* aPresContext, michael@0: WidgetKeyboardEvent* aEvent) michael@0: : UIEvent(aOwner, aPresContext, michael@0: aEvent ? aEvent : new WidgetKeyboardEvent(false, 0, nullptr)) michael@0: , mInitializedByCtor(false) michael@0: , mInitialzedWhichValue(0) michael@0: { michael@0: NS_ASSERTION(mEvent->eventStructType == NS_KEY_EVENT, "event type mismatch"); michael@0: michael@0: if (aEvent) { michael@0: mEventIsInternal = false; michael@0: } michael@0: else { michael@0: mEventIsInternal = true; michael@0: mEvent->time = PR_Now(); michael@0: mEvent->AsKeyboardEvent()->mKeyNameIndex = KEY_NAME_INDEX_USE_STRING; michael@0: } michael@0: } michael@0: michael@0: NS_IMPL_ADDREF_INHERITED(KeyboardEvent, UIEvent) michael@0: NS_IMPL_RELEASE_INHERITED(KeyboardEvent, UIEvent) michael@0: michael@0: NS_INTERFACE_MAP_BEGIN(KeyboardEvent) michael@0: NS_INTERFACE_MAP_ENTRY(nsIDOMKeyEvent) michael@0: NS_INTERFACE_MAP_END_INHERITING(UIEvent) michael@0: michael@0: bool michael@0: KeyboardEvent::AltKey() michael@0: { michael@0: return mEvent->AsKeyboardEvent()->IsAlt(); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: KeyboardEvent::GetAltKey(bool* aIsDown) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aIsDown); michael@0: *aIsDown = AltKey(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: bool michael@0: KeyboardEvent::CtrlKey() michael@0: { michael@0: return mEvent->AsKeyboardEvent()->IsControl(); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: KeyboardEvent::GetCtrlKey(bool* aIsDown) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aIsDown); michael@0: *aIsDown = CtrlKey(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: bool michael@0: KeyboardEvent::ShiftKey() michael@0: { michael@0: return mEvent->AsKeyboardEvent()->IsShift(); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: KeyboardEvent::GetShiftKey(bool* aIsDown) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aIsDown); michael@0: *aIsDown = ShiftKey(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: bool michael@0: KeyboardEvent::MetaKey() michael@0: { michael@0: return mEvent->AsKeyboardEvent()->IsMeta(); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: KeyboardEvent::GetMetaKey(bool* aIsDown) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aIsDown); michael@0: *aIsDown = MetaKey(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: bool michael@0: KeyboardEvent::Repeat() michael@0: { michael@0: return mEvent->AsKeyboardEvent()->mIsRepeat; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: KeyboardEvent::GetRepeat(bool* aIsRepeat) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aIsRepeat); michael@0: *aIsRepeat = Repeat(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: bool michael@0: KeyboardEvent::IsComposing() michael@0: { michael@0: return mEvent->AsKeyboardEvent()->mIsComposing; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: KeyboardEvent::GetModifierState(const nsAString& aKey, michael@0: bool* aState) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aState); michael@0: michael@0: *aState = GetModifierState(aKey); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: KeyboardEvent::GetKey(nsAString& aKeyName) michael@0: { michael@0: mEvent->AsKeyboardEvent()->GetDOMKeyName(aKeyName); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: KeyboardEvent::GetCharCode(uint32_t* aCharCode) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aCharCode); michael@0: *aCharCode = CharCode(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: uint32_t michael@0: KeyboardEvent::CharCode() michael@0: { michael@0: // If this event is initialized with ctor, we shouldn't check event type. michael@0: if (mInitializedByCtor) { michael@0: return mEvent->AsKeyboardEvent()->charCode; michael@0: } michael@0: michael@0: switch (mEvent->message) { michael@0: case NS_KEY_UP: michael@0: case NS_KEY_DOWN: michael@0: return 0; michael@0: case NS_KEY_PRESS: michael@0: return mEvent->AsKeyboardEvent()->charCode; michael@0: } michael@0: return 0; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: KeyboardEvent::GetKeyCode(uint32_t* aKeyCode) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aKeyCode); michael@0: *aKeyCode = KeyCode(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: uint32_t michael@0: KeyboardEvent::KeyCode() michael@0: { michael@0: // If this event is initialized with ctor, we shouldn't check event type. michael@0: if (mInitializedByCtor) { michael@0: return mEvent->AsKeyboardEvent()->keyCode; michael@0: } michael@0: michael@0: switch (mEvent->message) { michael@0: case NS_KEY_UP: michael@0: case NS_KEY_PRESS: michael@0: case NS_KEY_DOWN: michael@0: return mEvent->AsKeyboardEvent()->keyCode; michael@0: } michael@0: return 0; michael@0: } michael@0: michael@0: uint32_t michael@0: KeyboardEvent::Which() michael@0: { michael@0: // If this event is initialized with ctor, which can have independent value. michael@0: if (mInitializedByCtor) { michael@0: return mInitialzedWhichValue; michael@0: } michael@0: michael@0: switch (mEvent->message) { michael@0: case NS_KEY_UP: michael@0: case NS_KEY_DOWN: michael@0: return KeyCode(); michael@0: case NS_KEY_PRESS: michael@0: //Special case for 4xp bug 62878. Try to make value of which michael@0: //more closely mirror the values that 4.x gave for RETURN and BACKSPACE michael@0: { michael@0: uint32_t keyCode = mEvent->AsKeyboardEvent()->keyCode; michael@0: if (keyCode == NS_VK_RETURN || keyCode == NS_VK_BACK) { michael@0: return keyCode; michael@0: } michael@0: return CharCode(); michael@0: } michael@0: } michael@0: michael@0: return 0; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: KeyboardEvent::GetLocation(uint32_t* aLocation) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aLocation); michael@0: michael@0: *aLocation = Location(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: uint32_t michael@0: KeyboardEvent::Location() michael@0: { michael@0: return mEvent->AsKeyboardEvent()->location; michael@0: } michael@0: michael@0: // static michael@0: already_AddRefed michael@0: KeyboardEvent::Constructor(const GlobalObject& aGlobal, michael@0: const nsAString& aType, michael@0: const KeyboardEventInit& aParam, michael@0: ErrorResult& aRv) michael@0: { michael@0: nsCOMPtr target = do_QueryInterface(aGlobal.GetAsSupports()); michael@0: nsRefPtr newEvent = michael@0: new KeyboardEvent(target, nullptr, nullptr); michael@0: bool trusted = newEvent->Init(target); michael@0: aRv = newEvent->InitKeyEvent(aType, aParam.mBubbles, aParam.mCancelable, michael@0: aParam.mView, aParam.mCtrlKey, aParam.mAltKey, michael@0: aParam.mShiftKey, aParam.mMetaKey, michael@0: aParam.mKeyCode, aParam.mCharCode); michael@0: newEvent->SetTrusted(trusted); michael@0: newEvent->mDetail = aParam.mDetail; michael@0: newEvent->mInitializedByCtor = true; michael@0: newEvent->mInitialzedWhichValue = aParam.mWhich; michael@0: michael@0: WidgetKeyboardEvent* internalEvent = newEvent->mEvent->AsKeyboardEvent(); michael@0: internalEvent->location = aParam.mLocation; michael@0: internalEvent->mIsRepeat = aParam.mRepeat; michael@0: internalEvent->mIsComposing = aParam.mIsComposing; michael@0: internalEvent->mKeyNameIndex = KEY_NAME_INDEX_USE_STRING; michael@0: internalEvent->mKeyValue = aParam.mKey; michael@0: michael@0: return newEvent.forget(); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: KeyboardEvent::InitKeyEvent(const nsAString& aType, michael@0: bool aCanBubble, michael@0: bool aCancelable, michael@0: nsIDOMWindow* aView, michael@0: bool aCtrlKey, michael@0: bool aAltKey, michael@0: bool aShiftKey, michael@0: bool aMetaKey, michael@0: uint32_t aKeyCode, michael@0: uint32_t aCharCode) michael@0: { michael@0: nsresult rv = UIEvent::InitUIEvent(aType, aCanBubble, aCancelable, aView, 0); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: WidgetKeyboardEvent* keyEvent = mEvent->AsKeyboardEvent(); michael@0: keyEvent->InitBasicModifiers(aCtrlKey, aAltKey, aShiftKey, aMetaKey); michael@0: keyEvent->keyCode = aKeyCode; michael@0: keyEvent->charCode = aCharCode; michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: } // namespace dom michael@0: } // namespace mozilla michael@0: michael@0: using namespace mozilla; michael@0: using namespace mozilla::dom; michael@0: michael@0: nsresult michael@0: NS_NewDOMKeyboardEvent(nsIDOMEvent** aInstancePtrResult, michael@0: EventTarget* aOwner, michael@0: nsPresContext* aPresContext, michael@0: WidgetKeyboardEvent* aEvent) michael@0: { michael@0: KeyboardEvent* it = new KeyboardEvent(aOwner, aPresContext, aEvent); michael@0: NS_ADDREF(it); michael@0: *aInstancePtrResult = static_cast(it); michael@0: return NS_OK; michael@0: }