1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "BasicEvents.h"
7 #include "ContentEvents.h"
8 #include "MiscEvents.h"
9 #include "MouseEvents.h"
10 #include "NativeKeyBindingsType.h"
11 #include "TextEventDispatcher.h"
12 #include "TextEvents.h"
13 #include "TouchEvents.h"
15 #include "mozilla/EventStateManager.h"
16 #include "mozilla/InternalMutationEvent.h"
17 #include "mozilla/Maybe.h"
18 #include "mozilla/Preferences.h"
19 #include "mozilla/StaticPrefs_mousewheel.h"
20 #include "mozilla/StaticPrefs_ui.h"
21 #include "mozilla/WritingModes.h"
22 #include "mozilla/dom/KeyboardEventBinding.h"
23 #include "mozilla/dom/WheelEventBinding.h"
24 #include "nsCommandParams.h"
25 #include "nsContentUtils.h"
26 #include "nsIContent.h"
27 #include "nsIDragSession.h"
28 #include "nsPrintfCString.h"
32 # include "WinUtils.h"
33 #endif // #if defined (XP_WIN)
35 #if defined(MOZ_WIDGET_GTK) || defined(XP_MACOSX)
36 # include "NativeKeyBindings.h"
37 #endif // #if defined(MOZ_WIDGET_GTK) || defined(XP_MACOSX)
41 /******************************************************************************
42 * Global helper methods
43 ******************************************************************************/
45 const char* ToChar(EventMessage aEventMessage
) {
46 switch (aEventMessage
) {
47 #define NS_EVENT_MESSAGE(aMessage) \
51 #include "mozilla/EventMessageList.h"
53 #undef NS_EVENT_MESSAGE
55 return "illegal event message";
59 const char* ToChar(EventClassID aEventClassID
) {
60 switch (aEventClassID
) {
61 #define NS_ROOT_EVENT_CLASS(aPrefix, aName) \
62 case eBasic##aName##Class: \
63 return "eBasic" #aName "Class";
65 #define NS_EVENT_CLASS(aPrefix, aName) \
66 case e##aName##Class: \
67 return "e" #aName "Class";
69 #include "mozilla/EventClassList.h"
72 #undef NS_ROOT_EVENT_CLASS
74 return "illegal event class ID";
78 const nsCString
ToString(KeyNameIndex aKeyNameIndex
) {
79 if (aKeyNameIndex
== KEY_NAME_INDEX_USE_STRING
) {
80 return "USE_STRING"_ns
;
83 WidgetKeyboardEvent::GetDOMKeyName(aKeyNameIndex
, keyName
);
84 return NS_ConvertUTF16toUTF8(keyName
);
87 const nsCString
ToString(CodeNameIndex aCodeNameIndex
) {
88 if (aCodeNameIndex
== CODE_NAME_INDEX_USE_STRING
) {
89 return "USE_STRING"_ns
;
91 nsAutoString codeName
;
92 WidgetKeyboardEvent::GetDOMCodeName(aCodeNameIndex
, codeName
);
93 return NS_ConvertUTF16toUTF8(codeName
);
96 const char* ToChar(Command aCommand
) {
97 if (aCommand
== Command::DoNothing
) {
98 return "CommandDoNothing";
102 #define NS_DEFINE_COMMAND(aName, aCommandStr) \
103 case Command::aName: \
104 return "Command::" #aName;
105 #define NS_DEFINE_COMMAND_WITH_PARAM(aName, aCommandStr, aParam) \
106 case Command::aName: \
107 return "Command::" #aName;
108 #define NS_DEFINE_COMMAND_NO_EXEC_COMMAND(aName) \
109 case Command::aName: \
110 return "Command::" #aName;
112 #include "mozilla/CommandList.h"
114 #undef NS_DEFINE_COMMAND
115 #undef NS_DEFINE_COMMAND_WITH_PARAM
116 #undef NS_DEFINE_COMMAND_NO_EXEC_COMMAND
119 return "illegal command value";
123 const nsCString
GetDOMKeyCodeName(uint32_t aKeyCode
) {
125 #define NS_DISALLOW_SAME_KEYCODE
126 #define NS_DEFINE_VK(aDOMKeyName, aDOMKeyCode) \
128 return nsLiteralCString(#aDOMKeyName);
130 #include "mozilla/VirtualKeyCodeList.h"
133 #undef NS_DISALLOW_SAME_KEYCODE
136 return nsPrintfCString("Invalid DOM keyCode (0x%08X)", aKeyCode
);
140 bool IsValidRawTextRangeValue(RawTextRangeType aRawTextRangeType
) {
141 switch (static_cast<TextRangeType
>(aRawTextRangeType
)) {
142 case TextRangeType::eUninitialized
:
143 case TextRangeType::eCaret
:
144 case TextRangeType::eRawClause
:
145 case TextRangeType::eSelectedRawClause
:
146 case TextRangeType::eConvertedClause
:
147 case TextRangeType::eSelectedClause
:
154 RawTextRangeType
ToRawTextRangeType(TextRangeType aTextRangeType
) {
155 return static_cast<RawTextRangeType
>(aTextRangeType
);
158 TextRangeType
ToTextRangeType(RawTextRangeType aRawTextRangeType
) {
159 MOZ_ASSERT(IsValidRawTextRangeValue(aRawTextRangeType
));
160 return static_cast<TextRangeType
>(aRawTextRangeType
);
163 const char* ToChar(TextRangeType aTextRangeType
) {
164 switch (aTextRangeType
) {
165 case TextRangeType::eUninitialized
:
166 return "TextRangeType::eUninitialized";
167 case TextRangeType::eCaret
:
168 return "TextRangeType::eCaret";
169 case TextRangeType::eRawClause
:
170 return "TextRangeType::eRawClause";
171 case TextRangeType::eSelectedRawClause
:
172 return "TextRangeType::eSelectedRawClause";
173 case TextRangeType::eConvertedClause
:
174 return "TextRangeType::eConvertedClause";
175 case TextRangeType::eSelectedClause
:
176 return "TextRangeType::eSelectedClause";
178 return "Invalid TextRangeType";
182 SelectionType
ToSelectionType(TextRangeType aTextRangeType
) {
183 switch (aTextRangeType
) {
184 case TextRangeType::eRawClause
:
185 return SelectionType::eIMERawClause
;
186 case TextRangeType::eSelectedRawClause
:
187 return SelectionType::eIMESelectedRawClause
;
188 case TextRangeType::eConvertedClause
:
189 return SelectionType::eIMEConvertedClause
;
190 case TextRangeType::eSelectedClause
:
191 return SelectionType::eIMESelectedClause
;
193 MOZ_CRASH("TextRangeType is invalid");
194 return SelectionType::eNormal
;
198 /******************************************************************************
199 * non class method implementation
200 ******************************************************************************/
202 static nsTHashMap
<nsDepCharHashKey
, Command
>* sCommandHashtable
= nullptr;
204 Command
GetInternalCommand(const char* aCommandName
,
205 const nsCommandParams
* aCommandParams
) {
207 return Command::DoNothing
;
210 // Special cases for "cmd_align". It's mapped to multiple internal commands
211 // with additional param. Therefore, we cannot handle it with the hashtable.
212 if (!strcmp(aCommandName
, "cmd_align")) {
213 if (!aCommandParams
) {
214 // Note that if this is called by EditorCommand::IsCommandEnabled(),
215 // it cannot set aCommandParams. So, don't warn in this case even though
216 // this is illegal case for DoCommandParams().
217 return Command::FormatJustify
;
219 nsAutoCString cValue
;
220 nsresult rv
= aCommandParams
->GetCString("state_attribute", cValue
);
222 nsString value
; // Avoid copying the string buffer with using nsString.
223 rv
= aCommandParams
->GetString("state_attribute", value
);
225 return Command::FormatJustifyNone
;
227 CopyUTF16toUTF8(value
, cValue
);
229 if (cValue
.LowerCaseEqualsASCII("left")) {
230 return Command::FormatJustifyLeft
;
232 if (cValue
.LowerCaseEqualsASCII("right")) {
233 return Command::FormatJustifyRight
;
235 if (cValue
.LowerCaseEqualsASCII("center")) {
236 return Command::FormatJustifyCenter
;
238 if (cValue
.LowerCaseEqualsASCII("justify")) {
239 return Command::FormatJustifyFull
;
241 if (cValue
.IsEmpty()) {
242 return Command::FormatJustifyNone
;
244 return Command::DoNothing
;
247 if (!sCommandHashtable
) {
248 sCommandHashtable
= new nsTHashMap
<nsDepCharHashKey
, Command
>();
249 #define NS_DEFINE_COMMAND(aName, aCommandStr) \
250 sCommandHashtable->InsertOrUpdate(#aCommandStr, Command::aName);
252 #define NS_DEFINE_COMMAND_WITH_PARAM(aName, aCommandStr, aParam)
254 #define NS_DEFINE_COMMAND_NO_EXEC_COMMAND(aName)
256 #include "mozilla/CommandList.h"
258 #undef NS_DEFINE_COMMAND
259 #undef NS_DEFINE_COMMAND_WITH_PARAM
260 #undef NS_DEFINE_COMMAND_NO_EXEC_COMMAND
262 Command command
= Command::DoNothing
;
263 if (!sCommandHashtable
->Get(aCommandName
, &command
)) {
264 return Command::DoNothing
;
269 /******************************************************************************
270 * As*Event() implementation
271 ******************************************************************************/
273 #define NS_ROOT_EVENT_CLASS(aPrefix, aName)
274 #define NS_EVENT_CLASS(aPrefix, aName) \
275 aPrefix##aName* WidgetEvent::As##aName() { return nullptr; } \
277 const aPrefix##aName* WidgetEvent::As##aName() const { \
278 return const_cast<WidgetEvent*>(this)->As##aName(); \
281 #include "mozilla/EventClassList.h"
283 #undef NS_EVENT_CLASS
284 #undef NS_ROOT_EVENT_CLASS
286 /******************************************************************************
287 * mozilla::WidgetEvent
289 * Event struct type checking methods.
290 ******************************************************************************/
292 bool WidgetEvent::IsQueryContentEvent() const {
293 return mClass
== eQueryContentEventClass
;
296 bool WidgetEvent::IsSelectionEvent() const {
297 return mClass
== eSelectionEventClass
;
300 bool WidgetEvent::IsContentCommandEvent() const {
301 return mClass
== eContentCommandEventClass
;
304 /******************************************************************************
305 * mozilla::WidgetEvent
307 * Event message checking methods.
308 ******************************************************************************/
310 bool WidgetEvent::HasMouseEventMessage() const {
315 case eMouseDoubleClick
:
317 case eMouseEnterIntoWidget
:
318 case eMouseExitFromWidget
:
330 bool WidgetEvent::HasDragEventMessage() const {
347 bool WidgetEvent::IsKeyEventMessage(EventMessage aMessage
) {
352 case eKeyDownOnPlugin
:
354 case eAccessKeyNotFound
:
361 bool WidgetEvent::HasIMEEventMessage() const {
363 case eCompositionStart
:
364 case eCompositionEnd
:
365 case eCompositionUpdate
:
366 case eCompositionChange
:
367 case eCompositionCommitAsIs
:
368 case eCompositionCommit
:
375 bool WidgetEvent::HasPluginActivationEventMessage() const {
376 return mMessage
== ePluginActivate
|| mMessage
== ePluginFocus
;
379 /******************************************************************************
380 * mozilla::WidgetEvent
382 * Specific event checking methods.
383 ******************************************************************************/
385 bool WidgetEvent::CanBeSentToRemoteProcess() const {
386 // If this event is explicitly marked as shouldn't be sent to remote process,
387 // just return false.
388 if (IsCrossProcessForwardingStopped()) {
392 if (mClass
== eKeyboardEventClass
|| mClass
== eWheelEventClass
) {
400 case eMouseExploreByTouch
:
402 case eMouseEnterIntoWidget
:
403 case eMouseExitFromWidget
:
404 case eMouseTouchDrag
:
418 bool WidgetEvent::WillBeSentToRemoteProcess() const {
419 // This event won't be posted to remote process if it's already explicitly
421 if (IsCrossProcessForwardingStopped()) {
425 // When mOriginalTarget is nullptr, this method shouldn't be used.
426 if (NS_WARN_IF(!mOriginalTarget
)) {
430 return EventStateManager::IsTopLevelRemoteTarget(
431 nsIContent::FromEventTarget(mOriginalTarget
));
434 bool WidgetEvent::IsIMERelatedEvent() const {
435 return HasIMEEventMessage() || IsQueryContentEvent() || IsSelectionEvent();
438 bool WidgetEvent::IsUsingCoordinates() const {
439 const WidgetMouseEvent
* mouseEvent
= AsMouseEvent();
441 return !mouseEvent
->IsContextMenuKeyEvent();
443 return !HasKeyEventMessage() && !IsIMERelatedEvent() &&
444 !HasPluginActivationEventMessage() && !IsContentCommandEvent();
447 bool WidgetEvent::IsTargetedAtFocusedWindow() const {
448 const WidgetMouseEvent
* mouseEvent
= AsMouseEvent();
450 return mouseEvent
->IsContextMenuKeyEvent();
452 return HasKeyEventMessage() || IsIMERelatedEvent() || IsContentCommandEvent();
455 bool WidgetEvent::IsTargetedAtFocusedContent() const {
456 const WidgetMouseEvent
* mouseEvent
= AsMouseEvent();
458 return mouseEvent
->IsContextMenuKeyEvent();
460 return HasKeyEventMessage() || IsIMERelatedEvent();
463 bool WidgetEvent::IsAllowedToDispatchDOMEvent() const {
465 case eMouseEventClass
:
466 if (mMessage
== eMouseTouchDrag
) {
470 case ePointerEventClass
:
471 // We want synthesized mouse moves to cause mouseover and mouseout
472 // DOM events (EventStateManager::PreHandleEvent), but not mousemove
474 // Synthesized button up events also do not cause DOM events because they
475 // do not have a reliable mRefPoint.
476 return AsMouseEvent()->mReason
== WidgetMouseEvent::eReal
;
478 case eWheelEventClass
: {
479 // wheel event whose all delta values are zero by user pref applied, it
480 // shouldn't cause a DOM event.
481 const WidgetWheelEvent
* wheelEvent
= AsWheelEvent();
482 return wheelEvent
->mDeltaX
!= 0.0 || wheelEvent
->mDeltaY
!= 0.0 ||
483 wheelEvent
->mDeltaZ
!= 0.0;
485 case eTouchEventClass
:
486 return mMessage
!= eTouchPointerCancel
;
487 // Following events are handled in EventStateManager, so, we don't need to
488 // dispatch DOM event for them into the DOM tree.
489 case eQueryContentEventClass
:
490 case eSelectionEventClass
:
491 case eContentCommandEventClass
:
499 bool WidgetEvent::IsAllowedToDispatchInSystemGroup() const {
500 // We don't expect to implement default behaviors with pointer events because
501 // if we do, prevent default on mouse events can't prevent default behaviors
503 return mClass
!= ePointerEventClass
;
506 bool WidgetEvent::IsBlockedForFingerprintingResistance() const {
507 if (!nsContentUtils::ShouldResistFingerprinting()) {
512 case eKeyboardEventClass
: {
513 const WidgetKeyboardEvent
* keyboardEvent
= AsKeyboardEvent();
515 return (keyboardEvent
->mKeyNameIndex
== KEY_NAME_INDEX_Alt
||
516 keyboardEvent
->mKeyNameIndex
== KEY_NAME_INDEX_Shift
||
517 keyboardEvent
->mKeyNameIndex
== KEY_NAME_INDEX_Control
||
518 keyboardEvent
->mKeyNameIndex
== KEY_NAME_INDEX_AltGraph
);
520 case ePointerEventClass
: {
521 const WidgetPointerEvent
* pointerEvent
= AsPointerEvent();
523 // We suppress the pointer events if it is not primary for fingerprinting
524 // resistance. It is because of that we want to spoof any pointer event
525 // into a mouse pointer event and the mouse pointer event only has
526 // isPrimary as true.
527 return !pointerEvent
->mIsPrimary
;
534 /******************************************************************************
535 * mozilla::WidgetEvent
538 ******************************************************************************/
540 static dom::EventTarget
* GetTargetForDOMEvent(dom::EventTarget
* aTarget
) {
541 return aTarget
? aTarget
->GetTargetForDOMEvent() : nullptr;
544 dom::EventTarget
* WidgetEvent::GetDOMEventTarget() const {
545 return GetTargetForDOMEvent(mTarget
);
548 dom::EventTarget
* WidgetEvent::GetCurrentDOMEventTarget() const {
549 return GetTargetForDOMEvent(mCurrentTarget
);
552 dom::EventTarget
* WidgetEvent::GetOriginalDOMEventTarget() const {
553 if (mOriginalTarget
) {
554 return GetTargetForDOMEvent(mOriginalTarget
);
556 return GetDOMEventTarget();
559 void WidgetEvent::PreventDefault(bool aCalledByDefaultHandler
,
560 nsIPrincipal
* aPrincipal
) {
561 if (mMessage
== ePointerDown
) {
562 if (aCalledByDefaultHandler
) {
563 // Shouldn't prevent default on pointerdown by default handlers to stop
564 // firing legacy mouse events. Use MOZ_ASSERT to catch incorrect usages
570 nsAutoString addonId
;
571 Unused
<< NS_WARN_IF(NS_FAILED(aPrincipal
->GetAddonId(addonId
)));
572 if (!addonId
.IsEmpty()) {
573 // Ignore the case that it's called by a web extension.
578 mFlags
.PreventDefault(aCalledByDefaultHandler
);
581 bool WidgetEvent::IsUserAction() const {
585 // FYI: eMouseScrollEventClass and ePointerEventClass represent
586 // user action but they are synthesized events.
588 case eKeyboardEventClass
:
589 case eCompositionEventClass
:
590 case eMouseScrollEventClass
:
591 case eWheelEventClass
:
592 case eGestureNotifyEventClass
:
593 case eSimpleGestureEventClass
:
594 case eTouchEventClass
:
595 case eCommandEventClass
:
596 case eContentCommandEventClass
:
598 case eMouseEventClass
:
599 case eDragEventClass
:
600 case ePointerEventClass
:
601 return AsMouseEvent()->IsReal();
607 /******************************************************************************
608 * mozilla::WidgetInputEvent
609 ******************************************************************************/
612 Modifier
WidgetInputEvent::GetModifier(const nsAString
& aDOMKeyName
) {
613 if (aDOMKeyName
.EqualsLiteral("Accel")) {
614 return AccelModifier();
616 KeyNameIndex keyNameIndex
= WidgetKeyboardEvent::GetKeyNameIndex(aDOMKeyName
);
617 return WidgetKeyboardEvent::GetModifierForKeyName(keyNameIndex
);
621 Modifier
WidgetInputEvent::AccelModifier() {
622 static Modifier sAccelModifier
= MODIFIER_NONE
;
623 if (sAccelModifier
== MODIFIER_NONE
) {
624 switch (Preferences::GetInt("ui.key.accelKey", 0)) {
625 case dom::KeyboardEvent_Binding::DOM_VK_META
:
626 sAccelModifier
= MODIFIER_META
;
628 case dom::KeyboardEvent_Binding::DOM_VK_WIN
:
629 sAccelModifier
= MODIFIER_OS
;
631 case dom::KeyboardEvent_Binding::DOM_VK_ALT
:
632 sAccelModifier
= MODIFIER_ALT
;
634 case dom::KeyboardEvent_Binding::DOM_VK_CONTROL
:
635 sAccelModifier
= MODIFIER_CONTROL
;
639 sAccelModifier
= MODIFIER_META
;
641 sAccelModifier
= MODIFIER_CONTROL
;
646 return sAccelModifier
;
649 /******************************************************************************
650 * mozilla::WidgetMouseEvent (MouseEvents.h)
651 ******************************************************************************/
654 bool WidgetMouseEvent::IsMiddleClickPasteEnabled() {
655 return Preferences::GetBool("middlemouse.paste", false);
659 void WidgetMouseEvent::AssertContextMenuEventButtonConsistency() const {
660 if (mMessage
!= eContextMenu
) {
664 if (mContextMenuTrigger
== eNormal
) {
665 NS_WARNING_ASSERTION(mButton
== MouseButton::eSecondary
,
666 "eContextMenu events with eNormal trigger should use "
667 "secondary mouse button");
669 NS_WARNING_ASSERTION(mButton
== MouseButton::ePrimary
,
670 "eContextMenu events with non-eNormal trigger should "
671 "use primary mouse button");
674 if (mContextMenuTrigger
== eControlClick
) {
675 NS_WARNING_ASSERTION(IsControl(),
676 "eContextMenu events with eControlClick trigger "
677 "should return true from IsControl()");
682 /******************************************************************************
683 * mozilla::WidgetDragEvent (MouseEvents.h)
684 ******************************************************************************/
686 void WidgetDragEvent::InitDropEffectForTests() {
687 MOZ_ASSERT(mFlags
.mIsSynthesizedForTests
);
689 nsCOMPtr
<nsIDragSession
> session
= nsContentUtils::GetDragSession();
690 if (NS_WARN_IF(!session
)) {
694 uint32_t effectAllowed
= session
->GetEffectAllowedForTests();
695 uint32_t desiredDropEffect
= nsIDragService::DRAGDROP_ACTION_NONE
;
698 desiredDropEffect
= IsMeta() ? nsIDragService::DRAGDROP_ACTION_LINK
699 : nsIDragService::DRAGDROP_ACTION_COPY
;
702 // On Linux, we know user's intention from API, but we should use
703 // same modifiers as Windows for tests because GNOME on Ubuntu use
704 // them and that makes each test simpler.
706 desiredDropEffect
= IsShift() ? nsIDragService::DRAGDROP_ACTION_LINK
707 : nsIDragService::DRAGDROP_ACTION_COPY
;
708 } else if (IsShift()) {
709 desiredDropEffect
= nsIDragService::DRAGDROP_ACTION_MOVE
;
711 #endif // #ifdef XP_MACOSX #else
712 // First, use modifier state for preferring action which is explicitly
713 // specified by the synthesizer.
714 if (!(desiredDropEffect
&= effectAllowed
)) {
715 // Otherwise, use an action which is allowed at starting the session.
716 desiredDropEffect
= effectAllowed
;
718 if (desiredDropEffect
& nsIDragService::DRAGDROP_ACTION_MOVE
) {
719 session
->SetDragAction(nsIDragService::DRAGDROP_ACTION_MOVE
);
720 } else if (desiredDropEffect
& nsIDragService::DRAGDROP_ACTION_COPY
) {
721 session
->SetDragAction(nsIDragService::DRAGDROP_ACTION_COPY
);
722 } else if (desiredDropEffect
& nsIDragService::DRAGDROP_ACTION_LINK
) {
723 session
->SetDragAction(nsIDragService::DRAGDROP_ACTION_LINK
);
725 session
->SetDragAction(nsIDragService::DRAGDROP_ACTION_NONE
);
729 /******************************************************************************
730 * mozilla::WidgetWheelEvent (MouseEvents.h)
731 ******************************************************************************/
734 double WidgetWheelEvent::ComputeOverriddenDelta(double aDelta
,
735 bool aIsForVertical
) {
736 if (!StaticPrefs::mousewheel_system_scroll_override_enabled()) {
741 ? StaticPrefs::mousewheel_system_scroll_override_vertical_factor()
742 : StaticPrefs::mousewheel_system_scroll_override_horizontal_factor();
743 // Making the scroll speed slower doesn't make sense. So, ignore odd factor
744 // which is less than 1.0.
745 if (intFactor
<= 100) {
748 double factor
= static_cast<double>(intFactor
) / 100;
749 return aDelta
* factor
;
752 double WidgetWheelEvent::OverriddenDeltaX() const {
753 if (!mAllowToOverrideSystemScrollSpeed
||
754 mDeltaMode
!= dom::WheelEvent_Binding::DOM_DELTA_LINE
||
755 mCustomizedByUserPrefs
) {
758 return ComputeOverriddenDelta(mDeltaX
, false);
761 double WidgetWheelEvent::OverriddenDeltaY() const {
762 if (!mAllowToOverrideSystemScrollSpeed
||
763 mDeltaMode
!= dom::WheelEvent_Binding::DOM_DELTA_LINE
||
764 mCustomizedByUserPrefs
) {
767 return ComputeOverriddenDelta(mDeltaY
, true);
770 /******************************************************************************
771 * mozilla::WidgetKeyboardEvent (TextEvents.h)
772 ******************************************************************************/
774 #define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) (u"" aDOMKeyName),
775 const char16_t
* const WidgetKeyboardEvent::kKeyNames
[] = {
776 #include "mozilla/KeyNameList.h"
778 #undef NS_DEFINE_KEYNAME
780 #define NS_DEFINE_PHYSICAL_KEY_CODE_NAME(aCPPName, aDOMCodeName) \
782 const char16_t
* const WidgetKeyboardEvent::kCodeNames
[] = {
783 #include "mozilla/PhysicalKeyCodeNameList.h"
785 #undef NS_DEFINE_PHYSICAL_KEY_CODE_NAME
787 WidgetKeyboardEvent::KeyNameIndexHashtable
*
788 WidgetKeyboardEvent::sKeyNameIndexHashtable
= nullptr;
789 WidgetKeyboardEvent::CodeNameIndexHashtable
*
790 WidgetKeyboardEvent::sCodeNameIndexHashtable
= nullptr;
792 void WidgetKeyboardEvent::InitAllEditCommands(
793 const Maybe
<WritingMode
>& aWritingMode
) {
794 // If this event is synthesized for tests, we don't need to retrieve the
795 // command via the main process. So, we don't need widget and can trust
797 if (!mFlags
.mIsSynthesizedForTests
) {
798 // If the event was created without widget, e.g., created event in chrome
799 // script, this shouldn't execute native key bindings.
800 if (NS_WARN_IF(!mWidget
)) {
804 // This event should be trusted event here and we shouldn't expose native
805 // key binding information to web contents with untrusted events.
806 if (NS_WARN_IF(!IsTrusted())) {
811 XRE_IsParentProcess(),
812 "It's too expensive to retrieve all edit commands from remote process");
813 MOZ_ASSERT(!AreAllEditCommandsInitialized(),
814 "Shouldn't be called two or more times");
817 DebugOnly
<bool> okIgnored
= InitEditCommandsFor(
818 NativeKeyBindingsType::SingleLineEditor
, aWritingMode
);
819 NS_WARNING_ASSERTION(okIgnored
,
820 "InitEditCommandsFor(NativeKeyBindingsType::"
821 "SingleLineEditor) failed, but ignored");
823 InitEditCommandsFor(NativeKeyBindingsType::MultiLineEditor
, aWritingMode
);
824 NS_WARNING_ASSERTION(okIgnored
,
825 "InitEditCommandsFor(NativeKeyBindingsType::"
826 "MultiLineEditor) failed, but ignored");
828 InitEditCommandsFor(NativeKeyBindingsType::RichTextEditor
, aWritingMode
);
829 NS_WARNING_ASSERTION(okIgnored
,
830 "InitEditCommandsFor(NativeKeyBindingsType::"
831 "RichTextEditor) failed, but ignored");
834 bool WidgetKeyboardEvent::InitEditCommandsFor(
835 NativeKeyBindingsType aType
, const Maybe
<WritingMode
>& aWritingMode
) {
836 bool& initialized
= IsEditCommandsInitializedRef(aType
);
840 nsTArray
<CommandInt
>& commands
= EditCommandsRef(aType
);
842 // If this event is synthesized for tests, we shouldn't access customized
843 // shortcut settings of the environment. Therefore, we don't need to check
844 // whether `widget` is set or not. And we can treat synthesized events are
846 if (mFlags
.mIsSynthesizedForTests
) {
847 MOZ_DIAGNOSTIC_ASSERT(IsTrusted());
848 #if defined(MOZ_WIDGET_GTK) || defined(XP_MACOSX)
849 // TODO: We should implement `NativeKeyBindings` for Windows and Android
850 // too in bug 1301497 for getting rid of the #if.
851 widget::NativeKeyBindings::GetEditCommandsForTests(aType
, *this,
852 aWritingMode
, commands
);
858 if (NS_WARN_IF(!mWidget
) || NS_WARN_IF(!IsTrusted())) {
861 // `nsIWidget::GetEditCommands()` will retrieve `WritingMode` at selection
862 // again, but it should be almost zero-cost since `TextEventDispatcher`
864 nsCOMPtr
<nsIWidget
> widget
= mWidget
;
865 initialized
= widget
->GetEditCommands(aType
, *this, commands
);
869 bool WidgetKeyboardEvent::ExecuteEditCommands(NativeKeyBindingsType aType
,
870 DoCommandCallback aCallback
,
871 void* aCallbackData
) {
872 // If the event was created without widget, e.g., created event in chrome
873 // script, this shouldn't execute native key bindings.
874 if (NS_WARN_IF(!mWidget
)) {
878 // This event should be trusted event here and we shouldn't expose native
879 // key binding information to web contents with untrusted events.
880 if (NS_WARN_IF(!IsTrusted())) {
884 if (!IsEditCommandsInitializedRef(aType
)) {
885 Maybe
<WritingMode
> writingMode
;
886 if (RefPtr
<widget::TextEventDispatcher
> textEventDispatcher
=
887 mWidget
->GetTextEventDispatcher()) {
888 writingMode
= textEventDispatcher
->MaybeQueryWritingModeAtSelection();
890 if (NS_WARN_IF(!InitEditCommandsFor(aType
, writingMode
))) {
895 const nsTArray
<CommandInt
>& commands
= EditCommandsRef(aType
);
896 if (commands
.IsEmpty()) {
900 for (CommandInt command
: commands
) {
901 aCallback(static_cast<Command
>(command
), aCallbackData
);
906 bool WidgetKeyboardEvent::ShouldCauseKeypressEvents() const {
907 // Currently, we don't dispatch keypress events of modifier keys and
909 switch (mKeyNameIndex
) {
910 case KEY_NAME_INDEX_Alt
:
911 case KEY_NAME_INDEX_AltGraph
:
912 case KEY_NAME_INDEX_CapsLock
:
913 case KEY_NAME_INDEX_Control
:
914 case KEY_NAME_INDEX_Fn
:
915 case KEY_NAME_INDEX_FnLock
:
916 // case KEY_NAME_INDEX_Hyper:
917 case KEY_NAME_INDEX_Meta
:
918 case KEY_NAME_INDEX_NumLock
:
919 case KEY_NAME_INDEX_OS
:
920 case KEY_NAME_INDEX_ScrollLock
:
921 case KEY_NAME_INDEX_Shift
:
922 // case KEY_NAME_INDEX_Super:
923 case KEY_NAME_INDEX_Symbol
:
924 case KEY_NAME_INDEX_SymbolLock
:
925 case KEY_NAME_INDEX_Dead
:
932 static bool HasASCIIDigit(const ShortcutKeyCandidateArray
& aCandidates
) {
933 for (uint32_t i
= 0; i
< aCandidates
.Length(); ++i
) {
934 uint32_t ch
= aCandidates
[i
].mCharCode
;
935 if (ch
>= '0' && ch
<= '9') return true;
940 static bool CharsCaseInsensitiveEqual(uint32_t aChar1
, uint32_t aChar2
) {
941 return aChar1
== aChar2
|| (IS_IN_BMP(aChar1
) && IS_IN_BMP(aChar2
) &&
942 ToLowerCase(static_cast<char16_t
>(aChar1
)) ==
943 ToLowerCase(static_cast<char16_t
>(aChar2
)));
946 static bool IsCaseChangeableChar(uint32_t aChar
) {
947 return IS_IN_BMP(aChar
) && ToLowerCase(static_cast<char16_t
>(aChar
)) !=
948 ToUpperCase(static_cast<char16_t
>(aChar
));
951 void WidgetKeyboardEvent::GetShortcutKeyCandidates(
952 ShortcutKeyCandidateArray
& aCandidates
) const {
953 MOZ_ASSERT(aCandidates
.IsEmpty(), "aCandidates must be empty");
955 // ShortcutKeyCandidate::mCharCode is a candidate charCode.
956 // ShortcutKeyCandidate::mIgnoreShift means the mCharCode should be tried to
957 // execute a command with/without shift key state. If this is TRUE, the
958 // shifted key state should be ignored. Otherwise, don't ignore the state.
959 // the priority of the charCodes are (shift key is not pressed):
960 // 0: PseudoCharCode()/false,
961 // 1: unshiftedCharCodes[0]/false, 2: unshiftedCharCodes[1]/false...
962 // the priority of the charCodes are (shift key is pressed):
963 // 0: PseudoCharCode()/false,
964 // 1: shiftedCharCodes[0]/false, 2: shiftedCharCodes[0]/true,
965 // 3: shiftedCharCodes[1]/false, 4: shiftedCharCodes[1]/true...
966 uint32_t pseudoCharCode
= PseudoCharCode();
967 if (pseudoCharCode
) {
968 ShortcutKeyCandidate
key(pseudoCharCode
, false);
969 aCandidates
.AppendElement(key
);
972 uint32_t len
= mAlternativeCharCodes
.Length();
974 for (uint32_t i
= 0; i
< len
; ++i
) {
975 uint32_t ch
= mAlternativeCharCodes
[i
].mUnshiftedCharCode
;
976 if (!ch
|| ch
== pseudoCharCode
) {
979 ShortcutKeyCandidate
key(ch
, false);
980 aCandidates
.AppendElement(key
);
982 // If unshiftedCharCodes doesn't have numeric but shiftedCharCode has it,
983 // this keyboard layout is AZERTY or similar layout, probably.
984 // In this case, Accel+[0-9] should be accessible without shift key.
985 // However, the priority should be lowest.
986 if (!HasASCIIDigit(aCandidates
)) {
987 for (uint32_t i
= 0; i
< len
; ++i
) {
988 uint32_t ch
= mAlternativeCharCodes
[i
].mShiftedCharCode
;
989 if (ch
>= '0' && ch
<= '9') {
990 ShortcutKeyCandidate
key(ch
, false);
991 aCandidates
.AppendElement(key
);
997 for (uint32_t i
= 0; i
< len
; ++i
) {
998 uint32_t ch
= mAlternativeCharCodes
[i
].mShiftedCharCode
;
1003 if (ch
!= pseudoCharCode
) {
1004 ShortcutKeyCandidate
key(ch
, false);
1005 aCandidates
.AppendElement(key
);
1008 // If the char is an alphabet, the shift key state should not be
1009 // ignored. E.g., Ctrl+Shift+C should not execute Ctrl+C.
1011 // And checking the charCode is same as unshiftedCharCode too.
1012 // E.g., for Ctrl+Shift+(Plus of Numpad) should not run Ctrl+Plus.
1013 uint32_t unshiftCh
= mAlternativeCharCodes
[i
].mUnshiftedCharCode
;
1014 if (CharsCaseInsensitiveEqual(ch
, unshiftCh
)) {
1018 // On the Hebrew keyboard layout on Windows, the unshifted char is a
1019 // localized character but the shifted char is a Latin alphabet,
1020 // then, we should not execute without the shift state. See bug 433192.
1021 if (IsCaseChangeableChar(ch
)) {
1025 // Setting the alternative charCode candidates for retry without shift
1026 // key state only when the shift key is pressed.
1027 ShortcutKeyCandidate
key(ch
, true);
1028 aCandidates
.AppendElement(key
);
1032 // Special case for "Space" key. With some keyboard layouts, "Space" with
1033 // or without Shift key causes non-ASCII space. For such keyboard layouts,
1034 // we should guarantee that the key press works as an ASCII white space key
1035 // press. However, if the space key is assigned to a function key, it
1036 // shouldn't work as a space key.
1037 if (mKeyNameIndex
== KEY_NAME_INDEX_USE_STRING
&&
1038 mCodeNameIndex
== CODE_NAME_INDEX_Space
&& pseudoCharCode
!= ' ') {
1039 ShortcutKeyCandidate
spaceKey(' ', false);
1040 aCandidates
.AppendElement(spaceKey
);
1044 void WidgetKeyboardEvent::GetAccessKeyCandidates(
1045 nsTArray
<uint32_t>& aCandidates
) const {
1046 MOZ_ASSERT(aCandidates
.IsEmpty(), "aCandidates must be empty");
1048 // return the lower cased charCode candidates for access keys.
1049 // the priority of the charCodes are:
1050 // 0: charCode, 1: unshiftedCharCodes[0], 2: shiftedCharCodes[0]
1051 // 3: unshiftedCharCodes[1], 4: shiftedCharCodes[1],...
1052 uint32_t pseudoCharCode
= PseudoCharCode();
1053 if (pseudoCharCode
) {
1054 uint32_t ch
= pseudoCharCode
;
1055 if (IS_IN_BMP(ch
)) {
1056 ch
= ToLowerCase(static_cast<char16_t
>(ch
));
1058 aCandidates
.AppendElement(ch
);
1060 for (uint32_t i
= 0; i
< mAlternativeCharCodes
.Length(); ++i
) {
1061 uint32_t ch
[2] = {mAlternativeCharCodes
[i
].mUnshiftedCharCode
,
1062 mAlternativeCharCodes
[i
].mShiftedCharCode
};
1063 for (uint32_t j
= 0; j
< 2; ++j
) {
1067 if (IS_IN_BMP(ch
[j
])) {
1068 ch
[j
] = ToLowerCase(static_cast<char16_t
>(ch
[j
]));
1070 // Don't append the charcode that was already appended.
1071 if (aCandidates
.IndexOf(ch
[j
]) == aCandidates
.NoIndex
) {
1072 aCandidates
.AppendElement(ch
[j
]);
1076 // Special case for "Space" key. With some keyboard layouts, "Space" with
1077 // or without Shift key causes non-ASCII space. For such keyboard layouts,
1078 // we should guarantee that the key press works as an ASCII white space key
1079 // press. However, if the space key is assigned to a function key, it
1080 // shouldn't work as a space key.
1081 if (mKeyNameIndex
== KEY_NAME_INDEX_USE_STRING
&&
1082 mCodeNameIndex
== CODE_NAME_INDEX_Space
&& pseudoCharCode
!= ' ') {
1083 aCandidates
.AppendElement(' ');
1087 // mask values for ui.key.chromeAccess and ui.key.contentAccess
1088 #define NS_MODIFIER_SHIFT 1
1089 #define NS_MODIFIER_CONTROL 2
1090 #define NS_MODIFIER_ALT 4
1091 #define NS_MODIFIER_META 8
1092 #define NS_MODIFIER_OS 16
1094 static Modifiers
PrefFlagsToModifiers(int32_t aPrefFlags
) {
1095 Modifiers result
= 0;
1096 if (aPrefFlags
& NS_MODIFIER_SHIFT
) {
1097 result
|= MODIFIER_SHIFT
;
1099 if (aPrefFlags
& NS_MODIFIER_CONTROL
) {
1100 result
|= MODIFIER_CONTROL
;
1102 if (aPrefFlags
& NS_MODIFIER_ALT
) {
1103 result
|= MODIFIER_ALT
;
1105 if (aPrefFlags
& NS_MODIFIER_META
) {
1106 result
|= MODIFIER_META
;
1108 if (aPrefFlags
& NS_MODIFIER_OS
) {
1109 result
|= MODIFIER_OS
;
1114 bool WidgetKeyboardEvent::ModifiersMatchWithAccessKey(
1115 AccessKeyType aType
) const {
1116 if (!ModifiersForAccessKeyMatching()) {
1119 return ModifiersForAccessKeyMatching() == AccessKeyModifiers(aType
);
1122 Modifiers
WidgetKeyboardEvent::ModifiersForAccessKeyMatching() const {
1123 static const Modifiers kModifierMask
= MODIFIER_SHIFT
| MODIFIER_CONTROL
|
1124 MODIFIER_ALT
| MODIFIER_META
|
1126 return mModifiers
& kModifierMask
;
1130 Modifiers
WidgetKeyboardEvent::AccessKeyModifiers(AccessKeyType aType
) {
1131 switch (StaticPrefs::ui_key_generalAccessKey()) {
1133 break; // use the individual prefs
1135 return MODIFIER_SHIFT
;
1137 return MODIFIER_CONTROL
;
1139 return MODIFIER_ALT
;
1141 return MODIFIER_META
;
1145 return MODIFIER_NONE
;
1149 case AccessKeyType::eChrome
:
1150 return PrefFlagsToModifiers(StaticPrefs::ui_key_chromeAccess());
1151 case AccessKeyType::eContent
:
1152 return PrefFlagsToModifiers(StaticPrefs::ui_key_contentAccess());
1154 return MODIFIER_NONE
;
1159 void WidgetKeyboardEvent::Shutdown() {
1160 delete sKeyNameIndexHashtable
;
1161 sKeyNameIndexHashtable
= nullptr;
1162 delete sCodeNameIndexHashtable
;
1163 sCodeNameIndexHashtable
= nullptr;
1164 // Although sCommandHashtable is not a member of WidgetKeyboardEvent, but
1165 // let's delete it here since we need to do it at same time.
1166 delete sCommandHashtable
;
1167 sCommandHashtable
= nullptr;
1171 void WidgetKeyboardEvent::GetDOMKeyName(KeyNameIndex aKeyNameIndex
,
1172 nsAString
& aKeyName
) {
1173 if (aKeyNameIndex
>= KEY_NAME_INDEX_USE_STRING
) {
1174 aKeyName
.Truncate();
1179 static_cast<size_t>(aKeyNameIndex
) < ArrayLength(kKeyNames
),
1180 "Illegal key enumeration value");
1181 aKeyName
= kKeyNames
[aKeyNameIndex
];
1185 void WidgetKeyboardEvent::GetDOMCodeName(CodeNameIndex aCodeNameIndex
,
1186 nsAString
& aCodeName
) {
1187 if (aCodeNameIndex
>= CODE_NAME_INDEX_USE_STRING
) {
1188 aCodeName
.Truncate();
1193 static_cast<size_t>(aCodeNameIndex
) < ArrayLength(kCodeNames
),
1194 "Illegal physical code enumeration value");
1195 aCodeName
= kCodeNames
[aCodeNameIndex
];
1199 KeyNameIndex
WidgetKeyboardEvent::GetKeyNameIndex(const nsAString
& aKeyValue
) {
1200 if (!sKeyNameIndexHashtable
) {
1201 sKeyNameIndexHashtable
= new KeyNameIndexHashtable(ArrayLength(kKeyNames
));
1202 for (size_t i
= 0; i
< ArrayLength(kKeyNames
); i
++) {
1203 sKeyNameIndexHashtable
->InsertOrUpdate(nsDependentString(kKeyNames
[i
]),
1204 static_cast<KeyNameIndex
>(i
));
1207 return sKeyNameIndexHashtable
->MaybeGet(aKeyValue
).valueOr(
1208 KEY_NAME_INDEX_USE_STRING
);
1212 CodeNameIndex
WidgetKeyboardEvent::GetCodeNameIndex(
1213 const nsAString
& aCodeValue
) {
1214 if (!sCodeNameIndexHashtable
) {
1215 sCodeNameIndexHashtable
=
1216 new CodeNameIndexHashtable(ArrayLength(kCodeNames
));
1217 for (size_t i
= 0; i
< ArrayLength(kCodeNames
); i
++) {
1218 sCodeNameIndexHashtable
->InsertOrUpdate(nsDependentString(kCodeNames
[i
]),
1219 static_cast<CodeNameIndex
>(i
));
1222 return sCodeNameIndexHashtable
->MaybeGet(aCodeValue
)
1223 .valueOr(CODE_NAME_INDEX_USE_STRING
);
1227 uint32_t WidgetKeyboardEvent::GetFallbackKeyCodeOfPunctuationKey(
1228 CodeNameIndex aCodeNameIndex
) {
1229 switch (aCodeNameIndex
) {
1230 case CODE_NAME_INDEX_Semicolon
: // VK_OEM_1 on Windows
1231 return dom::KeyboardEvent_Binding::DOM_VK_SEMICOLON
;
1232 case CODE_NAME_INDEX_Equal
: // VK_OEM_PLUS on Windows
1233 return dom::KeyboardEvent_Binding::DOM_VK_EQUALS
;
1234 case CODE_NAME_INDEX_Comma
: // VK_OEM_COMMA on Windows
1235 return dom::KeyboardEvent_Binding::DOM_VK_COMMA
;
1236 case CODE_NAME_INDEX_Minus
: // VK_OEM_MINUS on Windows
1237 return dom::KeyboardEvent_Binding::DOM_VK_HYPHEN_MINUS
;
1238 case CODE_NAME_INDEX_Period
: // VK_OEM_PERIOD on Windows
1239 return dom::KeyboardEvent_Binding::DOM_VK_PERIOD
;
1240 case CODE_NAME_INDEX_Slash
: // VK_OEM_2 on Windows
1241 return dom::KeyboardEvent_Binding::DOM_VK_SLASH
;
1242 case CODE_NAME_INDEX_Backquote
: // VK_OEM_3 on Windows
1243 return dom::KeyboardEvent_Binding::DOM_VK_BACK_QUOTE
;
1244 case CODE_NAME_INDEX_BracketLeft
: // VK_OEM_4 on Windows
1245 return dom::KeyboardEvent_Binding::DOM_VK_OPEN_BRACKET
;
1246 case CODE_NAME_INDEX_Backslash
: // VK_OEM_5 on Windows
1247 return dom::KeyboardEvent_Binding::DOM_VK_BACK_SLASH
;
1248 case CODE_NAME_INDEX_BracketRight
: // VK_OEM_6 on Windows
1249 return dom::KeyboardEvent_Binding::DOM_VK_CLOSE_BRACKET
;
1250 case CODE_NAME_INDEX_Quote
: // VK_OEM_7 on Windows
1251 return dom::KeyboardEvent_Binding::DOM_VK_QUOTE
;
1252 case CODE_NAME_INDEX_IntlBackslash
: // VK_OEM_5 on Windows (ABNT, etc)
1253 case CODE_NAME_INDEX_IntlYen
: // VK_OEM_5 on Windows (JIS)
1254 case CODE_NAME_INDEX_IntlRo
: // VK_OEM_102 on Windows
1255 return dom::KeyboardEvent_Binding::DOM_VK_BACK_SLASH
;
1261 /* static */ const char* WidgetKeyboardEvent::GetCommandStr(Command aCommand
) {
1262 #define NS_DEFINE_COMMAND(aName, aCommandStr) , #aCommandStr
1263 #define NS_DEFINE_COMMAND_WITH_PARAM(aName, aCommandStr, aParam) , #aCommandStr
1264 #define NS_DEFINE_COMMAND_NO_EXEC_COMMAND(aName) , ""
1265 static const char* const kCommands
[] = {
1267 #include "mozilla/CommandList.h"
1269 #undef NS_DEFINE_COMMAND
1270 #undef NS_DEFINE_COMMAND_WITH_PARAM
1271 #undef NS_DEFINE_COMMAND_NO_EXEC_COMMAND
1273 MOZ_RELEASE_ASSERT(static_cast<size_t>(aCommand
) < ArrayLength(kCommands
),
1274 "Illegal command enumeration value");
1275 return kCommands
[static_cast<CommandInt
>(aCommand
)];
1279 uint32_t WidgetKeyboardEvent::ComputeLocationFromCodeValue(
1280 CodeNameIndex aCodeNameIndex
) {
1281 // Following commented out cases are not defined in PhysicalKeyCodeNameList.h
1282 // but are defined by D3E spec. So, they should be uncommented when the
1283 // code values are defined in the header.
1284 switch (aCodeNameIndex
) {
1285 case CODE_NAME_INDEX_AltLeft
:
1286 case CODE_NAME_INDEX_ControlLeft
:
1287 case CODE_NAME_INDEX_OSLeft
:
1288 case CODE_NAME_INDEX_ShiftLeft
:
1289 return eKeyLocationLeft
;
1290 case CODE_NAME_INDEX_AltRight
:
1291 case CODE_NAME_INDEX_ControlRight
:
1292 case CODE_NAME_INDEX_OSRight
:
1293 case CODE_NAME_INDEX_ShiftRight
:
1294 return eKeyLocationRight
;
1295 case CODE_NAME_INDEX_Numpad0
:
1296 case CODE_NAME_INDEX_Numpad1
:
1297 case CODE_NAME_INDEX_Numpad2
:
1298 case CODE_NAME_INDEX_Numpad3
:
1299 case CODE_NAME_INDEX_Numpad4
:
1300 case CODE_NAME_INDEX_Numpad5
:
1301 case CODE_NAME_INDEX_Numpad6
:
1302 case CODE_NAME_INDEX_Numpad7
:
1303 case CODE_NAME_INDEX_Numpad8
:
1304 case CODE_NAME_INDEX_Numpad9
:
1305 case CODE_NAME_INDEX_NumpadAdd
:
1306 case CODE_NAME_INDEX_NumpadBackspace
:
1307 case CODE_NAME_INDEX_NumpadClear
:
1308 case CODE_NAME_INDEX_NumpadClearEntry
:
1309 case CODE_NAME_INDEX_NumpadComma
:
1310 case CODE_NAME_INDEX_NumpadDecimal
:
1311 case CODE_NAME_INDEX_NumpadDivide
:
1312 case CODE_NAME_INDEX_NumpadEnter
:
1313 case CODE_NAME_INDEX_NumpadEqual
:
1314 case CODE_NAME_INDEX_NumpadMemoryAdd
:
1315 case CODE_NAME_INDEX_NumpadMemoryClear
:
1316 case CODE_NAME_INDEX_NumpadMemoryRecall
:
1317 case CODE_NAME_INDEX_NumpadMemoryStore
:
1318 case CODE_NAME_INDEX_NumpadMemorySubtract
:
1319 case CODE_NAME_INDEX_NumpadMultiply
:
1320 case CODE_NAME_INDEX_NumpadParenLeft
:
1321 case CODE_NAME_INDEX_NumpadParenRight
:
1322 case CODE_NAME_INDEX_NumpadSubtract
:
1323 return eKeyLocationNumpad
;
1325 return eKeyLocationStandard
;
1330 uint32_t WidgetKeyboardEvent::ComputeKeyCodeFromKeyNameIndex(
1331 KeyNameIndex aKeyNameIndex
) {
1332 switch (aKeyNameIndex
) {
1333 case KEY_NAME_INDEX_Cancel
:
1334 return dom::KeyboardEvent_Binding::DOM_VK_CANCEL
;
1335 case KEY_NAME_INDEX_Help
:
1336 return dom::KeyboardEvent_Binding::DOM_VK_HELP
;
1337 case KEY_NAME_INDEX_Backspace
:
1338 return dom::KeyboardEvent_Binding::DOM_VK_BACK_SPACE
;
1339 case KEY_NAME_INDEX_Tab
:
1340 return dom::KeyboardEvent_Binding::DOM_VK_TAB
;
1341 case KEY_NAME_INDEX_Clear
:
1342 return dom::KeyboardEvent_Binding::DOM_VK_CLEAR
;
1343 case KEY_NAME_INDEX_Enter
:
1344 return dom::KeyboardEvent_Binding::DOM_VK_RETURN
;
1345 case KEY_NAME_INDEX_Shift
:
1346 return dom::KeyboardEvent_Binding::DOM_VK_SHIFT
;
1347 case KEY_NAME_INDEX_Control
:
1348 return dom::KeyboardEvent_Binding::DOM_VK_CONTROL
;
1349 case KEY_NAME_INDEX_Alt
:
1350 return dom::KeyboardEvent_Binding::DOM_VK_ALT
;
1351 case KEY_NAME_INDEX_Pause
:
1352 return dom::KeyboardEvent_Binding::DOM_VK_PAUSE
;
1353 case KEY_NAME_INDEX_CapsLock
:
1354 return dom::KeyboardEvent_Binding::DOM_VK_CAPS_LOCK
;
1355 case KEY_NAME_INDEX_Hiragana
:
1356 case KEY_NAME_INDEX_Katakana
:
1357 case KEY_NAME_INDEX_HiraganaKatakana
:
1358 case KEY_NAME_INDEX_KanaMode
:
1359 return dom::KeyboardEvent_Binding::DOM_VK_KANA
;
1360 case KEY_NAME_INDEX_HangulMode
:
1361 return dom::KeyboardEvent_Binding::DOM_VK_HANGUL
;
1362 case KEY_NAME_INDEX_Eisu
:
1363 return dom::KeyboardEvent_Binding::DOM_VK_EISU
;
1364 case KEY_NAME_INDEX_JunjaMode
:
1365 return dom::KeyboardEvent_Binding::DOM_VK_JUNJA
;
1366 case KEY_NAME_INDEX_FinalMode
:
1367 return dom::KeyboardEvent_Binding::DOM_VK_FINAL
;
1368 case KEY_NAME_INDEX_HanjaMode
:
1369 return dom::KeyboardEvent_Binding::DOM_VK_HANJA
;
1370 case KEY_NAME_INDEX_KanjiMode
:
1371 return dom::KeyboardEvent_Binding::DOM_VK_KANJI
;
1372 case KEY_NAME_INDEX_Escape
:
1373 return dom::KeyboardEvent_Binding::DOM_VK_ESCAPE
;
1374 case KEY_NAME_INDEX_Convert
:
1375 return dom::KeyboardEvent_Binding::DOM_VK_CONVERT
;
1376 case KEY_NAME_INDEX_NonConvert
:
1377 return dom::KeyboardEvent_Binding::DOM_VK_NONCONVERT
;
1378 case KEY_NAME_INDEX_Accept
:
1379 return dom::KeyboardEvent_Binding::DOM_VK_ACCEPT
;
1380 case KEY_NAME_INDEX_ModeChange
:
1381 return dom::KeyboardEvent_Binding::DOM_VK_MODECHANGE
;
1382 case KEY_NAME_INDEX_PageUp
:
1383 return dom::KeyboardEvent_Binding::DOM_VK_PAGE_UP
;
1384 case KEY_NAME_INDEX_PageDown
:
1385 return dom::KeyboardEvent_Binding::DOM_VK_PAGE_DOWN
;
1386 case KEY_NAME_INDEX_End
:
1387 return dom::KeyboardEvent_Binding::DOM_VK_END
;
1388 case KEY_NAME_INDEX_Home
:
1389 return dom::KeyboardEvent_Binding::DOM_VK_HOME
;
1390 case KEY_NAME_INDEX_ArrowLeft
:
1391 return dom::KeyboardEvent_Binding::DOM_VK_LEFT
;
1392 case KEY_NAME_INDEX_ArrowUp
:
1393 return dom::KeyboardEvent_Binding::DOM_VK_UP
;
1394 case KEY_NAME_INDEX_ArrowRight
:
1395 return dom::KeyboardEvent_Binding::DOM_VK_RIGHT
;
1396 case KEY_NAME_INDEX_ArrowDown
:
1397 return dom::KeyboardEvent_Binding::DOM_VK_DOWN
;
1398 case KEY_NAME_INDEX_Select
:
1399 return dom::KeyboardEvent_Binding::DOM_VK_SELECT
;
1400 case KEY_NAME_INDEX_Print
:
1401 return dom::KeyboardEvent_Binding::DOM_VK_PRINT
;
1402 case KEY_NAME_INDEX_Execute
:
1403 return dom::KeyboardEvent_Binding::DOM_VK_EXECUTE
;
1404 case KEY_NAME_INDEX_PrintScreen
:
1405 return dom::KeyboardEvent_Binding::DOM_VK_PRINTSCREEN
;
1406 case KEY_NAME_INDEX_Insert
:
1407 return dom::KeyboardEvent_Binding::DOM_VK_INSERT
;
1408 case KEY_NAME_INDEX_Delete
:
1409 return dom::KeyboardEvent_Binding::DOM_VK_DELETE
;
1410 case KEY_NAME_INDEX_OS
:
1411 // case KEY_NAME_INDEX_Super:
1412 // case KEY_NAME_INDEX_Hyper:
1413 return dom::KeyboardEvent_Binding::DOM_VK_WIN
;
1414 case KEY_NAME_INDEX_ContextMenu
:
1415 return dom::KeyboardEvent_Binding::DOM_VK_CONTEXT_MENU
;
1416 case KEY_NAME_INDEX_Standby
:
1417 return dom::KeyboardEvent_Binding::DOM_VK_SLEEP
;
1418 case KEY_NAME_INDEX_F1
:
1419 return dom::KeyboardEvent_Binding::DOM_VK_F1
;
1420 case KEY_NAME_INDEX_F2
:
1421 return dom::KeyboardEvent_Binding::DOM_VK_F2
;
1422 case KEY_NAME_INDEX_F3
:
1423 return dom::KeyboardEvent_Binding::DOM_VK_F3
;
1424 case KEY_NAME_INDEX_F4
:
1425 return dom::KeyboardEvent_Binding::DOM_VK_F4
;
1426 case KEY_NAME_INDEX_F5
:
1427 return dom::KeyboardEvent_Binding::DOM_VK_F5
;
1428 case KEY_NAME_INDEX_F6
:
1429 return dom::KeyboardEvent_Binding::DOM_VK_F6
;
1430 case KEY_NAME_INDEX_F7
:
1431 return dom::KeyboardEvent_Binding::DOM_VK_F7
;
1432 case KEY_NAME_INDEX_F8
:
1433 return dom::KeyboardEvent_Binding::DOM_VK_F8
;
1434 case KEY_NAME_INDEX_F9
:
1435 return dom::KeyboardEvent_Binding::DOM_VK_F9
;
1436 case KEY_NAME_INDEX_F10
:
1437 return dom::KeyboardEvent_Binding::DOM_VK_F10
;
1438 case KEY_NAME_INDEX_F11
:
1439 return dom::KeyboardEvent_Binding::DOM_VK_F11
;
1440 case KEY_NAME_INDEX_F12
:
1441 return dom::KeyboardEvent_Binding::DOM_VK_F12
;
1442 case KEY_NAME_INDEX_F13
:
1443 return dom::KeyboardEvent_Binding::DOM_VK_F13
;
1444 case KEY_NAME_INDEX_F14
:
1445 return dom::KeyboardEvent_Binding::DOM_VK_F14
;
1446 case KEY_NAME_INDEX_F15
:
1447 return dom::KeyboardEvent_Binding::DOM_VK_F15
;
1448 case KEY_NAME_INDEX_F16
:
1449 return dom::KeyboardEvent_Binding::DOM_VK_F16
;
1450 case KEY_NAME_INDEX_F17
:
1451 return dom::KeyboardEvent_Binding::DOM_VK_F17
;
1452 case KEY_NAME_INDEX_F18
:
1453 return dom::KeyboardEvent_Binding::DOM_VK_F18
;
1454 case KEY_NAME_INDEX_F19
:
1455 return dom::KeyboardEvent_Binding::DOM_VK_F19
;
1456 case KEY_NAME_INDEX_F20
:
1457 return dom::KeyboardEvent_Binding::DOM_VK_F20
;
1458 case KEY_NAME_INDEX_F21
:
1459 return dom::KeyboardEvent_Binding::DOM_VK_F21
;
1460 case KEY_NAME_INDEX_F22
:
1461 return dom::KeyboardEvent_Binding::DOM_VK_F22
;
1462 case KEY_NAME_INDEX_F23
:
1463 return dom::KeyboardEvent_Binding::DOM_VK_F23
;
1464 case KEY_NAME_INDEX_F24
:
1465 return dom::KeyboardEvent_Binding::DOM_VK_F24
;
1466 case KEY_NAME_INDEX_NumLock
:
1467 return dom::KeyboardEvent_Binding::DOM_VK_NUM_LOCK
;
1468 case KEY_NAME_INDEX_ScrollLock
:
1469 return dom::KeyboardEvent_Binding::DOM_VK_SCROLL_LOCK
;
1470 case KEY_NAME_INDEX_AudioVolumeMute
:
1471 return dom::KeyboardEvent_Binding::DOM_VK_VOLUME_MUTE
;
1472 case KEY_NAME_INDEX_AudioVolumeDown
:
1473 return dom::KeyboardEvent_Binding::DOM_VK_VOLUME_DOWN
;
1474 case KEY_NAME_INDEX_AudioVolumeUp
:
1475 return dom::KeyboardEvent_Binding::DOM_VK_VOLUME_UP
;
1476 case KEY_NAME_INDEX_Meta
:
1477 return dom::KeyboardEvent_Binding::DOM_VK_META
;
1478 case KEY_NAME_INDEX_AltGraph
:
1479 return dom::KeyboardEvent_Binding::DOM_VK_ALTGR
;
1480 case KEY_NAME_INDEX_Process
:
1481 return dom::KeyboardEvent_Binding::DOM_VK_PROCESSKEY
;
1482 case KEY_NAME_INDEX_Attn
:
1483 return dom::KeyboardEvent_Binding::DOM_VK_ATTN
;
1484 case KEY_NAME_INDEX_CrSel
:
1485 return dom::KeyboardEvent_Binding::DOM_VK_CRSEL
;
1486 case KEY_NAME_INDEX_ExSel
:
1487 return dom::KeyboardEvent_Binding::DOM_VK_EXSEL
;
1488 case KEY_NAME_INDEX_EraseEof
:
1489 return dom::KeyboardEvent_Binding::DOM_VK_EREOF
;
1490 case KEY_NAME_INDEX_Play
:
1491 return dom::KeyboardEvent_Binding::DOM_VK_PLAY
;
1492 case KEY_NAME_INDEX_ZoomToggle
:
1493 case KEY_NAME_INDEX_ZoomIn
:
1494 case KEY_NAME_INDEX_ZoomOut
:
1495 return dom::KeyboardEvent_Binding::DOM_VK_ZOOM
;
1502 CodeNameIndex
WidgetKeyboardEvent::ComputeCodeNameIndexFromKeyNameIndex(
1503 KeyNameIndex aKeyNameIndex
, const Maybe
<uint32_t>& aLocation
) {
1504 if (aLocation
.isSome() &&
1505 aLocation
.value() ==
1506 dom::KeyboardEvent_Binding::DOM_KEY_LOCATION_NUMPAD
) {
1507 // On macOS, NumLock is not supported. Therefore, this handles
1508 // control key values except "Enter" only on non-macOS platforms.
1509 switch (aKeyNameIndex
) {
1511 case KEY_NAME_INDEX_Insert
:
1512 return CODE_NAME_INDEX_Numpad0
;
1513 case KEY_NAME_INDEX_End
:
1514 return CODE_NAME_INDEX_Numpad1
;
1515 case KEY_NAME_INDEX_ArrowDown
:
1516 return CODE_NAME_INDEX_Numpad2
;
1517 case KEY_NAME_INDEX_PageDown
:
1518 return CODE_NAME_INDEX_Numpad3
;
1519 case KEY_NAME_INDEX_ArrowLeft
:
1520 return CODE_NAME_INDEX_Numpad4
;
1521 case KEY_NAME_INDEX_Clear
:
1522 // FYI: "Clear" on macOS should be DOM_KEY_LOCATION_STANDARD.
1523 return CODE_NAME_INDEX_Numpad5
;
1524 case KEY_NAME_INDEX_ArrowRight
:
1525 return CODE_NAME_INDEX_Numpad6
;
1526 case KEY_NAME_INDEX_Home
:
1527 return CODE_NAME_INDEX_Numpad7
;
1528 case KEY_NAME_INDEX_ArrowUp
:
1529 return CODE_NAME_INDEX_Numpad8
;
1530 case KEY_NAME_INDEX_PageUp
:
1531 return CODE_NAME_INDEX_Numpad9
;
1532 case KEY_NAME_INDEX_Delete
:
1533 return CODE_NAME_INDEX_NumpadDecimal
;
1534 #endif // #ifndef XP_MACOSX
1535 case KEY_NAME_INDEX_Enter
:
1536 return CODE_NAME_INDEX_NumpadEnter
;
1538 return CODE_NAME_INDEX_UNKNOWN
;
1542 if (WidgetKeyboardEvent::IsLeftOrRightModiferKeyNameIndex(aKeyNameIndex
)) {
1543 if (aLocation
.isSome() &&
1544 (aLocation
.value() !=
1545 dom::KeyboardEvent_Binding::DOM_KEY_LOCATION_LEFT
&&
1546 aLocation
.value() !=
1547 dom::KeyboardEvent_Binding::DOM_KEY_LOCATION_RIGHT
)) {
1548 return CODE_NAME_INDEX_UNKNOWN
;
1551 aLocation
.isSome() &&
1552 aLocation
.value() == dom::KeyboardEvent_Binding::DOM_KEY_LOCATION_RIGHT
;
1553 switch (aKeyNameIndex
) {
1554 case KEY_NAME_INDEX_Alt
:
1555 return isRight
? CODE_NAME_INDEX_AltRight
: CODE_NAME_INDEX_AltLeft
;
1556 case KEY_NAME_INDEX_Control
:
1557 return isRight
? CODE_NAME_INDEX_ControlRight
1558 : CODE_NAME_INDEX_ControlLeft
;
1559 case KEY_NAME_INDEX_Shift
:
1560 return isRight
? CODE_NAME_INDEX_ShiftRight
: CODE_NAME_INDEX_ShiftLeft
;
1562 case KEY_NAME_INDEX_Meta
:
1563 return CODE_NAME_INDEX_UNKNOWN
;
1564 case KEY_NAME_INDEX_OS
: // win key.
1565 return isRight
? CODE_NAME_INDEX_OSRight
: CODE_NAME_INDEX_OSLeft
;
1566 #elif defined(XP_MACOSX) || defined(ANDROID)
1567 case KEY_NAME_INDEX_Meta
: // command key.
1568 return isRight
? CODE_NAME_INDEX_OSRight
: CODE_NAME_INDEX_OSLeft
;
1569 case KEY_NAME_INDEX_OS
:
1570 return CODE_NAME_INDEX_UNKNOWN
;
1572 case KEY_NAME_INDEX_Meta
: // Alt + Shift.
1573 return isRight
? CODE_NAME_INDEX_AltRight
: CODE_NAME_INDEX_AltLeft
;
1574 case KEY_NAME_INDEX_OS
: // Super/Hyper key.
1575 return isRight
? CODE_NAME_INDEX_OSRight
: CODE_NAME_INDEX_OSLeft
;
1578 return CODE_NAME_INDEX_UNKNOWN
;
1582 if (aLocation
.isSome() &&
1583 aLocation
.value() !=
1584 dom::KeyboardEvent_Binding::DOM_KEY_LOCATION_STANDARD
) {
1585 return CODE_NAME_INDEX_UNKNOWN
;
1588 switch (aKeyNameIndex
) {
1589 // Standard section:
1590 case KEY_NAME_INDEX_Escape
:
1591 return CODE_NAME_INDEX_Escape
;
1592 case KEY_NAME_INDEX_Tab
:
1593 return CODE_NAME_INDEX_Tab
;
1594 case KEY_NAME_INDEX_CapsLock
:
1595 return CODE_NAME_INDEX_CapsLock
;
1596 case KEY_NAME_INDEX_ContextMenu
:
1597 return CODE_NAME_INDEX_ContextMenu
;
1598 case KEY_NAME_INDEX_Backspace
:
1599 return CODE_NAME_INDEX_Backspace
;
1600 case KEY_NAME_INDEX_Enter
:
1601 return CODE_NAME_INDEX_Enter
;
1603 // Although, macOS does not fire native key event of "Fn" key, we support
1604 // Fn key event if it's sent by other apps directly.
1605 case KEY_NAME_INDEX_Fn
:
1606 return CODE_NAME_INDEX_Fn
;
1609 // Arrow Pad section:
1610 case KEY_NAME_INDEX_ArrowLeft
:
1611 return CODE_NAME_INDEX_ArrowLeft
;
1612 case KEY_NAME_INDEX_ArrowUp
:
1613 return CODE_NAME_INDEX_ArrowUp
;
1614 case KEY_NAME_INDEX_ArrowDown
:
1615 return CODE_NAME_INDEX_ArrowDown
;
1616 case KEY_NAME_INDEX_ArrowRight
:
1617 return CODE_NAME_INDEX_ArrowRight
;
1619 // Control Pad section:
1621 case KEY_NAME_INDEX_Insert
:
1622 return CODE_NAME_INDEX_Insert
;
1624 case KEY_NAME_INDEX_Help
:
1625 return CODE_NAME_INDEX_Help
;
1626 #endif // #ifndef XP_MACOSX #else
1627 case KEY_NAME_INDEX_Delete
:
1628 return CODE_NAME_INDEX_Delete
;
1629 case KEY_NAME_INDEX_Home
:
1630 return CODE_NAME_INDEX_Home
;
1631 case KEY_NAME_INDEX_End
:
1632 return CODE_NAME_INDEX_End
;
1633 case KEY_NAME_INDEX_PageUp
:
1634 return CODE_NAME_INDEX_PageUp
;
1635 case KEY_NAME_INDEX_PageDown
:
1636 return CODE_NAME_INDEX_PageDown
;
1639 case KEY_NAME_INDEX_F1
:
1640 return CODE_NAME_INDEX_F1
;
1641 case KEY_NAME_INDEX_F2
:
1642 return CODE_NAME_INDEX_F2
;
1643 case KEY_NAME_INDEX_F3
:
1644 return CODE_NAME_INDEX_F3
;
1645 case KEY_NAME_INDEX_F4
:
1646 return CODE_NAME_INDEX_F4
;
1647 case KEY_NAME_INDEX_F5
:
1648 return CODE_NAME_INDEX_F5
;
1649 case KEY_NAME_INDEX_F6
:
1650 return CODE_NAME_INDEX_F6
;
1651 case KEY_NAME_INDEX_F7
:
1652 return CODE_NAME_INDEX_F7
;
1653 case KEY_NAME_INDEX_F8
:
1654 return CODE_NAME_INDEX_F8
;
1655 case KEY_NAME_INDEX_F9
:
1656 return CODE_NAME_INDEX_F9
;
1657 case KEY_NAME_INDEX_F10
:
1658 return CODE_NAME_INDEX_F10
;
1659 case KEY_NAME_INDEX_F11
:
1660 return CODE_NAME_INDEX_F11
;
1661 case KEY_NAME_INDEX_F12
:
1662 return CODE_NAME_INDEX_F12
;
1663 case KEY_NAME_INDEX_F13
:
1664 return CODE_NAME_INDEX_F13
;
1665 case KEY_NAME_INDEX_F14
:
1666 return CODE_NAME_INDEX_F14
;
1667 case KEY_NAME_INDEX_F15
:
1668 return CODE_NAME_INDEX_F15
;
1669 case KEY_NAME_INDEX_F16
:
1670 return CODE_NAME_INDEX_F16
;
1671 case KEY_NAME_INDEX_F17
:
1672 return CODE_NAME_INDEX_F17
;
1673 case KEY_NAME_INDEX_F18
:
1674 return CODE_NAME_INDEX_F18
;
1675 case KEY_NAME_INDEX_F19
:
1676 return CODE_NAME_INDEX_F19
;
1677 case KEY_NAME_INDEX_F20
:
1678 return CODE_NAME_INDEX_F20
;
1680 case KEY_NAME_INDEX_F21
:
1681 return CODE_NAME_INDEX_F21
;
1682 case KEY_NAME_INDEX_F22
:
1683 return CODE_NAME_INDEX_F22
;
1684 case KEY_NAME_INDEX_F23
:
1685 return CODE_NAME_INDEX_F23
;
1686 case KEY_NAME_INDEX_F24
:
1687 return CODE_NAME_INDEX_F24
;
1688 case KEY_NAME_INDEX_Pause
:
1689 return CODE_NAME_INDEX_Pause
;
1690 case KEY_NAME_INDEX_PrintScreen
:
1691 return CODE_NAME_INDEX_PrintScreen
;
1692 case KEY_NAME_INDEX_ScrollLock
:
1693 return CODE_NAME_INDEX_ScrollLock
;
1694 #endif // #ifndef XP_MACOSX
1698 case KEY_NAME_INDEX_NumLock
:
1699 return CODE_NAME_INDEX_NumLock
;
1701 case KEY_NAME_INDEX_Clear
:
1702 return CODE_NAME_INDEX_NumLock
;
1703 #endif // #ifndef XP_MACOSX #else
1706 case KEY_NAME_INDEX_AudioVolumeDown
:
1707 return CODE_NAME_INDEX_VolumeDown
;
1708 case KEY_NAME_INDEX_AudioVolumeMute
:
1709 return CODE_NAME_INDEX_VolumeMute
;
1710 case KEY_NAME_INDEX_AudioVolumeUp
:
1711 return CODE_NAME_INDEX_VolumeUp
;
1713 case KEY_NAME_INDEX_BrowserBack
:
1714 return CODE_NAME_INDEX_BrowserBack
;
1715 case KEY_NAME_INDEX_BrowserFavorites
:
1716 return CODE_NAME_INDEX_BrowserFavorites
;
1717 case KEY_NAME_INDEX_BrowserForward
:
1718 return CODE_NAME_INDEX_BrowserForward
;
1719 case KEY_NAME_INDEX_BrowserRefresh
:
1720 return CODE_NAME_INDEX_BrowserRefresh
;
1721 case KEY_NAME_INDEX_BrowserSearch
:
1722 return CODE_NAME_INDEX_BrowserSearch
;
1723 case KEY_NAME_INDEX_BrowserStop
:
1724 return CODE_NAME_INDEX_BrowserStop
;
1725 case KEY_NAME_INDEX_MediaPlayPause
:
1726 return CODE_NAME_INDEX_MediaPlayPause
;
1727 case KEY_NAME_INDEX_MediaStop
:
1728 return CODE_NAME_INDEX_MediaStop
;
1729 case KEY_NAME_INDEX_MediaTrackNext
:
1730 return CODE_NAME_INDEX_MediaTrackNext
;
1731 case KEY_NAME_INDEX_MediaTrackPrevious
:
1732 return CODE_NAME_INDEX_MediaTrackPrevious
;
1733 case KEY_NAME_INDEX_LaunchApplication1
:
1734 return CODE_NAME_INDEX_LaunchApp1
;
1735 #endif // #ifndef XP_MACOSX
1737 // Only Windows and GTK supports the following multimedia keys.
1738 #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
1739 case KEY_NAME_INDEX_BrowserHome
:
1740 return CODE_NAME_INDEX_BrowserHome
;
1741 case KEY_NAME_INDEX_LaunchApplication2
:
1742 return CODE_NAME_INDEX_LaunchApp2
;
1743 #endif // #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
1745 // Only GTK and Android supports the following multimedia keys.
1746 #if defined(MOZ_WIDGET_GTK) || defined(ANDROID)
1747 case KEY_NAME_INDEX_Eject
:
1748 return CODE_NAME_INDEX_Eject
;
1749 case KEY_NAME_INDEX_WakeUp
:
1750 return CODE_NAME_INDEX_WakeUp
;
1751 #endif // #if defined(MOZ_WIDGET_GTK) || defined(ANDROID)
1753 // Only Windows does not support Help key (and macOS handled above).
1754 #if !defined(XP_WIN) && !defined(XP_MACOSX)
1755 case KEY_NAME_INDEX_Help
:
1756 return CODE_NAME_INDEX_Help
;
1757 #endif // #if !defined(XP_WIN) && !defined(XP_MACOSX)
1759 // IME specific keys:
1761 case KEY_NAME_INDEX_Convert
:
1762 return CODE_NAME_INDEX_Convert
;
1763 case KEY_NAME_INDEX_NonConvert
:
1764 return CODE_NAME_INDEX_NonConvert
;
1765 case KEY_NAME_INDEX_Alphanumeric
:
1766 return CODE_NAME_INDEX_CapsLock
;
1767 case KEY_NAME_INDEX_KanaMode
:
1768 case KEY_NAME_INDEX_Romaji
:
1769 case KEY_NAME_INDEX_Katakana
:
1770 case KEY_NAME_INDEX_Hiragana
:
1771 return CODE_NAME_INDEX_KanaMode
;
1772 case KEY_NAME_INDEX_Hankaku
:
1773 case KEY_NAME_INDEX_Zenkaku
:
1774 case KEY_NAME_INDEX_KanjiMode
:
1775 return CODE_NAME_INDEX_Backquote
;
1776 case KEY_NAME_INDEX_HanjaMode
:
1777 return CODE_NAME_INDEX_Lang2
;
1778 case KEY_NAME_INDEX_HangulMode
:
1779 return CODE_NAME_INDEX_Lang1
;
1780 #endif // #ifdef XP_WIN
1782 #ifdef MOZ_WIDGET_GTK
1783 case KEY_NAME_INDEX_Convert
:
1784 return CODE_NAME_INDEX_Convert
;
1785 case KEY_NAME_INDEX_NonConvert
:
1786 return CODE_NAME_INDEX_NonConvert
;
1787 case KEY_NAME_INDEX_Alphanumeric
:
1788 return CODE_NAME_INDEX_CapsLock
;
1789 case KEY_NAME_INDEX_HiraganaKatakana
:
1790 return CODE_NAME_INDEX_KanaMode
;
1791 case KEY_NAME_INDEX_ZenkakuHankaku
:
1792 return CODE_NAME_INDEX_Backquote
;
1793 #endif // #ifdef MOZ_WIDGET_GTK
1796 case KEY_NAME_INDEX_Convert
:
1797 return CODE_NAME_INDEX_Convert
;
1798 case KEY_NAME_INDEX_NonConvert
:
1799 return CODE_NAME_INDEX_NonConvert
;
1800 case KEY_NAME_INDEX_HiraganaKatakana
:
1801 return CODE_NAME_INDEX_KanaMode
;
1802 case KEY_NAME_INDEX_ZenkakuHankaku
:
1803 return CODE_NAME_INDEX_Backquote
;
1804 case KEY_NAME_INDEX_Eisu
:
1805 return CODE_NAME_INDEX_Lang2
;
1806 case KEY_NAME_INDEX_KanjiMode
:
1807 return CODE_NAME_INDEX_Lang1
;
1808 #endif // #ifdef ANDROID
1811 case KEY_NAME_INDEX_Eisu
:
1812 return CODE_NAME_INDEX_Lang2
;
1813 case KEY_NAME_INDEX_KanjiMode
:
1814 return CODE_NAME_INDEX_Lang1
;
1815 #endif // #ifdef XP_MACOSX
1818 return CODE_NAME_INDEX_UNKNOWN
;
1823 Modifier
WidgetKeyboardEvent::GetModifierForKeyName(
1824 KeyNameIndex aKeyNameIndex
) {
1825 switch (aKeyNameIndex
) {
1826 case KEY_NAME_INDEX_Alt
:
1827 return MODIFIER_ALT
;
1828 case KEY_NAME_INDEX_AltGraph
:
1829 return MODIFIER_ALTGRAPH
;
1830 case KEY_NAME_INDEX_CapsLock
:
1831 return MODIFIER_CAPSLOCK
;
1832 case KEY_NAME_INDEX_Control
:
1833 return MODIFIER_CONTROL
;
1834 case KEY_NAME_INDEX_Fn
:
1836 case KEY_NAME_INDEX_FnLock
:
1837 return MODIFIER_FNLOCK
;
1838 // case KEY_NAME_INDEX_Hyper:
1839 case KEY_NAME_INDEX_Meta
:
1840 return MODIFIER_META
;
1841 case KEY_NAME_INDEX_NumLock
:
1842 return MODIFIER_NUMLOCK
;
1843 case KEY_NAME_INDEX_OS
:
1845 case KEY_NAME_INDEX_ScrollLock
:
1846 return MODIFIER_SCROLLLOCK
;
1847 case KEY_NAME_INDEX_Shift
:
1848 return MODIFIER_SHIFT
;
1849 // case KEY_NAME_INDEX_Super:
1850 case KEY_NAME_INDEX_Symbol
:
1851 return MODIFIER_SYMBOL
;
1852 case KEY_NAME_INDEX_SymbolLock
:
1853 return MODIFIER_SYMBOLLOCK
;
1855 return MODIFIER_NONE
;
1860 bool WidgetKeyboardEvent::IsLockableModifier(KeyNameIndex aKeyNameIndex
) {
1861 switch (aKeyNameIndex
) {
1862 case KEY_NAME_INDEX_CapsLock
:
1863 case KEY_NAME_INDEX_FnLock
:
1864 case KEY_NAME_INDEX_NumLock
:
1865 case KEY_NAME_INDEX_ScrollLock
:
1866 case KEY_NAME_INDEX_SymbolLock
:
1873 /******************************************************************************
1874 * mozilla::InternalEditorInputEvent (TextEvents.h)
1875 ******************************************************************************/
1877 #define NS_DEFINE_INPUTTYPE(aCPPName, aDOMName) (u"" aDOMName),
1878 const char16_t
* const InternalEditorInputEvent::kInputTypeNames
[] = {
1879 #include "mozilla/InputTypeList.h"
1881 #undef NS_DEFINE_INPUTTYPE
1883 InternalEditorInputEvent::InputTypeHashtable
*
1884 InternalEditorInputEvent::sInputTypeHashtable
= nullptr;
1887 void InternalEditorInputEvent::Shutdown() {
1888 delete sInputTypeHashtable
;
1889 sInputTypeHashtable
= nullptr;
1893 void InternalEditorInputEvent::GetDOMInputTypeName(EditorInputType aInputType
,
1894 nsAString
& aInputTypeName
) {
1895 if (static_cast<size_t>(aInputType
) >=
1896 static_cast<size_t>(EditorInputType::eUnknown
)) {
1897 aInputTypeName
.Truncate();
1902 static_cast<size_t>(aInputType
) < ArrayLength(kInputTypeNames
),
1903 "Illegal input type enumeration value");
1904 aInputTypeName
.Assign(kInputTypeNames
[static_cast<size_t>(aInputType
)]);
1908 EditorInputType
InternalEditorInputEvent::GetEditorInputType(
1909 const nsAString
& aInputType
) {
1910 if (aInputType
.IsEmpty()) {
1911 return EditorInputType::eUnknown
;
1914 if (!sInputTypeHashtable
) {
1915 sInputTypeHashtable
= new InputTypeHashtable(ArrayLength(kInputTypeNames
));
1916 for (size_t i
= 0; i
< ArrayLength(kInputTypeNames
); i
++) {
1917 sInputTypeHashtable
->InsertOrUpdate(nsDependentString(kInputTypeNames
[i
]),
1918 static_cast<EditorInputType
>(i
));
1921 return sInputTypeHashtable
->MaybeGet(aInputType
)
1922 .valueOr(EditorInputType::eUnknown
);
1925 } // namespace mozilla