123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107 |
- /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* 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 "gfxPrefs.h"
- #include "mozilla/BasicEvents.h"
- #include "mozilla/ContentEvents.h"
- #include "mozilla/InternalMutationEvent.h"
- #include "mozilla/MiscEvents.h"
- #include "mozilla/MouseEvents.h"
- #include "mozilla/Preferences.h"
- #include "mozilla/TextEvents.h"
- #include "mozilla/TouchEvents.h"
- #include "nsIDOMEventTarget.h"
- #include "nsPrintfCString.h"
- namespace mozilla {
- /******************************************************************************
- * Global helper methods
- ******************************************************************************/
- const char*
- ToChar(EventMessage aEventMessage)
- {
- switch (aEventMessage) {
- #define NS_EVENT_MESSAGE(aMessage) \
- case aMessage: \
- return #aMessage;
- #include "mozilla/EventMessageList.h"
- #undef NS_EVENT_MESSAGE
- default:
- return "illegal event message";
- }
- }
- const char*
- ToChar(EventClassID aEventClassID)
- {
- switch (aEventClassID) {
- #define NS_ROOT_EVENT_CLASS(aPrefix, aName) \
- case eBasic##aName##Class: \
- return "eBasic" #aName "Class";
- #define NS_EVENT_CLASS(aPrefix, aName) \
- case e##aName##Class: \
- return "e" #aName "Class";
- #include "mozilla/EventClassList.h"
- #undef NS_EVENT_CLASS
- #undef NS_ROOT_EVENT_CLASS
- default:
- return "illegal event class ID";
- }
- }
- const nsCString
- ToString(KeyNameIndex aKeyNameIndex)
- {
- if (aKeyNameIndex == KEY_NAME_INDEX_USE_STRING) {
- return NS_LITERAL_CSTRING("USE_STRING");
- }
- nsAutoString keyName;
- WidgetKeyboardEvent::GetDOMKeyName(aKeyNameIndex, keyName);
- return NS_ConvertUTF16toUTF8(keyName);
- }
- const nsCString
- ToString(CodeNameIndex aCodeNameIndex)
- {
- if (aCodeNameIndex == CODE_NAME_INDEX_USE_STRING) {
- return NS_LITERAL_CSTRING("USE_STRING");
- }
- nsAutoString codeName;
- WidgetKeyboardEvent::GetDOMCodeName(aCodeNameIndex, codeName);
- return NS_ConvertUTF16toUTF8(codeName);
- }
- const nsCString
- GetDOMKeyCodeName(uint32_t aKeyCode)
- {
- switch (aKeyCode) {
- #define NS_DISALLOW_SAME_KEYCODE
- #define NS_DEFINE_VK(aDOMKeyName, aDOMKeyCode) \
- case aDOMKeyCode: \
- return NS_LITERAL_CSTRING(#aDOMKeyName);
- #include "mozilla/VirtualKeyCodeList.h"
- #undef NS_DEFINE_VK
- #undef NS_DISALLOW_SAME_KEYCODE
- default:
- return nsPrintfCString("Invalid DOM keyCode (0x%08X)", aKeyCode);
- }
- }
- bool
- IsValidRawTextRangeValue(RawTextRangeType aRawTextRangeType)
- {
- switch (static_cast<TextRangeType>(aRawTextRangeType)) {
- case TextRangeType::eUninitialized:
- case TextRangeType::eCaret:
- case TextRangeType::eRawClause:
- case TextRangeType::eSelectedRawClause:
- case TextRangeType::eConvertedClause:
- case TextRangeType::eSelectedClause:
- return true;
- default:
- return false;
- }
- }
- RawTextRangeType
- ToRawTextRangeType(TextRangeType aTextRangeType)
- {
- return static_cast<RawTextRangeType>(aTextRangeType);
- }
- TextRangeType
- ToTextRangeType(RawTextRangeType aRawTextRangeType)
- {
- MOZ_ASSERT(IsValidRawTextRangeValue(aRawTextRangeType));
- return static_cast<TextRangeType>(aRawTextRangeType);
- }
- const char*
- ToChar(TextRangeType aTextRangeType)
- {
- switch (aTextRangeType) {
- case TextRangeType::eUninitialized:
- return "TextRangeType::eUninitialized";
- case TextRangeType::eCaret:
- return "TextRangeType::eCaret";
- case TextRangeType::eRawClause:
- return "TextRangeType::eRawClause";
- case TextRangeType::eSelectedRawClause:
- return "TextRangeType::eSelectedRawClause";
- case TextRangeType::eConvertedClause:
- return "TextRangeType::eConvertedClause";
- case TextRangeType::eSelectedClause:
- return "TextRangeType::eSelectedClause";
- default:
- return "Invalid TextRangeType";
- }
- }
- SelectionType
- ToSelectionType(TextRangeType aTextRangeType)
- {
- switch (aTextRangeType) {
- case TextRangeType::eRawClause:
- return SelectionType::eIMERawClause;
- case TextRangeType::eSelectedRawClause:
- return SelectionType::eIMESelectedRawClause;
- case TextRangeType::eConvertedClause:
- return SelectionType::eIMEConvertedClause;
- case TextRangeType::eSelectedClause:
- return SelectionType::eIMESelectedClause;
- default:
- MOZ_CRASH("TextRangeType is invalid");
- return SelectionType::eNormal;
- }
- }
- /******************************************************************************
- * As*Event() implementation
- ******************************************************************************/
- #define NS_ROOT_EVENT_CLASS(aPrefix, aName)
- #define NS_EVENT_CLASS(aPrefix, aName) \
- aPrefix##aName* \
- WidgetEvent::As##aName() \
- { \
- return nullptr; \
- } \
- \
- const aPrefix##aName* \
- WidgetEvent::As##aName() const \
- { \
- return const_cast<WidgetEvent*>(this)->As##aName(); \
- }
- #include "mozilla/EventClassList.h"
- #undef NS_EVENT_CLASS
- #undef NS_ROOT_EVENT_CLASS
- /******************************************************************************
- * mozilla::WidgetEvent
- *
- * Event struct type checking methods.
- ******************************************************************************/
- bool
- WidgetEvent::IsQueryContentEvent() const
- {
- return mClass == eQueryContentEventClass;
- }
- bool
- WidgetEvent::IsSelectionEvent() const
- {
- return mClass == eSelectionEventClass;
- }
- bool
- WidgetEvent::IsContentCommandEvent() const
- {
- return mClass == eContentCommandEventClass;
- }
- bool
- WidgetEvent::IsNativeEventDelivererForPlugin() const
- {
- return mClass == ePluginEventClass;
- }
- /******************************************************************************
- * mozilla::WidgetEvent
- *
- * Event message checking methods.
- ******************************************************************************/
- bool
- WidgetEvent::HasMouseEventMessage() const
- {
- switch (mMessage) {
- case eMouseDown:
- case eMouseUp:
- case eMouseClick:
- case eMouseDoubleClick:
- case eMouseAuxClick:
- case eMouseEnterIntoWidget:
- case eMouseExitFromWidget:
- case eMouseActivate:
- case eMouseOver:
- case eMouseOut:
- case eMouseHitTest:
- case eMouseMove:
- return true;
- default:
- return false;
- }
- }
- bool
- WidgetEvent::HasDragEventMessage() const
- {
- switch (mMessage) {
- case eDragEnter:
- case eDragOver:
- case eDragExit:
- case eDrag:
- case eDragEnd:
- case eDragStart:
- case eDrop:
- case eDragLeave:
- return true;
- default:
- return false;
- }
- }
- bool
- WidgetEvent::HasKeyEventMessage() const
- {
- switch (mMessage) {
- case eKeyDown:
- case eKeyPress:
- case eKeyUp:
- case eKeyDownOnPlugin:
- case eKeyUpOnPlugin:
- case eBeforeKeyDown:
- case eBeforeKeyUp:
- case eAfterKeyDown:
- case eAfterKeyUp:
- case eAccessKeyNotFound:
- return true;
- default:
- return false;
- }
- }
- bool
- WidgetEvent::HasIMEEventMessage() const
- {
- switch (mMessage) {
- case eCompositionStart:
- case eCompositionEnd:
- case eCompositionUpdate:
- case eCompositionChange:
- case eCompositionCommitAsIs:
- case eCompositionCommit:
- return true;
- default:
- return false;
- }
- }
- bool
- WidgetEvent::HasPluginActivationEventMessage() const
- {
- return mMessage == ePluginActivate ||
- mMessage == ePluginFocus;
- }
- /******************************************************************************
- * mozilla::WidgetEvent
- *
- * Specific event checking methods.
- ******************************************************************************/
- bool
- WidgetEvent::IsRetargetedNativeEventDelivererForPlugin() const
- {
- const WidgetPluginEvent* pluginEvent = AsPluginEvent();
- return pluginEvent && pluginEvent->mRetargetToFocusedDocument;
- }
- bool
- WidgetEvent::IsNonRetargetedNativeEventDelivererForPlugin() const
- {
- const WidgetPluginEvent* pluginEvent = AsPluginEvent();
- return pluginEvent && !pluginEvent->mRetargetToFocusedDocument;
- }
- bool
- WidgetEvent::IsIMERelatedEvent() const
- {
- return HasIMEEventMessage() || IsQueryContentEvent() || IsSelectionEvent();
- }
- bool
- WidgetEvent::IsUsingCoordinates() const
- {
- const WidgetMouseEvent* mouseEvent = AsMouseEvent();
- if (mouseEvent) {
- return !mouseEvent->IsContextMenuKeyEvent();
- }
- return !HasKeyEventMessage() && !IsIMERelatedEvent() &&
- !HasPluginActivationEventMessage() &&
- !IsNativeEventDelivererForPlugin() &&
- !IsContentCommandEvent();
- }
- bool
- WidgetEvent::IsTargetedAtFocusedWindow() const
- {
- const WidgetMouseEvent* mouseEvent = AsMouseEvent();
- if (mouseEvent) {
- return mouseEvent->IsContextMenuKeyEvent();
- }
- return HasKeyEventMessage() || IsIMERelatedEvent() ||
- IsContentCommandEvent() ||
- IsRetargetedNativeEventDelivererForPlugin();
- }
- bool
- WidgetEvent::IsTargetedAtFocusedContent() const
- {
- const WidgetMouseEvent* mouseEvent = AsMouseEvent();
- if (mouseEvent) {
- return mouseEvent->IsContextMenuKeyEvent();
- }
- return HasKeyEventMessage() || IsIMERelatedEvent() ||
- IsRetargetedNativeEventDelivererForPlugin();
- }
- bool
- WidgetEvent::IsAllowedToDispatchDOMEvent() const
- {
- switch (mClass) {
- case eMouseEventClass:
- if (mMessage == eMouseTouchDrag) {
- return false;
- }
- MOZ_FALLTHROUGH;
- case ePointerEventClass:
- // We want synthesized mouse moves to cause mouseover and mouseout
- // DOM events (EventStateManager::PreHandleEvent), but not mousemove
- // DOM events.
- // Synthesized button up events also do not cause DOM events because they
- // do not have a reliable mRefPoint.
- return AsMouseEvent()->mReason == WidgetMouseEvent::eReal;
- case eWheelEventClass: {
- // wheel event whose all delta values are zero by user pref applied, it
- // shouldn't cause a DOM event.
- const WidgetWheelEvent* wheelEvent = AsWheelEvent();
- return wheelEvent->mDeltaX != 0.0 || wheelEvent->mDeltaY != 0.0 ||
- wheelEvent->mDeltaZ != 0.0;
- }
- // Following events are handled in EventStateManager, so, we don't need to
- // dispatch DOM event for them into the DOM tree.
- case eQueryContentEventClass:
- case eSelectionEventClass:
- case eContentCommandEventClass:
- return false;
- default:
- return true;
- }
- }
- /******************************************************************************
- * mozilla::WidgetEvent
- *
- * Misc methods.
- ******************************************************************************/
- static dom::EventTarget*
- GetTargetForDOMEvent(nsIDOMEventTarget* aTarget)
- {
- return aTarget ? aTarget->GetTargetForDOMEvent() : nullptr;
- }
- dom::EventTarget*
- WidgetEvent::GetDOMEventTarget() const
- {
- return GetTargetForDOMEvent(mTarget);
- }
- dom::EventTarget*
- WidgetEvent::GetCurrentDOMEventTarget() const
- {
- return GetTargetForDOMEvent(mCurrentTarget);
- }
- dom::EventTarget*
- WidgetEvent::GetOriginalDOMEventTarget() const
- {
- if (mOriginalTarget) {
- return GetTargetForDOMEvent(mOriginalTarget);
- }
- return GetDOMEventTarget();
- }
- /******************************************************************************
- * mozilla::WidgetInputEvent
- ******************************************************************************/
- /* static */
- Modifier
- WidgetInputEvent::GetModifier(const nsAString& aDOMKeyName)
- {
- if (aDOMKeyName.EqualsLiteral("Accel")) {
- return AccelModifier();
- }
- KeyNameIndex keyNameIndex = WidgetKeyboardEvent::GetKeyNameIndex(aDOMKeyName);
- return WidgetKeyboardEvent::GetModifierForKeyName(keyNameIndex);
- }
- /* static */
- Modifier
- WidgetInputEvent::AccelModifier()
- {
- static Modifier sAccelModifier = MODIFIER_NONE;
- if (sAccelModifier == MODIFIER_NONE) {
- switch (Preferences::GetInt("ui.key.accelKey", 0)) {
- case nsIDOMKeyEvent::DOM_VK_META:
- sAccelModifier = MODIFIER_META;
- break;
- case nsIDOMKeyEvent::DOM_VK_WIN:
- sAccelModifier = MODIFIER_OS;
- break;
- case nsIDOMKeyEvent::DOM_VK_ALT:
- sAccelModifier = MODIFIER_ALT;
- break;
- case nsIDOMKeyEvent::DOM_VK_CONTROL:
- sAccelModifier = MODIFIER_CONTROL;
- break;
- default:
- sAccelModifier = MODIFIER_CONTROL;
- break;
- }
- }
- return sAccelModifier;
- }
- /******************************************************************************
- * mozilla::WidgetWheelEvent (MouseEvents.h)
- ******************************************************************************/
- /* static */ double
- WidgetWheelEvent::ComputeOverriddenDelta(double aDelta, bool aIsForVertical)
- {
- if (!gfxPrefs::MouseWheelHasRootScrollDeltaOverride()) {
- return aDelta;
- }
- int32_t intFactor = aIsForVertical
- ? gfxPrefs::MouseWheelRootScrollVerticalFactor()
- : gfxPrefs::MouseWheelRootScrollHorizontalFactor();
- // Making the scroll speed slower doesn't make sense. So, ignore odd factor
- // which is less than 1.0.
- if (intFactor <= 100) {
- return aDelta;
- }
- double factor = static_cast<double>(intFactor) / 100;
- return aDelta * factor;
- }
- double
- WidgetWheelEvent::OverriddenDeltaX() const
- {
- if (!mAllowToOverrideSystemScrollSpeed) {
- return mDeltaX;
- }
- return ComputeOverriddenDelta(mDeltaX, false);
- }
- double
- WidgetWheelEvent::OverriddenDeltaY() const
- {
- if (!mAllowToOverrideSystemScrollSpeed) {
- return mDeltaY;
- }
- return ComputeOverriddenDelta(mDeltaY, true);
- }
- /******************************************************************************
- * mozilla::WidgetKeyboardEvent (TextEvents.h)
- ******************************************************************************/
- #define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) (u"" aDOMKeyName),
- const char16_t* const WidgetKeyboardEvent::kKeyNames[] = {
- #include "mozilla/KeyNameList.h"
- };
- #undef NS_DEFINE_KEYNAME
- #define NS_DEFINE_PHYSICAL_KEY_CODE_NAME(aCPPName, aDOMCodeName) \
- (u"" aDOMCodeName),
- const char16_t* const WidgetKeyboardEvent::kCodeNames[] = {
- #include "mozilla/PhysicalKeyCodeNameList.h"
- };
- #undef NS_DEFINE_PHYSICAL_KEY_CODE_NAME
- WidgetKeyboardEvent::KeyNameIndexHashtable*
- WidgetKeyboardEvent::sKeyNameIndexHashtable = nullptr;
- WidgetKeyboardEvent::CodeNameIndexHashtable*
- WidgetKeyboardEvent::sCodeNameIndexHashtable = nullptr;
- bool
- WidgetKeyboardEvent::ShouldCauseKeypressEvents() const
- {
- // Currently, we don't dispatch keypress events of modifier keys and
- // dead keys.
- switch (mKeyNameIndex) {
- case KEY_NAME_INDEX_Alt:
- case KEY_NAME_INDEX_AltGraph:
- case KEY_NAME_INDEX_CapsLock:
- case KEY_NAME_INDEX_Control:
- case KEY_NAME_INDEX_Fn:
- case KEY_NAME_INDEX_FnLock:
- // case KEY_NAME_INDEX_Hyper:
- case KEY_NAME_INDEX_Meta:
- case KEY_NAME_INDEX_NumLock:
- case KEY_NAME_INDEX_OS:
- case KEY_NAME_INDEX_ScrollLock:
- case KEY_NAME_INDEX_Shift:
- // case KEY_NAME_INDEX_Super:
- case KEY_NAME_INDEX_Symbol:
- case KEY_NAME_INDEX_SymbolLock:
- case KEY_NAME_INDEX_Dead:
- return false;
- default:
- return true;
- }
- }
- static bool
- HasASCIIDigit(const ShortcutKeyCandidateArray& aCandidates)
- {
- for (uint32_t i = 0; i < aCandidates.Length(); ++i) {
- uint32_t ch = aCandidates[i].mCharCode;
- if (ch >= '0' && ch <= '9')
- return true;
- }
- return false;
- }
- static bool
- CharsCaseInsensitiveEqual(uint32_t aChar1, uint32_t aChar2)
- {
- return aChar1 == aChar2 ||
- (IS_IN_BMP(aChar1) && IS_IN_BMP(aChar2) &&
- ToLowerCase(static_cast<char16_t>(aChar1)) ==
- ToLowerCase(static_cast<char16_t>(aChar2)));
- }
- static bool
- IsCaseChangeableChar(uint32_t aChar)
- {
- return IS_IN_BMP(aChar) &&
- ToLowerCase(static_cast<char16_t>(aChar)) !=
- ToUpperCase(static_cast<char16_t>(aChar));
- }
- void
- WidgetKeyboardEvent::GetShortcutKeyCandidates(
- ShortcutKeyCandidateArray& aCandidates)
- {
- MOZ_ASSERT(aCandidates.IsEmpty(), "aCandidates must be empty");
- // ShortcutKeyCandidate::mCharCode is a candidate charCode.
- // ShortcutKeyCandidate::mIgnoreShift means the mCharCode should be tried to
- // execute a command with/without shift key state. If this is TRUE, the
- // shifted key state should be ignored. Otherwise, don't ignore the state.
- // the priority of the charCodes are (shift key is not pressed):
- // 0: PseudoCharCode()/false,
- // 1: unshiftedCharCodes[0]/false, 2: unshiftedCharCodes[1]/false...
- // the priority of the charCodes are (shift key is pressed):
- // 0: PseudoCharCode()/false,
- // 1: shiftedCharCodes[0]/false, 2: shiftedCharCodes[0]/true,
- // 3: shiftedCharCodes[1]/false, 4: shiftedCharCodes[1]/true...
- uint32_t pseudoCharCode = PseudoCharCode();
- if (pseudoCharCode) {
- ShortcutKeyCandidate key(pseudoCharCode, false);
- aCandidates.AppendElement(key);
- }
- uint32_t len = mAlternativeCharCodes.Length();
- if (!IsShift()) {
- for (uint32_t i = 0; i < len; ++i) {
- uint32_t ch = mAlternativeCharCodes[i].mUnshiftedCharCode;
- if (!ch || ch == pseudoCharCode) {
- continue;
- }
- ShortcutKeyCandidate key(ch, false);
- aCandidates.AppendElement(key);
- }
- // If unshiftedCharCodes doesn't have numeric but shiftedCharCode has it,
- // this keyboard layout is AZERTY or similar layout, probably.
- // In this case, Accel+[0-9] should be accessible without shift key.
- // However, the priority should be lowest.
- if (!HasASCIIDigit(aCandidates)) {
- for (uint32_t i = 0; i < len; ++i) {
- uint32_t ch = mAlternativeCharCodes[i].mShiftedCharCode;
- if (ch >= '0' && ch <= '9') {
- ShortcutKeyCandidate key(ch, false);
- aCandidates.AppendElement(key);
- break;
- }
- }
- }
- } else {
- for (uint32_t i = 0; i < len; ++i) {
- uint32_t ch = mAlternativeCharCodes[i].mShiftedCharCode;
- if (!ch) {
- continue;
- }
- if (ch != pseudoCharCode) {
- ShortcutKeyCandidate key(ch, false);
- aCandidates.AppendElement(key);
- }
- // If the char is an alphabet, the shift key state should not be
- // ignored. E.g., Ctrl+Shift+C should not execute Ctrl+C.
- // And checking the charCode is same as unshiftedCharCode too.
- // E.g., for Ctrl+Shift+(Plus of Numpad) should not run Ctrl+Plus.
- uint32_t unshiftCh = mAlternativeCharCodes[i].mUnshiftedCharCode;
- if (CharsCaseInsensitiveEqual(ch, unshiftCh)) {
- continue;
- }
- // On the Hebrew keyboard layout on Windows, the unshifted char is a
- // localized character but the shifted char is a Latin alphabet,
- // then, we should not execute without the shift state. See bug 433192.
- if (IsCaseChangeableChar(ch)) {
- continue;
- }
- // Setting the alternative charCode candidates for retry without shift
- // key state only when the shift key is pressed.
- ShortcutKeyCandidate key(ch, true);
- aCandidates.AppendElement(key);
- }
- }
- // Special case for "Space" key. With some keyboard layouts, "Space" with
- // or without Shift key causes non-ASCII space. For such keyboard layouts,
- // we should guarantee that the key press works as an ASCII white space key
- // press. However, if the space key is assigned to a function key, it
- // shouldn't work as a space key.
- if (mKeyNameIndex == KEY_NAME_INDEX_USE_STRING &&
- mCodeNameIndex == CODE_NAME_INDEX_Space && pseudoCharCode != ' ') {
- ShortcutKeyCandidate spaceKey(' ', false);
- aCandidates.AppendElement(spaceKey);
- }
- }
- void
- WidgetKeyboardEvent::GetAccessKeyCandidates(nsTArray<uint32_t>& aCandidates)
- {
- MOZ_ASSERT(aCandidates.IsEmpty(), "aCandidates must be empty");
- // return the lower cased charCode candidates for access keys.
- // the priority of the charCodes are:
- // 0: charCode, 1: unshiftedCharCodes[0], 2: shiftedCharCodes[0]
- // 3: unshiftedCharCodes[1], 4: shiftedCharCodes[1],...
- if (mCharCode) {
- uint32_t ch = mCharCode;
- if (IS_IN_BMP(ch)) {
- ch = ToLowerCase(static_cast<char16_t>(ch));
- }
- aCandidates.AppendElement(ch);
- }
- for (uint32_t i = 0; i < mAlternativeCharCodes.Length(); ++i) {
- uint32_t ch[2] =
- { mAlternativeCharCodes[i].mUnshiftedCharCode,
- mAlternativeCharCodes[i].mShiftedCharCode };
- for (uint32_t j = 0; j < 2; ++j) {
- if (!ch[j]) {
- continue;
- }
- if (IS_IN_BMP(ch[j])) {
- ch[j] = ToLowerCase(static_cast<char16_t>(ch[j]));
- }
- // Don't append the mCharCode that was already appended.
- if (aCandidates.IndexOf(ch[j]) == aCandidates.NoIndex) {
- aCandidates.AppendElement(ch[j]);
- }
- }
- }
- // Special case for "Space" key. With some keyboard layouts, "Space" with
- // or without Shift key causes non-ASCII space. For such keyboard layouts,
- // we should guarantee that the key press works as an ASCII white space key
- // press. However, if the space key is assigned to a function key, it
- // shouldn't work as a space key.
- if (mKeyNameIndex == KEY_NAME_INDEX_USE_STRING &&
- mCodeNameIndex == CODE_NAME_INDEX_Space && mCharCode != ' ') {
- aCandidates.AppendElement(' ');
- }
- return;
- }
- /* static */ void
- WidgetKeyboardEvent::Shutdown()
- {
- delete sKeyNameIndexHashtable;
- sKeyNameIndexHashtable = nullptr;
- delete sCodeNameIndexHashtable;
- sCodeNameIndexHashtable = nullptr;
- }
- /* static */ void
- WidgetKeyboardEvent::GetDOMKeyName(KeyNameIndex aKeyNameIndex,
- nsAString& aKeyName)
- {
- if (aKeyNameIndex >= KEY_NAME_INDEX_USE_STRING) {
- aKeyName.Truncate();
- return;
- }
- MOZ_RELEASE_ASSERT(static_cast<size_t>(aKeyNameIndex) <
- ArrayLength(kKeyNames),
- "Illegal key enumeration value");
- aKeyName = kKeyNames[aKeyNameIndex];
- }
- /* static */ void
- WidgetKeyboardEvent::GetDOMCodeName(CodeNameIndex aCodeNameIndex,
- nsAString& aCodeName)
- {
- if (aCodeNameIndex >= CODE_NAME_INDEX_USE_STRING) {
- aCodeName.Truncate();
- return;
- }
- MOZ_RELEASE_ASSERT(static_cast<size_t>(aCodeNameIndex) <
- ArrayLength(kCodeNames),
- "Illegal physical code enumeration value");
- aCodeName = kCodeNames[aCodeNameIndex];
- }
- /* static */ KeyNameIndex
- WidgetKeyboardEvent::GetKeyNameIndex(const nsAString& aKeyValue)
- {
- if (!sKeyNameIndexHashtable) {
- sKeyNameIndexHashtable =
- new KeyNameIndexHashtable(ArrayLength(kKeyNames));
- for (size_t i = 0; i < ArrayLength(kKeyNames); i++) {
- sKeyNameIndexHashtable->Put(nsDependentString(kKeyNames[i]),
- static_cast<KeyNameIndex>(i));
- }
- }
- KeyNameIndex result = KEY_NAME_INDEX_USE_STRING;
- sKeyNameIndexHashtable->Get(aKeyValue, &result);
- return result;
- }
- /* static */ CodeNameIndex
- WidgetKeyboardEvent::GetCodeNameIndex(const nsAString& aCodeValue)
- {
- if (!sCodeNameIndexHashtable) {
- sCodeNameIndexHashtable =
- new CodeNameIndexHashtable(ArrayLength(kCodeNames));
- for (size_t i = 0; i < ArrayLength(kCodeNames); i++) {
- sCodeNameIndexHashtable->Put(nsDependentString(kCodeNames[i]),
- static_cast<CodeNameIndex>(i));
- }
- }
- CodeNameIndex result = CODE_NAME_INDEX_USE_STRING;
- sCodeNameIndexHashtable->Get(aCodeValue, &result);
- return result;
- }
- /* static */ const char*
- WidgetKeyboardEvent::GetCommandStr(Command aCommand)
- {
- #define NS_DEFINE_COMMAND(aName, aCommandStr) , #aCommandStr
- static const char* const kCommands[] = {
- "" // CommandDoNothing
- #include "mozilla/CommandList.h"
- };
- #undef NS_DEFINE_COMMAND
- MOZ_RELEASE_ASSERT(static_cast<size_t>(aCommand) < ArrayLength(kCommands),
- "Illegal command enumeration value");
- return kCommands[aCommand];
- }
- /* static */ uint32_t
- WidgetKeyboardEvent::ComputeLocationFromCodeValue(CodeNameIndex aCodeNameIndex)
- {
- // Following commented out cases are not defined in PhysicalKeyCodeNameList.h
- // but are defined by D3E spec. So, they should be uncommented when the
- // code values are defined in the header.
- switch (aCodeNameIndex) {
- case CODE_NAME_INDEX_AltLeft:
- case CODE_NAME_INDEX_ControlLeft:
- case CODE_NAME_INDEX_OSLeft:
- case CODE_NAME_INDEX_ShiftLeft:
- return nsIDOMKeyEvent::DOM_KEY_LOCATION_LEFT;
- case CODE_NAME_INDEX_AltRight:
- case CODE_NAME_INDEX_ControlRight:
- case CODE_NAME_INDEX_OSRight:
- case CODE_NAME_INDEX_ShiftRight:
- return nsIDOMKeyEvent::DOM_KEY_LOCATION_RIGHT;
- case CODE_NAME_INDEX_Numpad0:
- case CODE_NAME_INDEX_Numpad1:
- case CODE_NAME_INDEX_Numpad2:
- case CODE_NAME_INDEX_Numpad3:
- case CODE_NAME_INDEX_Numpad4:
- case CODE_NAME_INDEX_Numpad5:
- case CODE_NAME_INDEX_Numpad6:
- case CODE_NAME_INDEX_Numpad7:
- case CODE_NAME_INDEX_Numpad8:
- case CODE_NAME_INDEX_Numpad9:
- case CODE_NAME_INDEX_NumpadAdd:
- case CODE_NAME_INDEX_NumpadBackspace:
- case CODE_NAME_INDEX_NumpadClear:
- case CODE_NAME_INDEX_NumpadClearEntry:
- case CODE_NAME_INDEX_NumpadComma:
- case CODE_NAME_INDEX_NumpadDecimal:
- case CODE_NAME_INDEX_NumpadDivide:
- case CODE_NAME_INDEX_NumpadEnter:
- case CODE_NAME_INDEX_NumpadEqual:
- case CODE_NAME_INDEX_NumpadMemoryAdd:
- case CODE_NAME_INDEX_NumpadMemoryClear:
- case CODE_NAME_INDEX_NumpadMemoryRecall:
- case CODE_NAME_INDEX_NumpadMemoryStore:
- case CODE_NAME_INDEX_NumpadMemorySubtract:
- case CODE_NAME_INDEX_NumpadMultiply:
- case CODE_NAME_INDEX_NumpadParenLeft:
- case CODE_NAME_INDEX_NumpadParenRight:
- case CODE_NAME_INDEX_NumpadSubtract:
- return nsIDOMKeyEvent::DOM_KEY_LOCATION_NUMPAD;
- default:
- return nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD;
- }
- }
- /* static */ uint32_t
- WidgetKeyboardEvent::ComputeKeyCodeFromKeyNameIndex(KeyNameIndex aKeyNameIndex)
- {
- switch (aKeyNameIndex) {
- case KEY_NAME_INDEX_Cancel:
- return nsIDOMKeyEvent::DOM_VK_CANCEL;
- case KEY_NAME_INDEX_Help:
- return nsIDOMKeyEvent::DOM_VK_HELP;
- case KEY_NAME_INDEX_Backspace:
- return nsIDOMKeyEvent::DOM_VK_BACK_SPACE;
- case KEY_NAME_INDEX_Tab:
- return nsIDOMKeyEvent::DOM_VK_TAB;
- case KEY_NAME_INDEX_Clear:
- return nsIDOMKeyEvent::DOM_VK_CLEAR;
- case KEY_NAME_INDEX_Enter:
- return nsIDOMKeyEvent::DOM_VK_RETURN;
- case KEY_NAME_INDEX_Shift:
- return nsIDOMKeyEvent::DOM_VK_SHIFT;
- case KEY_NAME_INDEX_Control:
- return nsIDOMKeyEvent::DOM_VK_CONTROL;
- case KEY_NAME_INDEX_Alt:
- return nsIDOMKeyEvent::DOM_VK_ALT;
- case KEY_NAME_INDEX_Pause:
- return nsIDOMKeyEvent::DOM_VK_PAUSE;
- case KEY_NAME_INDEX_CapsLock:
- return nsIDOMKeyEvent::DOM_VK_CAPS_LOCK;
- case KEY_NAME_INDEX_Hiragana:
- case KEY_NAME_INDEX_Katakana:
- case KEY_NAME_INDEX_HiraganaKatakana:
- case KEY_NAME_INDEX_KanaMode:
- return nsIDOMKeyEvent::DOM_VK_KANA;
- case KEY_NAME_INDEX_HangulMode:
- return nsIDOMKeyEvent::DOM_VK_HANGUL;
- case KEY_NAME_INDEX_Eisu:
- return nsIDOMKeyEvent::DOM_VK_EISU;
- case KEY_NAME_INDEX_JunjaMode:
- return nsIDOMKeyEvent::DOM_VK_JUNJA;
- case KEY_NAME_INDEX_FinalMode:
- return nsIDOMKeyEvent::DOM_VK_FINAL;
- case KEY_NAME_INDEX_HanjaMode:
- return nsIDOMKeyEvent::DOM_VK_HANJA;
- case KEY_NAME_INDEX_KanjiMode:
- return nsIDOMKeyEvent::DOM_VK_KANJI;
- case KEY_NAME_INDEX_Escape:
- return nsIDOMKeyEvent::DOM_VK_ESCAPE;
- case KEY_NAME_INDEX_Convert:
- return nsIDOMKeyEvent::DOM_VK_CONVERT;
- case KEY_NAME_INDEX_NonConvert:
- return nsIDOMKeyEvent::DOM_VK_NONCONVERT;
- case KEY_NAME_INDEX_Accept:
- return nsIDOMKeyEvent::DOM_VK_ACCEPT;
- case KEY_NAME_INDEX_ModeChange:
- return nsIDOMKeyEvent::DOM_VK_MODECHANGE;
- case KEY_NAME_INDEX_PageUp:
- return nsIDOMKeyEvent::DOM_VK_PAGE_UP;
- case KEY_NAME_INDEX_PageDown:
- return nsIDOMKeyEvent::DOM_VK_PAGE_DOWN;
- case KEY_NAME_INDEX_End:
- return nsIDOMKeyEvent::DOM_VK_END;
- case KEY_NAME_INDEX_Home:
- return nsIDOMKeyEvent::DOM_VK_HOME;
- case KEY_NAME_INDEX_ArrowLeft:
- return nsIDOMKeyEvent::DOM_VK_LEFT;
- case KEY_NAME_INDEX_ArrowUp:
- return nsIDOMKeyEvent::DOM_VK_UP;
- case KEY_NAME_INDEX_ArrowRight:
- return nsIDOMKeyEvent::DOM_VK_RIGHT;
- case KEY_NAME_INDEX_ArrowDown:
- return nsIDOMKeyEvent::DOM_VK_DOWN;
- case KEY_NAME_INDEX_Select:
- return nsIDOMKeyEvent::DOM_VK_SELECT;
- case KEY_NAME_INDEX_Print:
- return nsIDOMKeyEvent::DOM_VK_PRINT;
- case KEY_NAME_INDEX_Execute:
- return nsIDOMKeyEvent::DOM_VK_EXECUTE;
- case KEY_NAME_INDEX_PrintScreen:
- return nsIDOMKeyEvent::DOM_VK_PRINTSCREEN;
- case KEY_NAME_INDEX_Insert:
- return nsIDOMKeyEvent::DOM_VK_INSERT;
- case KEY_NAME_INDEX_Delete:
- return nsIDOMKeyEvent::DOM_VK_DELETE;
- case KEY_NAME_INDEX_OS:
- // case KEY_NAME_INDEX_Super:
- // case KEY_NAME_INDEX_Hyper:
- return nsIDOMKeyEvent::DOM_VK_WIN;
- case KEY_NAME_INDEX_ContextMenu:
- return nsIDOMKeyEvent::DOM_VK_CONTEXT_MENU;
- case KEY_NAME_INDEX_Standby:
- return nsIDOMKeyEvent::DOM_VK_SLEEP;
- case KEY_NAME_INDEX_F1:
- return nsIDOMKeyEvent::DOM_VK_F1;
- case KEY_NAME_INDEX_F2:
- return nsIDOMKeyEvent::DOM_VK_F2;
- case KEY_NAME_INDEX_F3:
- return nsIDOMKeyEvent::DOM_VK_F3;
- case KEY_NAME_INDEX_F4:
- return nsIDOMKeyEvent::DOM_VK_F4;
- case KEY_NAME_INDEX_F5:
- return nsIDOMKeyEvent::DOM_VK_F5;
- case KEY_NAME_INDEX_F6:
- return nsIDOMKeyEvent::DOM_VK_F6;
- case KEY_NAME_INDEX_F7:
- return nsIDOMKeyEvent::DOM_VK_F7;
- case KEY_NAME_INDEX_F8:
- return nsIDOMKeyEvent::DOM_VK_F8;
- case KEY_NAME_INDEX_F9:
- return nsIDOMKeyEvent::DOM_VK_F9;
- case KEY_NAME_INDEX_F10:
- return nsIDOMKeyEvent::DOM_VK_F10;
- case KEY_NAME_INDEX_F11:
- return nsIDOMKeyEvent::DOM_VK_F11;
- case KEY_NAME_INDEX_F12:
- return nsIDOMKeyEvent::DOM_VK_F12;
- case KEY_NAME_INDEX_F13:
- return nsIDOMKeyEvent::DOM_VK_F13;
- case KEY_NAME_INDEX_F14:
- return nsIDOMKeyEvent::DOM_VK_F14;
- case KEY_NAME_INDEX_F15:
- return nsIDOMKeyEvent::DOM_VK_F15;
- case KEY_NAME_INDEX_F16:
- return nsIDOMKeyEvent::DOM_VK_F16;
- case KEY_NAME_INDEX_F17:
- return nsIDOMKeyEvent::DOM_VK_F17;
- case KEY_NAME_INDEX_F18:
- return nsIDOMKeyEvent::DOM_VK_F18;
- case KEY_NAME_INDEX_F19:
- return nsIDOMKeyEvent::DOM_VK_F19;
- case KEY_NAME_INDEX_F20:
- return nsIDOMKeyEvent::DOM_VK_F20;
- case KEY_NAME_INDEX_F21:
- return nsIDOMKeyEvent::DOM_VK_F21;
- case KEY_NAME_INDEX_F22:
- return nsIDOMKeyEvent::DOM_VK_F22;
- case KEY_NAME_INDEX_F23:
- return nsIDOMKeyEvent::DOM_VK_F23;
- case KEY_NAME_INDEX_F24:
- return nsIDOMKeyEvent::DOM_VK_F24;
- case KEY_NAME_INDEX_NumLock:
- return nsIDOMKeyEvent::DOM_VK_NUM_LOCK;
- case KEY_NAME_INDEX_ScrollLock:
- return nsIDOMKeyEvent::DOM_VK_SCROLL_LOCK;
- case KEY_NAME_INDEX_AudioVolumeMute:
- return nsIDOMKeyEvent::DOM_VK_VOLUME_MUTE;
- case KEY_NAME_INDEX_AudioVolumeDown:
- return nsIDOMKeyEvent::DOM_VK_VOLUME_DOWN;
- case KEY_NAME_INDEX_AudioVolumeUp:
- return nsIDOMKeyEvent::DOM_VK_VOLUME_UP;
- case KEY_NAME_INDEX_Meta:
- return nsIDOMKeyEvent::DOM_VK_META;
- case KEY_NAME_INDEX_AltGraph:
- return nsIDOMKeyEvent::DOM_VK_ALTGR;
- case KEY_NAME_INDEX_Attn:
- return nsIDOMKeyEvent::DOM_VK_ATTN;
- case KEY_NAME_INDEX_CrSel:
- return nsIDOMKeyEvent::DOM_VK_CRSEL;
- case KEY_NAME_INDEX_ExSel:
- return nsIDOMKeyEvent::DOM_VK_EXSEL;
- case KEY_NAME_INDEX_EraseEof:
- return nsIDOMKeyEvent::DOM_VK_EREOF;
- case KEY_NAME_INDEX_Play:
- return nsIDOMKeyEvent::DOM_VK_PLAY;
- case KEY_NAME_INDEX_ZoomToggle:
- case KEY_NAME_INDEX_ZoomIn:
- case KEY_NAME_INDEX_ZoomOut:
- return nsIDOMKeyEvent::DOM_VK_ZOOM;
- default:
- return 0;
- }
- }
- /* static */ Modifier
- WidgetKeyboardEvent::GetModifierForKeyName(KeyNameIndex aKeyNameIndex)
- {
- switch (aKeyNameIndex) {
- case KEY_NAME_INDEX_Alt:
- return MODIFIER_ALT;
- case KEY_NAME_INDEX_AltGraph:
- return MODIFIER_ALTGRAPH;
- case KEY_NAME_INDEX_CapsLock:
- return MODIFIER_CAPSLOCK;
- case KEY_NAME_INDEX_Control:
- return MODIFIER_CONTROL;
- case KEY_NAME_INDEX_Fn:
- return MODIFIER_FN;
- case KEY_NAME_INDEX_FnLock:
- return MODIFIER_FNLOCK;
- // case KEY_NAME_INDEX_Hyper:
- case KEY_NAME_INDEX_Meta:
- return MODIFIER_META;
- case KEY_NAME_INDEX_NumLock:
- return MODIFIER_NUMLOCK;
- case KEY_NAME_INDEX_OS:
- return MODIFIER_OS;
- case KEY_NAME_INDEX_ScrollLock:
- return MODIFIER_SCROLLLOCK;
- case KEY_NAME_INDEX_Shift:
- return MODIFIER_SHIFT;
- // case KEY_NAME_INDEX_Super:
- case KEY_NAME_INDEX_Symbol:
- return MODIFIER_SYMBOL;
- case KEY_NAME_INDEX_SymbolLock:
- return MODIFIER_SYMBOLLOCK;
- default:
- return MODIFIER_NONE;
- }
- }
- /* static */ bool
- WidgetKeyboardEvent::IsLockableModifier(KeyNameIndex aKeyNameIndex)
- {
- switch (aKeyNameIndex) {
- case KEY_NAME_INDEX_CapsLock:
- case KEY_NAME_INDEX_FnLock:
- case KEY_NAME_INDEX_NumLock:
- case KEY_NAME_INDEX_ScrollLock:
- case KEY_NAME_INDEX_SymbolLock:
- return true;
- default:
- return false;
- }
- }
- } // namespace mozilla
|