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 "winnetwk.h"
34 # include "WinUtils.h"
35 #endif // #if defined (XP_WIN)
37 #if defined(MOZ_WIDGET_GTK) || defined(XP_MACOSX)
38 # include "NativeKeyBindings.h"
39 #endif // #if defined(MOZ_WIDGET_GTK) || defined(XP_MACOSX)
43 /******************************************************************************
44 * Global helper methods
45 ******************************************************************************/
47 const char* ToChar(EventMessage aEventMessage
) {
48 switch (aEventMessage
) {
49 #define NS_EVENT_MESSAGE(aMessage) \
53 #include "mozilla/EventMessageList.h"
55 #undef NS_EVENT_MESSAGE
57 return "illegal event message";
61 const char* ToChar(EventClassID aEventClassID
) {
62 switch (aEventClassID
) {
63 #define NS_ROOT_EVENT_CLASS(aPrefix, aName) \
64 case eBasic##aName##Class: \
65 return "eBasic" #aName "Class";
67 #define NS_EVENT_CLASS(aPrefix, aName) \
68 case e##aName##Class: \
69 return "e" #aName "Class";
71 #include "mozilla/EventClassList.h"
74 #undef NS_ROOT_EVENT_CLASS
76 return "illegal event class ID";
80 const nsCString
ToString(KeyNameIndex aKeyNameIndex
) {
81 if (aKeyNameIndex
== KEY_NAME_INDEX_USE_STRING
) {
82 return "USE_STRING"_ns
;
85 WidgetKeyboardEvent::GetDOMKeyName(aKeyNameIndex
, keyName
);
86 return NS_ConvertUTF16toUTF8(keyName
);
89 const nsCString
ToString(CodeNameIndex aCodeNameIndex
) {
90 if (aCodeNameIndex
== CODE_NAME_INDEX_USE_STRING
) {
91 return "USE_STRING"_ns
;
93 nsAutoString codeName
;
94 WidgetKeyboardEvent::GetDOMCodeName(aCodeNameIndex
, codeName
);
95 return NS_ConvertUTF16toUTF8(codeName
);
98 const char* ToChar(Command aCommand
) {
99 if (aCommand
== Command::DoNothing
) {
100 return "CommandDoNothing";
104 #define NS_DEFINE_COMMAND(aName, aCommandStr) \
105 case Command::aName: \
106 return "Command::" #aName;
107 #define NS_DEFINE_COMMAND_WITH_PARAM(aName, aCommandStr, aParam) \
108 case Command::aName: \
109 return "Command::" #aName;
110 #define NS_DEFINE_COMMAND_NO_EXEC_COMMAND(aName) \
111 case Command::aName: \
112 return "Command::" #aName;
114 #include "mozilla/CommandList.h"
116 #undef NS_DEFINE_COMMAND
117 #undef NS_DEFINE_COMMAND_WITH_PARAM
118 #undef NS_DEFINE_COMMAND_NO_EXEC_COMMAND
121 return "illegal command value";
125 const nsCString
GetDOMKeyCodeName(uint32_t aKeyCode
) {
127 #define NS_DISALLOW_SAME_KEYCODE
128 #define NS_DEFINE_VK(aDOMKeyName, aDOMKeyCode) \
130 return nsLiteralCString(#aDOMKeyName);
132 #include "mozilla/VirtualKeyCodeList.h"
135 #undef NS_DISALLOW_SAME_KEYCODE
138 return nsPrintfCString("Invalid DOM keyCode (0x%08X)", aKeyCode
);
142 bool IsValidRawTextRangeValue(RawTextRangeType aRawTextRangeType
) {
143 switch (static_cast<TextRangeType
>(aRawTextRangeType
)) {
144 case TextRangeType::eUninitialized
:
145 case TextRangeType::eCaret
:
146 case TextRangeType::eRawClause
:
147 case TextRangeType::eSelectedRawClause
:
148 case TextRangeType::eConvertedClause
:
149 case TextRangeType::eSelectedClause
:
156 RawTextRangeType
ToRawTextRangeType(TextRangeType aTextRangeType
) {
157 return static_cast<RawTextRangeType
>(aTextRangeType
);
160 TextRangeType
ToTextRangeType(RawTextRangeType aRawTextRangeType
) {
161 MOZ_ASSERT(IsValidRawTextRangeValue(aRawTextRangeType
));
162 return static_cast<TextRangeType
>(aRawTextRangeType
);
165 const char* ToChar(TextRangeType aTextRangeType
) {
166 switch (aTextRangeType
) {
167 case TextRangeType::eUninitialized
:
168 return "TextRangeType::eUninitialized";
169 case TextRangeType::eCaret
:
170 return "TextRangeType::eCaret";
171 case TextRangeType::eRawClause
:
172 return "TextRangeType::eRawClause";
173 case TextRangeType::eSelectedRawClause
:
174 return "TextRangeType::eSelectedRawClause";
175 case TextRangeType::eConvertedClause
:
176 return "TextRangeType::eConvertedClause";
177 case TextRangeType::eSelectedClause
:
178 return "TextRangeType::eSelectedClause";
180 return "Invalid TextRangeType";
184 SelectionType
ToSelectionType(TextRangeType aTextRangeType
) {
185 switch (aTextRangeType
) {
186 case TextRangeType::eRawClause
:
187 return SelectionType::eIMERawClause
;
188 case TextRangeType::eSelectedRawClause
:
189 return SelectionType::eIMESelectedRawClause
;
190 case TextRangeType::eConvertedClause
:
191 return SelectionType::eIMEConvertedClause
;
192 case TextRangeType::eSelectedClause
:
193 return SelectionType::eIMESelectedClause
;
195 MOZ_CRASH("TextRangeType is invalid");
196 return SelectionType::eNormal
;
200 /******************************************************************************
201 * non class method implementation
202 ******************************************************************************/
204 static nsTHashMap
<nsDepCharHashKey
, Command
>* sCommandHashtable
= nullptr;
206 Command
GetInternalCommand(const char* aCommandName
,
207 const nsCommandParams
* aCommandParams
) {
209 return Command::DoNothing
;
212 // Special cases for "cmd_align". It's mapped to multiple internal commands
213 // with additional param. Therefore, we cannot handle it with the hashtable.
214 if (!strcmp(aCommandName
, "cmd_align")) {
215 if (!aCommandParams
) {
216 // Note that if this is called by EditorCommand::IsCommandEnabled(),
217 // it cannot set aCommandParams. So, don't warn in this case even though
218 // this is illegal case for DoCommandParams().
219 return Command::FormatJustify
;
221 nsAutoCString cValue
;
222 nsresult rv
= aCommandParams
->GetCString("state_attribute", cValue
);
224 nsString value
; // Avoid copying the string buffer with using nsString.
225 rv
= aCommandParams
->GetString("state_attribute", value
);
227 return Command::FormatJustifyNone
;
229 CopyUTF16toUTF8(value
, cValue
);
231 if (cValue
.LowerCaseEqualsASCII("left")) {
232 return Command::FormatJustifyLeft
;
234 if (cValue
.LowerCaseEqualsASCII("right")) {
235 return Command::FormatJustifyRight
;
237 if (cValue
.LowerCaseEqualsASCII("center")) {
238 return Command::FormatJustifyCenter
;
240 if (cValue
.LowerCaseEqualsASCII("justify")) {
241 return Command::FormatJustifyFull
;
243 if (cValue
.IsEmpty()) {
244 return Command::FormatJustifyNone
;
246 return Command::DoNothing
;
249 if (!sCommandHashtable
) {
250 sCommandHashtable
= new nsTHashMap
<nsDepCharHashKey
, Command
>();
251 #define NS_DEFINE_COMMAND(aName, aCommandStr) \
252 sCommandHashtable->InsertOrUpdate(#aCommandStr, Command::aName);
254 #define NS_DEFINE_COMMAND_WITH_PARAM(aName, aCommandStr, aParam)
256 #define NS_DEFINE_COMMAND_NO_EXEC_COMMAND(aName)
258 #include "mozilla/CommandList.h"
260 #undef NS_DEFINE_COMMAND
261 #undef NS_DEFINE_COMMAND_WITH_PARAM
262 #undef NS_DEFINE_COMMAND_NO_EXEC_COMMAND
264 Command command
= Command::DoNothing
;
265 if (!sCommandHashtable
->Get(aCommandName
, &command
)) {
266 return Command::DoNothing
;
271 /******************************************************************************
272 * As*Event() implementation
273 ******************************************************************************/
275 #define NS_ROOT_EVENT_CLASS(aPrefix, aName)
276 #define NS_EVENT_CLASS(aPrefix, aName) \
277 aPrefix##aName* WidgetEvent::As##aName() { return nullptr; } \
279 const aPrefix##aName* WidgetEvent::As##aName() const { \
280 return const_cast<WidgetEvent*>(this)->As##aName(); \
283 #include "mozilla/EventClassList.h"
285 #undef NS_EVENT_CLASS
286 #undef NS_ROOT_EVENT_CLASS
288 /******************************************************************************
289 * mozilla::WidgetEvent
291 * Event struct type checking methods.
292 ******************************************************************************/
294 bool WidgetEvent::IsQueryContentEvent() const {
295 return mClass
== eQueryContentEventClass
;
298 bool WidgetEvent::IsSelectionEvent() const {
299 return mClass
== eSelectionEventClass
;
302 bool WidgetEvent::IsContentCommandEvent() const {
303 return mClass
== eContentCommandEventClass
;
306 /******************************************************************************
307 * mozilla::WidgetEvent
309 * Event message checking methods.
310 ******************************************************************************/
312 bool WidgetEvent::HasMouseEventMessage() const {
317 case eMouseDoubleClick
:
319 case eMouseEnterIntoWidget
:
320 case eMouseExitFromWidget
:
332 bool WidgetEvent::HasDragEventMessage() const {
349 bool WidgetEvent::IsKeyEventMessage(EventMessage aMessage
) {
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 /******************************************************************************
376 * mozilla::WidgetEvent
378 * Specific event checking methods.
379 ******************************************************************************/
381 bool WidgetEvent::CanBeSentToRemoteProcess() const {
382 // If this event is explicitly marked as shouldn't be sent to remote process,
383 // just return false.
384 if (IsCrossProcessForwardingStopped()) {
388 if (mClass
== eKeyboardEventClass
|| mClass
== eWheelEventClass
) {
396 case eMouseExploreByTouch
:
398 case eMouseEnterIntoWidget
:
399 case eMouseExitFromWidget
:
400 case eMouseTouchDrag
:
414 bool WidgetEvent::WillBeSentToRemoteProcess() const {
415 // This event won't be posted to remote process if it's already explicitly
417 if (IsCrossProcessForwardingStopped()) {
421 // When mOriginalTarget is nullptr, this method shouldn't be used.
422 if (NS_WARN_IF(!mOriginalTarget
)) {
426 return EventStateManager::IsTopLevelRemoteTarget(
427 nsIContent::FromEventTarget(mOriginalTarget
));
430 bool WidgetEvent::IsIMERelatedEvent() const {
431 return HasIMEEventMessage() || IsQueryContentEvent() || IsSelectionEvent();
434 bool WidgetEvent::IsUsingCoordinates() const {
435 const WidgetMouseEvent
* mouseEvent
= AsMouseEvent();
437 return !mouseEvent
->IsContextMenuKeyEvent();
439 return !HasKeyEventMessage() && !IsIMERelatedEvent() &&
440 !IsContentCommandEvent();
443 bool WidgetEvent::IsTargetedAtFocusedWindow() const {
444 const WidgetMouseEvent
* mouseEvent
= AsMouseEvent();
446 return mouseEvent
->IsContextMenuKeyEvent();
448 return HasKeyEventMessage() || IsIMERelatedEvent() || IsContentCommandEvent();
451 bool WidgetEvent::IsTargetedAtFocusedContent() const {
452 const WidgetMouseEvent
* mouseEvent
= AsMouseEvent();
454 return mouseEvent
->IsContextMenuKeyEvent();
456 return HasKeyEventMessage() || IsIMERelatedEvent();
459 bool WidgetEvent::IsAllowedToDispatchDOMEvent() const {
461 case eMouseEventClass
:
462 if (mMessage
== eMouseTouchDrag
) {
466 case ePointerEventClass
:
467 // We want synthesized mouse moves to cause mouseover and mouseout
468 // DOM events (EventStateManager::PreHandleEvent), but not mousemove
470 // Synthesized button up events also do not cause DOM events because they
471 // do not have a reliable mRefPoint.
472 return AsMouseEvent()->mReason
== WidgetMouseEvent::eReal
;
474 case eWheelEventClass
: {
475 // wheel event whose all delta values are zero by user pref applied, it
476 // shouldn't cause a DOM event.
477 const WidgetWheelEvent
* wheelEvent
= AsWheelEvent();
478 return wheelEvent
->mDeltaX
!= 0.0 || wheelEvent
->mDeltaY
!= 0.0 ||
479 wheelEvent
->mDeltaZ
!= 0.0;
481 case eTouchEventClass
:
482 return mMessage
!= eTouchPointerCancel
;
483 // Following events are handled in EventStateManager, so, we don't need to
484 // dispatch DOM event for them into the DOM tree.
485 case eQueryContentEventClass
:
486 case eSelectionEventClass
:
487 case eContentCommandEventClass
:
495 bool WidgetEvent::IsAllowedToDispatchInSystemGroup() const {
496 // We don't expect to implement default behaviors with pointer events because
497 // if we do, prevent default on mouse events can't prevent default behaviors
499 return mClass
!= ePointerEventClass
;
502 bool WidgetEvent::IsBlockedForFingerprintingResistance() const {
504 case eKeyboardEventClass
: {
505 const WidgetKeyboardEvent
* keyboardEvent
= AsKeyboardEvent();
507 return (keyboardEvent
->mKeyNameIndex
== KEY_NAME_INDEX_Alt
||
508 keyboardEvent
->mKeyNameIndex
== KEY_NAME_INDEX_Shift
||
509 keyboardEvent
->mKeyNameIndex
== KEY_NAME_INDEX_Control
||
510 keyboardEvent
->mKeyNameIndex
== KEY_NAME_INDEX_AltGraph
);
512 case ePointerEventClass
: {
513 const WidgetPointerEvent
* pointerEvent
= AsPointerEvent();
515 // We suppress the pointer events if it is not primary for fingerprinting
516 // resistance. It is because of that we want to spoof any pointer event
517 // into a mouse pointer event and the mouse pointer event only has
518 // isPrimary as true.
519 return !pointerEvent
->mIsPrimary
;
526 /******************************************************************************
527 * mozilla::WidgetEvent
530 ******************************************************************************/
532 static dom::EventTarget
* GetTargetForDOMEvent(dom::EventTarget
* aTarget
) {
533 return aTarget
? aTarget
->GetTargetForDOMEvent() : nullptr;
536 dom::EventTarget
* WidgetEvent::GetDOMEventTarget() const {
537 return GetTargetForDOMEvent(mTarget
);
540 dom::EventTarget
* WidgetEvent::GetCurrentDOMEventTarget() const {
541 return GetTargetForDOMEvent(mCurrentTarget
);
544 dom::EventTarget
* WidgetEvent::GetOriginalDOMEventTarget() const {
545 if (mOriginalTarget
) {
546 return GetTargetForDOMEvent(mOriginalTarget
);
548 return GetDOMEventTarget();
551 void WidgetEvent::PreventDefault(bool aCalledByDefaultHandler
,
552 nsIPrincipal
* aPrincipal
) {
553 if (mMessage
== ePointerDown
) {
554 if (aCalledByDefaultHandler
) {
555 // Shouldn't prevent default on pointerdown by default handlers to stop
556 // firing legacy mouse events. Use MOZ_ASSERT to catch incorrect usages
562 nsAutoString addonId
;
563 Unused
<< NS_WARN_IF(NS_FAILED(aPrincipal
->GetAddonId(addonId
)));
564 if (!addonId
.IsEmpty()) {
565 // Ignore the case that it's called by a web extension.
570 mFlags
.PreventDefault(aCalledByDefaultHandler
);
573 bool WidgetEvent::IsUserAction() const {
577 // FYI: eMouseScrollEventClass and ePointerEventClass represent
578 // user action but they are synthesized events.
580 case eKeyboardEventClass
:
581 case eCompositionEventClass
:
582 case eMouseScrollEventClass
:
583 case eWheelEventClass
:
584 case eGestureNotifyEventClass
:
585 case eSimpleGestureEventClass
:
586 case eTouchEventClass
:
587 case eCommandEventClass
:
588 case eContentCommandEventClass
:
590 case eMouseEventClass
:
591 case eDragEventClass
:
592 case ePointerEventClass
:
593 return AsMouseEvent()->IsReal();
599 /******************************************************************************
600 * mozilla::WidgetInputEvent
601 ******************************************************************************/
604 Modifier
WidgetInputEvent::GetModifier(const nsAString
& aDOMKeyName
) {
605 if (aDOMKeyName
.EqualsLiteral("Accel")) {
606 return AccelModifier();
608 KeyNameIndex keyNameIndex
= WidgetKeyboardEvent::GetKeyNameIndex(aDOMKeyName
);
609 return WidgetKeyboardEvent::GetModifierForKeyName(keyNameIndex
);
613 Modifier
WidgetInputEvent::AccelModifier() {
614 static Modifier sAccelModifier
= MODIFIER_NONE
;
615 if (sAccelModifier
== MODIFIER_NONE
) {
616 switch (StaticPrefs::ui_key_accelKey()) {
617 case dom::KeyboardEvent_Binding::DOM_VK_META
:
618 sAccelModifier
= MODIFIER_META
;
620 case dom::KeyboardEvent_Binding::DOM_VK_WIN
:
621 sAccelModifier
= MODIFIER_OS
;
623 case dom::KeyboardEvent_Binding::DOM_VK_ALT
:
624 sAccelModifier
= MODIFIER_ALT
;
626 case dom::KeyboardEvent_Binding::DOM_VK_CONTROL
:
627 sAccelModifier
= MODIFIER_CONTROL
;
631 sAccelModifier
= MODIFIER_META
;
633 sAccelModifier
= MODIFIER_CONTROL
;
638 return sAccelModifier
;
641 /******************************************************************************
642 * mozilla::WidgetMouseEvent (MouseEvents.h)
643 ******************************************************************************/
646 bool WidgetMouseEvent::IsMiddleClickPasteEnabled() {
647 return Preferences::GetBool("middlemouse.paste", false);
651 void WidgetMouseEvent::AssertContextMenuEventButtonConsistency() const {
652 if (mMessage
!= eContextMenu
) {
656 if (mContextMenuTrigger
== eNormal
) {
657 NS_WARNING_ASSERTION(mButton
== MouseButton::eSecondary
,
658 "eContextMenu events with eNormal trigger should use "
659 "secondary mouse button");
661 NS_WARNING_ASSERTION(mButton
== MouseButton::ePrimary
,
662 "eContextMenu events with non-eNormal trigger should "
663 "use primary mouse button");
666 if (mContextMenuTrigger
== eControlClick
) {
667 NS_WARNING_ASSERTION(IsControl(),
668 "eContextMenu events with eControlClick trigger "
669 "should return true from IsControl()");
674 /******************************************************************************
675 * mozilla::WidgetDragEvent (MouseEvents.h)
676 ******************************************************************************/
678 void WidgetDragEvent::InitDropEffectForTests() {
679 MOZ_ASSERT(mFlags
.mIsSynthesizedForTests
);
681 nsCOMPtr
<nsIDragSession
> session
= nsContentUtils::GetDragSession();
682 if (NS_WARN_IF(!session
)) {
686 uint32_t effectAllowed
= session
->GetEffectAllowedForTests();
687 uint32_t desiredDropEffect
= nsIDragService::DRAGDROP_ACTION_NONE
;
690 desiredDropEffect
= IsMeta() ? nsIDragService::DRAGDROP_ACTION_LINK
691 : nsIDragService::DRAGDROP_ACTION_COPY
;
694 // On Linux, we know user's intention from API, but we should use
695 // same modifiers as Windows for tests because GNOME on Ubuntu use
696 // them and that makes each test simpler.
698 desiredDropEffect
= IsShift() ? nsIDragService::DRAGDROP_ACTION_LINK
699 : nsIDragService::DRAGDROP_ACTION_COPY
;
700 } else if (IsShift()) {
701 desiredDropEffect
= nsIDragService::DRAGDROP_ACTION_MOVE
;
703 #endif // #ifdef XP_MACOSX #else
704 // First, use modifier state for preferring action which is explicitly
705 // specified by the synthesizer.
706 if (!(desiredDropEffect
&= effectAllowed
)) {
707 // Otherwise, use an action which is allowed at starting the session.
708 desiredDropEffect
= effectAllowed
;
710 if (desiredDropEffect
& nsIDragService::DRAGDROP_ACTION_MOVE
) {
711 session
->SetDragAction(nsIDragService::DRAGDROP_ACTION_MOVE
);
712 } else if (desiredDropEffect
& nsIDragService::DRAGDROP_ACTION_COPY
) {
713 session
->SetDragAction(nsIDragService::DRAGDROP_ACTION_COPY
);
714 } else if (desiredDropEffect
& nsIDragService::DRAGDROP_ACTION_LINK
) {
715 session
->SetDragAction(nsIDragService::DRAGDROP_ACTION_LINK
);
717 session
->SetDragAction(nsIDragService::DRAGDROP_ACTION_NONE
);
721 /******************************************************************************
722 * mozilla::WidgetWheelEvent (MouseEvents.h)
723 ******************************************************************************/
726 double WidgetWheelEvent::ComputeOverriddenDelta(double aDelta
,
727 bool aIsForVertical
) {
728 if (!StaticPrefs::mousewheel_system_scroll_override_enabled()) {
733 ? StaticPrefs::mousewheel_system_scroll_override_vertical_factor()
734 : StaticPrefs::mousewheel_system_scroll_override_horizontal_factor();
735 // Making the scroll speed slower doesn't make sense. So, ignore odd factor
736 // which is less than 1.0.
737 if (intFactor
<= 100) {
740 double factor
= static_cast<double>(intFactor
) / 100;
741 return aDelta
* factor
;
744 double WidgetWheelEvent::OverriddenDeltaX() const {
745 if (!mAllowToOverrideSystemScrollSpeed
||
746 mDeltaMode
!= dom::WheelEvent_Binding::DOM_DELTA_LINE
||
747 mCustomizedByUserPrefs
) {
750 return ComputeOverriddenDelta(mDeltaX
, false);
753 double WidgetWheelEvent::OverriddenDeltaY() const {
754 if (!mAllowToOverrideSystemScrollSpeed
||
755 mDeltaMode
!= dom::WheelEvent_Binding::DOM_DELTA_LINE
||
756 mCustomizedByUserPrefs
) {
759 return ComputeOverriddenDelta(mDeltaY
, true);
762 /******************************************************************************
763 * mozilla::WidgetKeyboardEvent (TextEvents.h)
764 ******************************************************************************/
766 #define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) (u"" aDOMKeyName),
767 const char16_t
* const WidgetKeyboardEvent::kKeyNames
[] = {
768 #include "mozilla/KeyNameList.h"
770 #undef NS_DEFINE_KEYNAME
772 #define NS_DEFINE_PHYSICAL_KEY_CODE_NAME(aCPPName, aDOMCodeName) \
774 const char16_t
* const WidgetKeyboardEvent::kCodeNames
[] = {
775 #include "mozilla/PhysicalKeyCodeNameList.h"
777 #undef NS_DEFINE_PHYSICAL_KEY_CODE_NAME
779 WidgetKeyboardEvent::KeyNameIndexHashtable
*
780 WidgetKeyboardEvent::sKeyNameIndexHashtable
= nullptr;
781 WidgetKeyboardEvent::CodeNameIndexHashtable
*
782 WidgetKeyboardEvent::sCodeNameIndexHashtable
= nullptr;
784 void WidgetKeyboardEvent::InitAllEditCommands(
785 const Maybe
<WritingMode
>& aWritingMode
) {
786 // If this event is synthesized for tests, we don't need to retrieve the
787 // command via the main process. So, we don't need widget and can trust
789 if (!mFlags
.mIsSynthesizedForTests
) {
790 // If the event was created without widget, e.g., created event in chrome
791 // script, this shouldn't execute native key bindings.
792 if (NS_WARN_IF(!mWidget
)) {
796 // This event should be trusted event here and we shouldn't expose native
797 // key binding information to web contents with untrusted events.
798 if (NS_WARN_IF(!IsTrusted())) {
803 XRE_IsParentProcess(),
804 "It's too expensive to retrieve all edit commands from remote process");
805 MOZ_ASSERT(!AreAllEditCommandsInitialized(),
806 "Shouldn't be called two or more times");
809 DebugOnly
<bool> okIgnored
= InitEditCommandsFor(
810 NativeKeyBindingsType::SingleLineEditor
, aWritingMode
);
811 NS_WARNING_ASSERTION(okIgnored
,
812 "InitEditCommandsFor(NativeKeyBindingsType::"
813 "SingleLineEditor) failed, but ignored");
815 InitEditCommandsFor(NativeKeyBindingsType::MultiLineEditor
, aWritingMode
);
816 NS_WARNING_ASSERTION(okIgnored
,
817 "InitEditCommandsFor(NativeKeyBindingsType::"
818 "MultiLineEditor) failed, but ignored");
820 InitEditCommandsFor(NativeKeyBindingsType::RichTextEditor
, aWritingMode
);
821 NS_WARNING_ASSERTION(okIgnored
,
822 "InitEditCommandsFor(NativeKeyBindingsType::"
823 "RichTextEditor) failed, but ignored");
826 bool WidgetKeyboardEvent::InitEditCommandsFor(
827 NativeKeyBindingsType aType
, const Maybe
<WritingMode
>& aWritingMode
) {
828 bool& initialized
= IsEditCommandsInitializedRef(aType
);
832 nsTArray
<CommandInt
>& commands
= EditCommandsRef(aType
);
834 // If this event is synthesized for tests, we shouldn't access customized
835 // shortcut settings of the environment. Therefore, we don't need to check
836 // whether `widget` is set or not. And we can treat synthesized events are
838 if (mFlags
.mIsSynthesizedForTests
) {
839 MOZ_DIAGNOSTIC_ASSERT(IsTrusted());
840 #if defined(MOZ_WIDGET_GTK) || defined(XP_MACOSX)
841 // TODO: We should implement `NativeKeyBindings` for Windows and Android
842 // too in bug 1301497 for getting rid of the #if.
843 widget::NativeKeyBindings::GetEditCommandsForTests(aType
, *this,
844 aWritingMode
, commands
);
850 if (NS_WARN_IF(!mWidget
) || NS_WARN_IF(!IsTrusted())) {
853 // `nsIWidget::GetEditCommands()` will retrieve `WritingMode` at selection
854 // again, but it should be almost zero-cost since `TextEventDispatcher`
856 nsCOMPtr
<nsIWidget
> widget
= mWidget
;
857 initialized
= widget
->GetEditCommands(aType
, *this, commands
);
861 bool WidgetKeyboardEvent::ExecuteEditCommands(NativeKeyBindingsType aType
,
862 DoCommandCallback aCallback
,
863 void* aCallbackData
) {
864 // If the event was created without widget, e.g., created event in chrome
865 // script, this shouldn't execute native key bindings.
866 if (NS_WARN_IF(!mWidget
)) {
870 // This event should be trusted event here and we shouldn't expose native
871 // key binding information to web contents with untrusted events.
872 if (NS_WARN_IF(!IsTrusted())) {
876 if (!IsEditCommandsInitializedRef(aType
)) {
877 Maybe
<WritingMode
> writingMode
;
878 if (RefPtr
<widget::TextEventDispatcher
> textEventDispatcher
=
879 mWidget
->GetTextEventDispatcher()) {
880 writingMode
= textEventDispatcher
->MaybeQueryWritingModeAtSelection();
882 if (NS_WARN_IF(!InitEditCommandsFor(aType
, writingMode
))) {
887 const nsTArray
<CommandInt
>& commands
= EditCommandsRef(aType
);
888 if (commands
.IsEmpty()) {
892 for (CommandInt command
: commands
) {
893 aCallback(static_cast<Command
>(command
), aCallbackData
);
898 bool WidgetKeyboardEvent::ShouldCauseKeypressEvents() const {
899 // Currently, we don't dispatch keypress events of modifier keys and
901 switch (mKeyNameIndex
) {
902 case KEY_NAME_INDEX_Alt
:
903 case KEY_NAME_INDEX_AltGraph
:
904 case KEY_NAME_INDEX_CapsLock
:
905 case KEY_NAME_INDEX_Control
:
906 case KEY_NAME_INDEX_Fn
:
907 case KEY_NAME_INDEX_FnLock
:
908 // case KEY_NAME_INDEX_Hyper:
909 case KEY_NAME_INDEX_Meta
:
910 case KEY_NAME_INDEX_NumLock
:
911 case KEY_NAME_INDEX_OS
:
912 case KEY_NAME_INDEX_ScrollLock
:
913 case KEY_NAME_INDEX_Shift
:
914 // case KEY_NAME_INDEX_Super:
915 case KEY_NAME_INDEX_Symbol
:
916 case KEY_NAME_INDEX_SymbolLock
:
917 case KEY_NAME_INDEX_Dead
:
924 static bool HasASCIIDigit(const ShortcutKeyCandidateArray
& aCandidates
) {
925 for (uint32_t i
= 0; i
< aCandidates
.Length(); ++i
) {
926 uint32_t ch
= aCandidates
[i
].mCharCode
;
927 if (ch
>= '0' && ch
<= '9') return true;
932 static bool CharsCaseInsensitiveEqual(uint32_t aChar1
, uint32_t aChar2
) {
933 return aChar1
== aChar2
|| (IS_IN_BMP(aChar1
) && IS_IN_BMP(aChar2
) &&
934 ToLowerCase(static_cast<char16_t
>(aChar1
)) ==
935 ToLowerCase(static_cast<char16_t
>(aChar2
)));
938 static bool IsCaseChangeableChar(uint32_t aChar
) {
939 return IS_IN_BMP(aChar
) && ToLowerCase(static_cast<char16_t
>(aChar
)) !=
940 ToUpperCase(static_cast<char16_t
>(aChar
));
943 void WidgetKeyboardEvent::GetShortcutKeyCandidates(
944 ShortcutKeyCandidateArray
& aCandidates
) const {
945 MOZ_ASSERT(aCandidates
.IsEmpty(), "aCandidates must be empty");
947 // ShortcutKeyCandidate::mCharCode is a candidate charCode.
948 // ShortcutKeyCandidate::mIgnoreShift means the mCharCode should be tried to
949 // execute a command with/without shift key state. If this is TRUE, the
950 // shifted key state should be ignored. Otherwise, don't ignore the state.
951 // the priority of the charCodes are (shift key is not pressed):
952 // 0: PseudoCharCode()/false,
953 // 1: unshiftedCharCodes[0]/false, 2: unshiftedCharCodes[1]/false...
954 // the priority of the charCodes are (shift key is pressed):
955 // 0: PseudoCharCode()/false,
956 // 1: shiftedCharCodes[0]/false, 2: shiftedCharCodes[0]/true,
957 // 3: shiftedCharCodes[1]/false, 4: shiftedCharCodes[1]/true...
958 uint32_t pseudoCharCode
= PseudoCharCode();
959 if (pseudoCharCode
) {
960 ShortcutKeyCandidate
key(pseudoCharCode
, false);
961 aCandidates
.AppendElement(key
);
964 uint32_t len
= mAlternativeCharCodes
.Length();
966 for (uint32_t i
= 0; i
< len
; ++i
) {
967 uint32_t ch
= mAlternativeCharCodes
[i
].mUnshiftedCharCode
;
968 if (!ch
|| ch
== pseudoCharCode
) {
971 ShortcutKeyCandidate
key(ch
, false);
972 aCandidates
.AppendElement(key
);
974 // If unshiftedCharCodes doesn't have numeric but shiftedCharCode has it,
975 // this keyboard layout is AZERTY or similar layout, probably.
976 // In this case, Accel+[0-9] should be accessible without shift key.
977 // However, the priority should be lowest.
978 if (!HasASCIIDigit(aCandidates
)) {
979 for (uint32_t i
= 0; i
< len
; ++i
) {
980 uint32_t ch
= mAlternativeCharCodes
[i
].mShiftedCharCode
;
981 if (ch
>= '0' && ch
<= '9') {
982 ShortcutKeyCandidate
key(ch
, false);
983 aCandidates
.AppendElement(key
);
989 for (uint32_t i
= 0; i
< len
; ++i
) {
990 uint32_t ch
= mAlternativeCharCodes
[i
].mShiftedCharCode
;
995 if (ch
!= pseudoCharCode
) {
996 ShortcutKeyCandidate
key(ch
, false);
997 aCandidates
.AppendElement(key
);
1000 // If the char is an alphabet, the shift key state should not be
1001 // ignored. E.g., Ctrl+Shift+C should not execute Ctrl+C.
1003 // And checking the charCode is same as unshiftedCharCode too.
1004 // E.g., for Ctrl+Shift+(Plus of Numpad) should not run Ctrl+Plus.
1005 uint32_t unshiftCh
= mAlternativeCharCodes
[i
].mUnshiftedCharCode
;
1006 if (CharsCaseInsensitiveEqual(ch
, unshiftCh
)) {
1010 // On the Hebrew keyboard layout on Windows, the unshifted char is a
1011 // localized character but the shifted char is a Latin alphabet,
1012 // then, we should not execute without the shift state. See bug 433192.
1013 if (IsCaseChangeableChar(ch
)) {
1017 // Setting the alternative charCode candidates for retry without shift
1018 // key state only when the shift key is pressed.
1019 ShortcutKeyCandidate
key(ch
, true);
1020 aCandidates
.AppendElement(key
);
1024 // Special case for "Space" key. With some keyboard layouts, "Space" with
1025 // or without Shift key causes non-ASCII space. For such keyboard layouts,
1026 // we should guarantee that the key press works as an ASCII white space key
1027 // press. However, if the space key is assigned to a function key, it
1028 // shouldn't work as a space key.
1029 if (mKeyNameIndex
== KEY_NAME_INDEX_USE_STRING
&&
1030 mCodeNameIndex
== CODE_NAME_INDEX_Space
&& pseudoCharCode
!= ' ') {
1031 ShortcutKeyCandidate
spaceKey(' ', false);
1032 aCandidates
.AppendElement(spaceKey
);
1036 void WidgetKeyboardEvent::GetAccessKeyCandidates(
1037 nsTArray
<uint32_t>& aCandidates
) const {
1038 MOZ_ASSERT(aCandidates
.IsEmpty(), "aCandidates must be empty");
1040 // return the lower cased charCode candidates for access keys.
1041 // the priority of the charCodes are:
1042 // 0: charCode, 1: unshiftedCharCodes[0], 2: shiftedCharCodes[0]
1043 // 3: unshiftedCharCodes[1], 4: shiftedCharCodes[1],...
1044 uint32_t pseudoCharCode
= PseudoCharCode();
1045 if (pseudoCharCode
) {
1046 uint32_t ch
= pseudoCharCode
;
1047 if (IS_IN_BMP(ch
)) {
1048 ch
= ToLowerCase(static_cast<char16_t
>(ch
));
1050 aCandidates
.AppendElement(ch
);
1052 for (uint32_t i
= 0; i
< mAlternativeCharCodes
.Length(); ++i
) {
1053 uint32_t ch
[2] = {mAlternativeCharCodes
[i
].mUnshiftedCharCode
,
1054 mAlternativeCharCodes
[i
].mShiftedCharCode
};
1055 for (uint32_t j
= 0; j
< 2; ++j
) {
1059 if (IS_IN_BMP(ch
[j
])) {
1060 ch
[j
] = ToLowerCase(static_cast<char16_t
>(ch
[j
]));
1062 // Don't append the charcode that was already appended.
1063 if (aCandidates
.IndexOf(ch
[j
]) == aCandidates
.NoIndex
) {
1064 aCandidates
.AppendElement(ch
[j
]);
1068 // Special case for "Space" key. With some keyboard layouts, "Space" with
1069 // or without Shift key causes non-ASCII space. For such keyboard layouts,
1070 // we should guarantee that the key press works as an ASCII white space key
1071 // press. However, if the space key is assigned to a function key, it
1072 // shouldn't work as a space key.
1073 if (mKeyNameIndex
== KEY_NAME_INDEX_USE_STRING
&&
1074 mCodeNameIndex
== CODE_NAME_INDEX_Space
&& pseudoCharCode
!= ' ') {
1075 aCandidates
.AppendElement(' ');
1079 // mask values for ui.key.chromeAccess and ui.key.contentAccess
1080 #define NS_MODIFIER_SHIFT 1
1081 #define NS_MODIFIER_CONTROL 2
1082 #define NS_MODIFIER_ALT 4
1083 #define NS_MODIFIER_META 8
1084 #define NS_MODIFIER_OS 16
1086 static Modifiers
PrefFlagsToModifiers(int32_t aPrefFlags
) {
1087 Modifiers result
= 0;
1088 if (aPrefFlags
& NS_MODIFIER_SHIFT
) {
1089 result
|= MODIFIER_SHIFT
;
1091 if (aPrefFlags
& NS_MODIFIER_CONTROL
) {
1092 result
|= MODIFIER_CONTROL
;
1094 if (aPrefFlags
& NS_MODIFIER_ALT
) {
1095 result
|= MODIFIER_ALT
;
1097 if (aPrefFlags
& NS_MODIFIER_META
) {
1098 result
|= MODIFIER_META
;
1100 if (aPrefFlags
& NS_MODIFIER_OS
) {
1101 result
|= MODIFIER_OS
;
1106 bool WidgetKeyboardEvent::ModifiersMatchWithAccessKey(
1107 AccessKeyType aType
) const {
1108 if (!ModifiersForAccessKeyMatching()) {
1111 return ModifiersForAccessKeyMatching() == AccessKeyModifiers(aType
);
1114 Modifiers
WidgetKeyboardEvent::ModifiersForAccessKeyMatching() const {
1115 static const Modifiers kModifierMask
= MODIFIER_SHIFT
| MODIFIER_CONTROL
|
1116 MODIFIER_ALT
| MODIFIER_META
|
1118 return mModifiers
& kModifierMask
;
1122 Modifiers
WidgetKeyboardEvent::AccessKeyModifiers(AccessKeyType aType
) {
1123 switch (StaticPrefs::ui_key_generalAccessKey()) {
1125 break; // use the individual prefs
1127 return MODIFIER_SHIFT
;
1129 return MODIFIER_CONTROL
;
1131 return MODIFIER_ALT
;
1133 return MODIFIER_META
;
1137 return MODIFIER_NONE
;
1141 case AccessKeyType::eChrome
:
1142 return PrefFlagsToModifiers(StaticPrefs::ui_key_chromeAccess());
1143 case AccessKeyType::eContent
:
1144 return PrefFlagsToModifiers(StaticPrefs::ui_key_contentAccess());
1146 return MODIFIER_NONE
;
1151 void WidgetKeyboardEvent::Shutdown() {
1152 delete sKeyNameIndexHashtable
;
1153 sKeyNameIndexHashtable
= nullptr;
1154 delete sCodeNameIndexHashtable
;
1155 sCodeNameIndexHashtable
= nullptr;
1156 // Although sCommandHashtable is not a member of WidgetKeyboardEvent, but
1157 // let's delete it here since we need to do it at same time.
1158 delete sCommandHashtable
;
1159 sCommandHashtable
= nullptr;
1163 void WidgetKeyboardEvent::GetDOMKeyName(KeyNameIndex aKeyNameIndex
,
1164 nsAString
& aKeyName
) {
1165 if (aKeyNameIndex
>= KEY_NAME_INDEX_USE_STRING
) {
1166 aKeyName
.Truncate();
1171 static_cast<size_t>(aKeyNameIndex
) < ArrayLength(kKeyNames
),
1172 "Illegal key enumeration value");
1173 aKeyName
= kKeyNames
[aKeyNameIndex
];
1177 void WidgetKeyboardEvent::GetDOMCodeName(CodeNameIndex aCodeNameIndex
,
1178 nsAString
& aCodeName
) {
1179 if (aCodeNameIndex
>= CODE_NAME_INDEX_USE_STRING
) {
1180 aCodeName
.Truncate();
1185 static_cast<size_t>(aCodeNameIndex
) < ArrayLength(kCodeNames
),
1186 "Illegal physical code enumeration value");
1188 // Generate some continuous runs of codes, rather than looking them up.
1189 if (aCodeNameIndex
>= CODE_NAME_INDEX_KeyA
&&
1190 aCodeNameIndex
<= CODE_NAME_INDEX_KeyZ
) {
1191 uint32_t index
= aCodeNameIndex
- CODE_NAME_INDEX_KeyA
;
1192 aCodeName
.AssignLiteral(u
"Key");
1193 aCodeName
.Append(u
'A' + index
);
1196 if (aCodeNameIndex
>= CODE_NAME_INDEX_Digit0
&&
1197 aCodeNameIndex
<= CODE_NAME_INDEX_Digit9
) {
1198 uint32_t index
= aCodeNameIndex
- CODE_NAME_INDEX_Digit0
;
1199 aCodeName
.AssignLiteral(u
"Digit");
1200 aCodeName
.AppendInt(index
);
1203 if (aCodeNameIndex
>= CODE_NAME_INDEX_Numpad0
&&
1204 aCodeNameIndex
<= CODE_NAME_INDEX_Numpad9
) {
1205 uint32_t index
= aCodeNameIndex
- CODE_NAME_INDEX_Numpad0
;
1206 aCodeName
.AssignLiteral(u
"Numpad");
1207 aCodeName
.AppendInt(index
);
1210 if (aCodeNameIndex
>= CODE_NAME_INDEX_F1
&&
1211 aCodeNameIndex
<= CODE_NAME_INDEX_F24
) {
1212 uint32_t index
= aCodeNameIndex
- CODE_NAME_INDEX_F1
;
1213 aCodeName
.Assign(u
'F');
1214 aCodeName
.AppendInt(index
+ 1);
1218 aCodeName
= kCodeNames
[aCodeNameIndex
];
1222 KeyNameIndex
WidgetKeyboardEvent::GetKeyNameIndex(const nsAString
& aKeyValue
) {
1223 if (!sKeyNameIndexHashtable
) {
1224 sKeyNameIndexHashtable
= new KeyNameIndexHashtable(ArrayLength(kKeyNames
));
1225 for (size_t i
= 0; i
< ArrayLength(kKeyNames
); i
++) {
1226 sKeyNameIndexHashtable
->InsertOrUpdate(nsDependentString(kKeyNames
[i
]),
1227 static_cast<KeyNameIndex
>(i
));
1230 return sKeyNameIndexHashtable
->MaybeGet(aKeyValue
).valueOr(
1231 KEY_NAME_INDEX_USE_STRING
);
1235 CodeNameIndex
WidgetKeyboardEvent::GetCodeNameIndex(
1236 const nsAString
& aCodeValue
) {
1237 if (!sCodeNameIndexHashtable
) {
1238 sCodeNameIndexHashtable
=
1239 new CodeNameIndexHashtable(ArrayLength(kCodeNames
));
1240 for (size_t i
= 0; i
< ArrayLength(kCodeNames
); i
++) {
1241 sCodeNameIndexHashtable
->InsertOrUpdate(nsDependentString(kCodeNames
[i
]),
1242 static_cast<CodeNameIndex
>(i
));
1245 return sCodeNameIndexHashtable
->MaybeGet(aCodeValue
)
1246 .valueOr(CODE_NAME_INDEX_USE_STRING
);
1250 uint32_t WidgetKeyboardEvent::GetFallbackKeyCodeOfPunctuationKey(
1251 CodeNameIndex aCodeNameIndex
) {
1252 switch (aCodeNameIndex
) {
1253 case CODE_NAME_INDEX_Semicolon
: // VK_OEM_1 on Windows
1254 return dom::KeyboardEvent_Binding::DOM_VK_SEMICOLON
;
1255 case CODE_NAME_INDEX_Equal
: // VK_OEM_PLUS on Windows
1256 return dom::KeyboardEvent_Binding::DOM_VK_EQUALS
;
1257 case CODE_NAME_INDEX_Comma
: // VK_OEM_COMMA on Windows
1258 return dom::KeyboardEvent_Binding::DOM_VK_COMMA
;
1259 case CODE_NAME_INDEX_Minus
: // VK_OEM_MINUS on Windows
1260 return dom::KeyboardEvent_Binding::DOM_VK_HYPHEN_MINUS
;
1261 case CODE_NAME_INDEX_Period
: // VK_OEM_PERIOD on Windows
1262 return dom::KeyboardEvent_Binding::DOM_VK_PERIOD
;
1263 case CODE_NAME_INDEX_Slash
: // VK_OEM_2 on Windows
1264 return dom::KeyboardEvent_Binding::DOM_VK_SLASH
;
1265 case CODE_NAME_INDEX_Backquote
: // VK_OEM_3 on Windows
1266 return dom::KeyboardEvent_Binding::DOM_VK_BACK_QUOTE
;
1267 case CODE_NAME_INDEX_BracketLeft
: // VK_OEM_4 on Windows
1268 return dom::KeyboardEvent_Binding::DOM_VK_OPEN_BRACKET
;
1269 case CODE_NAME_INDEX_Backslash
: // VK_OEM_5 on Windows
1270 return dom::KeyboardEvent_Binding::DOM_VK_BACK_SLASH
;
1271 case CODE_NAME_INDEX_BracketRight
: // VK_OEM_6 on Windows
1272 return dom::KeyboardEvent_Binding::DOM_VK_CLOSE_BRACKET
;
1273 case CODE_NAME_INDEX_Quote
: // VK_OEM_7 on Windows
1274 return dom::KeyboardEvent_Binding::DOM_VK_QUOTE
;
1275 case CODE_NAME_INDEX_IntlBackslash
: // VK_OEM_5 on Windows (ABNT, etc)
1276 case CODE_NAME_INDEX_IntlYen
: // VK_OEM_5 on Windows (JIS)
1277 case CODE_NAME_INDEX_IntlRo
: // VK_OEM_102 on Windows
1278 return dom::KeyboardEvent_Binding::DOM_VK_BACK_SLASH
;
1284 /* static */ const char* WidgetKeyboardEvent::GetCommandStr(Command aCommand
) {
1285 #define NS_DEFINE_COMMAND(aName, aCommandStr) , #aCommandStr
1286 #define NS_DEFINE_COMMAND_WITH_PARAM(aName, aCommandStr, aParam) , #aCommandStr
1287 #define NS_DEFINE_COMMAND_NO_EXEC_COMMAND(aName) , ""
1288 static const char* const kCommands
[] = {
1290 #include "mozilla/CommandList.h"
1292 #undef NS_DEFINE_COMMAND
1293 #undef NS_DEFINE_COMMAND_WITH_PARAM
1294 #undef NS_DEFINE_COMMAND_NO_EXEC_COMMAND
1296 MOZ_RELEASE_ASSERT(static_cast<size_t>(aCommand
) < ArrayLength(kCommands
),
1297 "Illegal command enumeration value");
1298 return kCommands
[static_cast<CommandInt
>(aCommand
)];
1302 uint32_t WidgetKeyboardEvent::ComputeLocationFromCodeValue(
1303 CodeNameIndex aCodeNameIndex
) {
1304 // Following commented out cases are not defined in PhysicalKeyCodeNameList.h
1305 // but are defined by D3E spec. So, they should be uncommented when the
1306 // code values are defined in the header.
1307 switch (aCodeNameIndex
) {
1308 case CODE_NAME_INDEX_AltLeft
:
1309 case CODE_NAME_INDEX_ControlLeft
:
1310 case CODE_NAME_INDEX_OSLeft
:
1311 case CODE_NAME_INDEX_ShiftLeft
:
1312 return eKeyLocationLeft
;
1313 case CODE_NAME_INDEX_AltRight
:
1314 case CODE_NAME_INDEX_ControlRight
:
1315 case CODE_NAME_INDEX_OSRight
:
1316 case CODE_NAME_INDEX_ShiftRight
:
1317 return eKeyLocationRight
;
1318 case CODE_NAME_INDEX_Numpad0
:
1319 case CODE_NAME_INDEX_Numpad1
:
1320 case CODE_NAME_INDEX_Numpad2
:
1321 case CODE_NAME_INDEX_Numpad3
:
1322 case CODE_NAME_INDEX_Numpad4
:
1323 case CODE_NAME_INDEX_Numpad5
:
1324 case CODE_NAME_INDEX_Numpad6
:
1325 case CODE_NAME_INDEX_Numpad7
:
1326 case CODE_NAME_INDEX_Numpad8
:
1327 case CODE_NAME_INDEX_Numpad9
:
1328 case CODE_NAME_INDEX_NumpadAdd
:
1329 case CODE_NAME_INDEX_NumpadBackspace
:
1330 case CODE_NAME_INDEX_NumpadClear
:
1331 case CODE_NAME_INDEX_NumpadClearEntry
:
1332 case CODE_NAME_INDEX_NumpadComma
:
1333 case CODE_NAME_INDEX_NumpadDecimal
:
1334 case CODE_NAME_INDEX_NumpadDivide
:
1335 case CODE_NAME_INDEX_NumpadEnter
:
1336 case CODE_NAME_INDEX_NumpadEqual
:
1337 case CODE_NAME_INDEX_NumpadMemoryAdd
:
1338 case CODE_NAME_INDEX_NumpadMemoryClear
:
1339 case CODE_NAME_INDEX_NumpadMemoryRecall
:
1340 case CODE_NAME_INDEX_NumpadMemoryStore
:
1341 case CODE_NAME_INDEX_NumpadMemorySubtract
:
1342 case CODE_NAME_INDEX_NumpadMultiply
:
1343 case CODE_NAME_INDEX_NumpadParenLeft
:
1344 case CODE_NAME_INDEX_NumpadParenRight
:
1345 case CODE_NAME_INDEX_NumpadSubtract
:
1346 return eKeyLocationNumpad
;
1348 return eKeyLocationStandard
;
1353 uint32_t WidgetKeyboardEvent::ComputeKeyCodeFromKeyNameIndex(
1354 KeyNameIndex aKeyNameIndex
) {
1355 switch (aKeyNameIndex
) {
1356 case KEY_NAME_INDEX_Cancel
:
1357 return dom::KeyboardEvent_Binding::DOM_VK_CANCEL
;
1358 case KEY_NAME_INDEX_Help
:
1359 return dom::KeyboardEvent_Binding::DOM_VK_HELP
;
1360 case KEY_NAME_INDEX_Backspace
:
1361 return dom::KeyboardEvent_Binding::DOM_VK_BACK_SPACE
;
1362 case KEY_NAME_INDEX_Tab
:
1363 return dom::KeyboardEvent_Binding::DOM_VK_TAB
;
1364 case KEY_NAME_INDEX_Clear
:
1365 return dom::KeyboardEvent_Binding::DOM_VK_CLEAR
;
1366 case KEY_NAME_INDEX_Enter
:
1367 return dom::KeyboardEvent_Binding::DOM_VK_RETURN
;
1368 case KEY_NAME_INDEX_Shift
:
1369 return dom::KeyboardEvent_Binding::DOM_VK_SHIFT
;
1370 case KEY_NAME_INDEX_Control
:
1371 return dom::KeyboardEvent_Binding::DOM_VK_CONTROL
;
1372 case KEY_NAME_INDEX_Alt
:
1373 return dom::KeyboardEvent_Binding::DOM_VK_ALT
;
1374 case KEY_NAME_INDEX_Pause
:
1375 return dom::KeyboardEvent_Binding::DOM_VK_PAUSE
;
1376 case KEY_NAME_INDEX_CapsLock
:
1377 return dom::KeyboardEvent_Binding::DOM_VK_CAPS_LOCK
;
1378 case KEY_NAME_INDEX_Hiragana
:
1379 case KEY_NAME_INDEX_Katakana
:
1380 case KEY_NAME_INDEX_HiraganaKatakana
:
1381 case KEY_NAME_INDEX_KanaMode
:
1382 return dom::KeyboardEvent_Binding::DOM_VK_KANA
;
1383 case KEY_NAME_INDEX_HangulMode
:
1384 return dom::KeyboardEvent_Binding::DOM_VK_HANGUL
;
1385 case KEY_NAME_INDEX_Eisu
:
1386 return dom::KeyboardEvent_Binding::DOM_VK_EISU
;
1387 case KEY_NAME_INDEX_JunjaMode
:
1388 return dom::KeyboardEvent_Binding::DOM_VK_JUNJA
;
1389 case KEY_NAME_INDEX_FinalMode
:
1390 return dom::KeyboardEvent_Binding::DOM_VK_FINAL
;
1391 case KEY_NAME_INDEX_HanjaMode
:
1392 return dom::KeyboardEvent_Binding::DOM_VK_HANJA
;
1393 case KEY_NAME_INDEX_KanjiMode
:
1394 return dom::KeyboardEvent_Binding::DOM_VK_KANJI
;
1395 case KEY_NAME_INDEX_Escape
:
1396 return dom::KeyboardEvent_Binding::DOM_VK_ESCAPE
;
1397 case KEY_NAME_INDEX_Convert
:
1398 return dom::KeyboardEvent_Binding::DOM_VK_CONVERT
;
1399 case KEY_NAME_INDEX_NonConvert
:
1400 return dom::KeyboardEvent_Binding::DOM_VK_NONCONVERT
;
1401 case KEY_NAME_INDEX_Accept
:
1402 return dom::KeyboardEvent_Binding::DOM_VK_ACCEPT
;
1403 case KEY_NAME_INDEX_ModeChange
:
1404 return dom::KeyboardEvent_Binding::DOM_VK_MODECHANGE
;
1405 case KEY_NAME_INDEX_PageUp
:
1406 return dom::KeyboardEvent_Binding::DOM_VK_PAGE_UP
;
1407 case KEY_NAME_INDEX_PageDown
:
1408 return dom::KeyboardEvent_Binding::DOM_VK_PAGE_DOWN
;
1409 case KEY_NAME_INDEX_End
:
1410 return dom::KeyboardEvent_Binding::DOM_VK_END
;
1411 case KEY_NAME_INDEX_Home
:
1412 return dom::KeyboardEvent_Binding::DOM_VK_HOME
;
1413 case KEY_NAME_INDEX_ArrowLeft
:
1414 return dom::KeyboardEvent_Binding::DOM_VK_LEFT
;
1415 case KEY_NAME_INDEX_ArrowUp
:
1416 return dom::KeyboardEvent_Binding::DOM_VK_UP
;
1417 case KEY_NAME_INDEX_ArrowRight
:
1418 return dom::KeyboardEvent_Binding::DOM_VK_RIGHT
;
1419 case KEY_NAME_INDEX_ArrowDown
:
1420 return dom::KeyboardEvent_Binding::DOM_VK_DOWN
;
1421 case KEY_NAME_INDEX_Select
:
1422 return dom::KeyboardEvent_Binding::DOM_VK_SELECT
;
1423 case KEY_NAME_INDEX_Print
:
1424 return dom::KeyboardEvent_Binding::DOM_VK_PRINT
;
1425 case KEY_NAME_INDEX_Execute
:
1426 return dom::KeyboardEvent_Binding::DOM_VK_EXECUTE
;
1427 case KEY_NAME_INDEX_PrintScreen
:
1428 return dom::KeyboardEvent_Binding::DOM_VK_PRINTSCREEN
;
1429 case KEY_NAME_INDEX_Insert
:
1430 return dom::KeyboardEvent_Binding::DOM_VK_INSERT
;
1431 case KEY_NAME_INDEX_Delete
:
1432 return dom::KeyboardEvent_Binding::DOM_VK_DELETE
;
1433 case KEY_NAME_INDEX_OS
:
1434 // case KEY_NAME_INDEX_Super:
1435 // case KEY_NAME_INDEX_Hyper:
1436 return dom::KeyboardEvent_Binding::DOM_VK_WIN
;
1437 case KEY_NAME_INDEX_ContextMenu
:
1438 return dom::KeyboardEvent_Binding::DOM_VK_CONTEXT_MENU
;
1439 case KEY_NAME_INDEX_Standby
:
1440 return dom::KeyboardEvent_Binding::DOM_VK_SLEEP
;
1441 case KEY_NAME_INDEX_F1
:
1442 return dom::KeyboardEvent_Binding::DOM_VK_F1
;
1443 case KEY_NAME_INDEX_F2
:
1444 return dom::KeyboardEvent_Binding::DOM_VK_F2
;
1445 case KEY_NAME_INDEX_F3
:
1446 return dom::KeyboardEvent_Binding::DOM_VK_F3
;
1447 case KEY_NAME_INDEX_F4
:
1448 return dom::KeyboardEvent_Binding::DOM_VK_F4
;
1449 case KEY_NAME_INDEX_F5
:
1450 return dom::KeyboardEvent_Binding::DOM_VK_F5
;
1451 case KEY_NAME_INDEX_F6
:
1452 return dom::KeyboardEvent_Binding::DOM_VK_F6
;
1453 case KEY_NAME_INDEX_F7
:
1454 return dom::KeyboardEvent_Binding::DOM_VK_F7
;
1455 case KEY_NAME_INDEX_F8
:
1456 return dom::KeyboardEvent_Binding::DOM_VK_F8
;
1457 case KEY_NAME_INDEX_F9
:
1458 return dom::KeyboardEvent_Binding::DOM_VK_F9
;
1459 case KEY_NAME_INDEX_F10
:
1460 return dom::KeyboardEvent_Binding::DOM_VK_F10
;
1461 case KEY_NAME_INDEX_F11
:
1462 return dom::KeyboardEvent_Binding::DOM_VK_F11
;
1463 case KEY_NAME_INDEX_F12
:
1464 return dom::KeyboardEvent_Binding::DOM_VK_F12
;
1465 case KEY_NAME_INDEX_F13
:
1466 return dom::KeyboardEvent_Binding::DOM_VK_F13
;
1467 case KEY_NAME_INDEX_F14
:
1468 return dom::KeyboardEvent_Binding::DOM_VK_F14
;
1469 case KEY_NAME_INDEX_F15
:
1470 return dom::KeyboardEvent_Binding::DOM_VK_F15
;
1471 case KEY_NAME_INDEX_F16
:
1472 return dom::KeyboardEvent_Binding::DOM_VK_F16
;
1473 case KEY_NAME_INDEX_F17
:
1474 return dom::KeyboardEvent_Binding::DOM_VK_F17
;
1475 case KEY_NAME_INDEX_F18
:
1476 return dom::KeyboardEvent_Binding::DOM_VK_F18
;
1477 case KEY_NAME_INDEX_F19
:
1478 return dom::KeyboardEvent_Binding::DOM_VK_F19
;
1479 case KEY_NAME_INDEX_F20
:
1480 return dom::KeyboardEvent_Binding::DOM_VK_F20
;
1481 case KEY_NAME_INDEX_F21
:
1482 return dom::KeyboardEvent_Binding::DOM_VK_F21
;
1483 case KEY_NAME_INDEX_F22
:
1484 return dom::KeyboardEvent_Binding::DOM_VK_F22
;
1485 case KEY_NAME_INDEX_F23
:
1486 return dom::KeyboardEvent_Binding::DOM_VK_F23
;
1487 case KEY_NAME_INDEX_F24
:
1488 return dom::KeyboardEvent_Binding::DOM_VK_F24
;
1489 case KEY_NAME_INDEX_NumLock
:
1490 return dom::KeyboardEvent_Binding::DOM_VK_NUM_LOCK
;
1491 case KEY_NAME_INDEX_ScrollLock
:
1492 return dom::KeyboardEvent_Binding::DOM_VK_SCROLL_LOCK
;
1493 case KEY_NAME_INDEX_AudioVolumeMute
:
1494 return dom::KeyboardEvent_Binding::DOM_VK_VOLUME_MUTE
;
1495 case KEY_NAME_INDEX_AudioVolumeDown
:
1496 return dom::KeyboardEvent_Binding::DOM_VK_VOLUME_DOWN
;
1497 case KEY_NAME_INDEX_AudioVolumeUp
:
1498 return dom::KeyboardEvent_Binding::DOM_VK_VOLUME_UP
;
1499 case KEY_NAME_INDEX_Meta
:
1500 return dom::KeyboardEvent_Binding::DOM_VK_META
;
1501 case KEY_NAME_INDEX_AltGraph
:
1502 return dom::KeyboardEvent_Binding::DOM_VK_ALTGR
;
1503 case KEY_NAME_INDEX_Process
:
1504 return dom::KeyboardEvent_Binding::DOM_VK_PROCESSKEY
;
1505 case KEY_NAME_INDEX_Attn
:
1506 return dom::KeyboardEvent_Binding::DOM_VK_ATTN
;
1507 case KEY_NAME_INDEX_CrSel
:
1508 return dom::KeyboardEvent_Binding::DOM_VK_CRSEL
;
1509 case KEY_NAME_INDEX_ExSel
:
1510 return dom::KeyboardEvent_Binding::DOM_VK_EXSEL
;
1511 case KEY_NAME_INDEX_EraseEof
:
1512 return dom::KeyboardEvent_Binding::DOM_VK_EREOF
;
1513 case KEY_NAME_INDEX_Play
:
1514 return dom::KeyboardEvent_Binding::DOM_VK_PLAY
;
1515 case KEY_NAME_INDEX_ZoomToggle
:
1516 case KEY_NAME_INDEX_ZoomIn
:
1517 case KEY_NAME_INDEX_ZoomOut
:
1518 return dom::KeyboardEvent_Binding::DOM_VK_ZOOM
;
1525 CodeNameIndex
WidgetKeyboardEvent::ComputeCodeNameIndexFromKeyNameIndex(
1526 KeyNameIndex aKeyNameIndex
, const Maybe
<uint32_t>& aLocation
) {
1527 if (aLocation
.isSome() &&
1528 aLocation
.value() ==
1529 dom::KeyboardEvent_Binding::DOM_KEY_LOCATION_NUMPAD
) {
1530 // On macOS, NumLock is not supported. Therefore, this handles
1531 // control key values except "Enter" only on non-macOS platforms.
1532 switch (aKeyNameIndex
) {
1534 case KEY_NAME_INDEX_Insert
:
1535 return CODE_NAME_INDEX_Numpad0
;
1536 case KEY_NAME_INDEX_End
:
1537 return CODE_NAME_INDEX_Numpad1
;
1538 case KEY_NAME_INDEX_ArrowDown
:
1539 return CODE_NAME_INDEX_Numpad2
;
1540 case KEY_NAME_INDEX_PageDown
:
1541 return CODE_NAME_INDEX_Numpad3
;
1542 case KEY_NAME_INDEX_ArrowLeft
:
1543 return CODE_NAME_INDEX_Numpad4
;
1544 case KEY_NAME_INDEX_Clear
:
1545 // FYI: "Clear" on macOS should be DOM_KEY_LOCATION_STANDARD.
1546 return CODE_NAME_INDEX_Numpad5
;
1547 case KEY_NAME_INDEX_ArrowRight
:
1548 return CODE_NAME_INDEX_Numpad6
;
1549 case KEY_NAME_INDEX_Home
:
1550 return CODE_NAME_INDEX_Numpad7
;
1551 case KEY_NAME_INDEX_ArrowUp
:
1552 return CODE_NAME_INDEX_Numpad8
;
1553 case KEY_NAME_INDEX_PageUp
:
1554 return CODE_NAME_INDEX_Numpad9
;
1555 case KEY_NAME_INDEX_Delete
:
1556 return CODE_NAME_INDEX_NumpadDecimal
;
1557 #endif // #ifndef XP_MACOSX
1558 case KEY_NAME_INDEX_Enter
:
1559 return CODE_NAME_INDEX_NumpadEnter
;
1561 return CODE_NAME_INDEX_UNKNOWN
;
1565 if (WidgetKeyboardEvent::IsLeftOrRightModiferKeyNameIndex(aKeyNameIndex
)) {
1566 if (aLocation
.isSome() &&
1567 (aLocation
.value() !=
1568 dom::KeyboardEvent_Binding::DOM_KEY_LOCATION_LEFT
&&
1569 aLocation
.value() !=
1570 dom::KeyboardEvent_Binding::DOM_KEY_LOCATION_RIGHT
)) {
1571 return CODE_NAME_INDEX_UNKNOWN
;
1574 aLocation
.isSome() &&
1575 aLocation
.value() == dom::KeyboardEvent_Binding::DOM_KEY_LOCATION_RIGHT
;
1576 switch (aKeyNameIndex
) {
1577 case KEY_NAME_INDEX_Alt
:
1578 return isRight
? CODE_NAME_INDEX_AltRight
: CODE_NAME_INDEX_AltLeft
;
1579 case KEY_NAME_INDEX_Control
:
1580 return isRight
? CODE_NAME_INDEX_ControlRight
1581 : CODE_NAME_INDEX_ControlLeft
;
1582 case KEY_NAME_INDEX_Shift
:
1583 return isRight
? CODE_NAME_INDEX_ShiftRight
: CODE_NAME_INDEX_ShiftLeft
;
1585 case KEY_NAME_INDEX_Meta
:
1586 return CODE_NAME_INDEX_UNKNOWN
;
1587 case KEY_NAME_INDEX_OS
: // win key.
1588 return isRight
? CODE_NAME_INDEX_OSRight
: CODE_NAME_INDEX_OSLeft
;
1589 #elif defined(XP_MACOSX) || defined(ANDROID)
1590 case KEY_NAME_INDEX_Meta
: // command key.
1591 return isRight
? CODE_NAME_INDEX_OSRight
: CODE_NAME_INDEX_OSLeft
;
1592 case KEY_NAME_INDEX_OS
:
1593 return CODE_NAME_INDEX_UNKNOWN
;
1595 case KEY_NAME_INDEX_Meta
: // Alt + Shift.
1596 return isRight
? CODE_NAME_INDEX_AltRight
: CODE_NAME_INDEX_AltLeft
;
1597 case KEY_NAME_INDEX_OS
: // Super/Hyper key.
1598 return isRight
? CODE_NAME_INDEX_OSRight
: CODE_NAME_INDEX_OSLeft
;
1601 return CODE_NAME_INDEX_UNKNOWN
;
1605 if (aLocation
.isSome() &&
1606 aLocation
.value() !=
1607 dom::KeyboardEvent_Binding::DOM_KEY_LOCATION_STANDARD
) {
1608 return CODE_NAME_INDEX_UNKNOWN
;
1611 switch (aKeyNameIndex
) {
1612 // Standard section:
1613 case KEY_NAME_INDEX_Escape
:
1614 return CODE_NAME_INDEX_Escape
;
1615 case KEY_NAME_INDEX_Tab
:
1616 return CODE_NAME_INDEX_Tab
;
1617 case KEY_NAME_INDEX_CapsLock
:
1618 return CODE_NAME_INDEX_CapsLock
;
1619 case KEY_NAME_INDEX_ContextMenu
:
1620 return CODE_NAME_INDEX_ContextMenu
;
1621 case KEY_NAME_INDEX_Backspace
:
1622 return CODE_NAME_INDEX_Backspace
;
1623 case KEY_NAME_INDEX_Enter
:
1624 return CODE_NAME_INDEX_Enter
;
1626 // Although, macOS does not fire native key event of "Fn" key, we support
1627 // Fn key event if it's sent by other apps directly.
1628 case KEY_NAME_INDEX_Fn
:
1629 return CODE_NAME_INDEX_Fn
;
1632 // Arrow Pad section:
1633 case KEY_NAME_INDEX_ArrowLeft
:
1634 return CODE_NAME_INDEX_ArrowLeft
;
1635 case KEY_NAME_INDEX_ArrowUp
:
1636 return CODE_NAME_INDEX_ArrowUp
;
1637 case KEY_NAME_INDEX_ArrowDown
:
1638 return CODE_NAME_INDEX_ArrowDown
;
1639 case KEY_NAME_INDEX_ArrowRight
:
1640 return CODE_NAME_INDEX_ArrowRight
;
1642 // Control Pad section:
1644 case KEY_NAME_INDEX_Insert
:
1645 return CODE_NAME_INDEX_Insert
;
1647 case KEY_NAME_INDEX_Help
:
1648 return CODE_NAME_INDEX_Help
;
1649 #endif // #ifndef XP_MACOSX #else
1650 case KEY_NAME_INDEX_Delete
:
1651 return CODE_NAME_INDEX_Delete
;
1652 case KEY_NAME_INDEX_Home
:
1653 return CODE_NAME_INDEX_Home
;
1654 case KEY_NAME_INDEX_End
:
1655 return CODE_NAME_INDEX_End
;
1656 case KEY_NAME_INDEX_PageUp
:
1657 return CODE_NAME_INDEX_PageUp
;
1658 case KEY_NAME_INDEX_PageDown
:
1659 return CODE_NAME_INDEX_PageDown
;
1662 case KEY_NAME_INDEX_F1
:
1663 return CODE_NAME_INDEX_F1
;
1664 case KEY_NAME_INDEX_F2
:
1665 return CODE_NAME_INDEX_F2
;
1666 case KEY_NAME_INDEX_F3
:
1667 return CODE_NAME_INDEX_F3
;
1668 case KEY_NAME_INDEX_F4
:
1669 return CODE_NAME_INDEX_F4
;
1670 case KEY_NAME_INDEX_F5
:
1671 return CODE_NAME_INDEX_F5
;
1672 case KEY_NAME_INDEX_F6
:
1673 return CODE_NAME_INDEX_F6
;
1674 case KEY_NAME_INDEX_F7
:
1675 return CODE_NAME_INDEX_F7
;
1676 case KEY_NAME_INDEX_F8
:
1677 return CODE_NAME_INDEX_F8
;
1678 case KEY_NAME_INDEX_F9
:
1679 return CODE_NAME_INDEX_F9
;
1680 case KEY_NAME_INDEX_F10
:
1681 return CODE_NAME_INDEX_F10
;
1682 case KEY_NAME_INDEX_F11
:
1683 return CODE_NAME_INDEX_F11
;
1684 case KEY_NAME_INDEX_F12
:
1685 return CODE_NAME_INDEX_F12
;
1686 case KEY_NAME_INDEX_F13
:
1687 return CODE_NAME_INDEX_F13
;
1688 case KEY_NAME_INDEX_F14
:
1689 return CODE_NAME_INDEX_F14
;
1690 case KEY_NAME_INDEX_F15
:
1691 return CODE_NAME_INDEX_F15
;
1692 case KEY_NAME_INDEX_F16
:
1693 return CODE_NAME_INDEX_F16
;
1694 case KEY_NAME_INDEX_F17
:
1695 return CODE_NAME_INDEX_F17
;
1696 case KEY_NAME_INDEX_F18
:
1697 return CODE_NAME_INDEX_F18
;
1698 case KEY_NAME_INDEX_F19
:
1699 return CODE_NAME_INDEX_F19
;
1700 case KEY_NAME_INDEX_F20
:
1701 return CODE_NAME_INDEX_F20
;
1703 case KEY_NAME_INDEX_F21
:
1704 return CODE_NAME_INDEX_F21
;
1705 case KEY_NAME_INDEX_F22
:
1706 return CODE_NAME_INDEX_F22
;
1707 case KEY_NAME_INDEX_F23
:
1708 return CODE_NAME_INDEX_F23
;
1709 case KEY_NAME_INDEX_F24
:
1710 return CODE_NAME_INDEX_F24
;
1711 case KEY_NAME_INDEX_Pause
:
1712 return CODE_NAME_INDEX_Pause
;
1713 case KEY_NAME_INDEX_PrintScreen
:
1714 return CODE_NAME_INDEX_PrintScreen
;
1715 case KEY_NAME_INDEX_ScrollLock
:
1716 return CODE_NAME_INDEX_ScrollLock
;
1717 #endif // #ifndef XP_MACOSX
1721 case KEY_NAME_INDEX_NumLock
:
1722 return CODE_NAME_INDEX_NumLock
;
1724 case KEY_NAME_INDEX_Clear
:
1725 return CODE_NAME_INDEX_NumLock
;
1726 #endif // #ifndef XP_MACOSX #else
1729 case KEY_NAME_INDEX_AudioVolumeDown
:
1730 return CODE_NAME_INDEX_VolumeDown
;
1731 case KEY_NAME_INDEX_AudioVolumeMute
:
1732 return CODE_NAME_INDEX_VolumeMute
;
1733 case KEY_NAME_INDEX_AudioVolumeUp
:
1734 return CODE_NAME_INDEX_VolumeUp
;
1736 case KEY_NAME_INDEX_BrowserBack
:
1737 return CODE_NAME_INDEX_BrowserBack
;
1738 case KEY_NAME_INDEX_BrowserFavorites
:
1739 return CODE_NAME_INDEX_BrowserFavorites
;
1740 case KEY_NAME_INDEX_BrowserForward
:
1741 return CODE_NAME_INDEX_BrowserForward
;
1742 case KEY_NAME_INDEX_BrowserRefresh
:
1743 return CODE_NAME_INDEX_BrowserRefresh
;
1744 case KEY_NAME_INDEX_BrowserSearch
:
1745 return CODE_NAME_INDEX_BrowserSearch
;
1746 case KEY_NAME_INDEX_BrowserStop
:
1747 return CODE_NAME_INDEX_BrowserStop
;
1748 case KEY_NAME_INDEX_MediaPlayPause
:
1749 return CODE_NAME_INDEX_MediaPlayPause
;
1750 case KEY_NAME_INDEX_MediaStop
:
1751 return CODE_NAME_INDEX_MediaStop
;
1752 case KEY_NAME_INDEX_MediaTrackNext
:
1753 return CODE_NAME_INDEX_MediaTrackNext
;
1754 case KEY_NAME_INDEX_MediaTrackPrevious
:
1755 return CODE_NAME_INDEX_MediaTrackPrevious
;
1756 case KEY_NAME_INDEX_LaunchApplication1
:
1757 return CODE_NAME_INDEX_LaunchApp1
;
1758 #endif // #ifndef XP_MACOSX
1760 // Only Windows and GTK supports the following multimedia keys.
1761 #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
1762 case KEY_NAME_INDEX_BrowserHome
:
1763 return CODE_NAME_INDEX_BrowserHome
;
1764 case KEY_NAME_INDEX_LaunchApplication2
:
1765 return CODE_NAME_INDEX_LaunchApp2
;
1766 #endif // #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
1768 // Only GTK and Android supports the following multimedia keys.
1769 #if defined(MOZ_WIDGET_GTK) || defined(ANDROID)
1770 case KEY_NAME_INDEX_Eject
:
1771 return CODE_NAME_INDEX_Eject
;
1772 case KEY_NAME_INDEX_WakeUp
:
1773 return CODE_NAME_INDEX_WakeUp
;
1774 #endif // #if defined(MOZ_WIDGET_GTK) || defined(ANDROID)
1776 // Only Windows does not support Help key (and macOS handled above).
1777 #if !defined(XP_WIN) && !defined(XP_MACOSX)
1778 case KEY_NAME_INDEX_Help
:
1779 return CODE_NAME_INDEX_Help
;
1780 #endif // #if !defined(XP_WIN) && !defined(XP_MACOSX)
1782 // IME specific keys:
1784 case KEY_NAME_INDEX_Convert
:
1785 return CODE_NAME_INDEX_Convert
;
1786 case KEY_NAME_INDEX_NonConvert
:
1787 return CODE_NAME_INDEX_NonConvert
;
1788 case KEY_NAME_INDEX_Alphanumeric
:
1789 return CODE_NAME_INDEX_CapsLock
;
1790 case KEY_NAME_INDEX_KanaMode
:
1791 case KEY_NAME_INDEX_Romaji
:
1792 case KEY_NAME_INDEX_Katakana
:
1793 case KEY_NAME_INDEX_Hiragana
:
1794 return CODE_NAME_INDEX_KanaMode
;
1795 case KEY_NAME_INDEX_Hankaku
:
1796 case KEY_NAME_INDEX_Zenkaku
:
1797 case KEY_NAME_INDEX_KanjiMode
:
1798 return CODE_NAME_INDEX_Backquote
;
1799 case KEY_NAME_INDEX_HanjaMode
:
1800 return CODE_NAME_INDEX_Lang2
;
1801 case KEY_NAME_INDEX_HangulMode
:
1802 return CODE_NAME_INDEX_Lang1
;
1803 #endif // #ifdef XP_WIN
1805 #ifdef MOZ_WIDGET_GTK
1806 case KEY_NAME_INDEX_Convert
:
1807 return CODE_NAME_INDEX_Convert
;
1808 case KEY_NAME_INDEX_NonConvert
:
1809 return CODE_NAME_INDEX_NonConvert
;
1810 case KEY_NAME_INDEX_Alphanumeric
:
1811 return CODE_NAME_INDEX_CapsLock
;
1812 case KEY_NAME_INDEX_HiraganaKatakana
:
1813 return CODE_NAME_INDEX_KanaMode
;
1814 case KEY_NAME_INDEX_ZenkakuHankaku
:
1815 return CODE_NAME_INDEX_Backquote
;
1816 #endif // #ifdef MOZ_WIDGET_GTK
1819 case KEY_NAME_INDEX_Convert
:
1820 return CODE_NAME_INDEX_Convert
;
1821 case KEY_NAME_INDEX_NonConvert
:
1822 return CODE_NAME_INDEX_NonConvert
;
1823 case KEY_NAME_INDEX_HiraganaKatakana
:
1824 return CODE_NAME_INDEX_KanaMode
;
1825 case KEY_NAME_INDEX_ZenkakuHankaku
:
1826 return CODE_NAME_INDEX_Backquote
;
1827 case KEY_NAME_INDEX_Eisu
:
1828 return CODE_NAME_INDEX_Lang2
;
1829 case KEY_NAME_INDEX_KanjiMode
:
1830 return CODE_NAME_INDEX_Lang1
;
1831 #endif // #ifdef ANDROID
1834 case KEY_NAME_INDEX_Eisu
:
1835 return CODE_NAME_INDEX_Lang2
;
1836 case KEY_NAME_INDEX_KanjiMode
:
1837 return CODE_NAME_INDEX_Lang1
;
1838 #endif // #ifdef XP_MACOSX
1841 return CODE_NAME_INDEX_UNKNOWN
;
1846 Modifier
WidgetKeyboardEvent::GetModifierForKeyName(
1847 KeyNameIndex aKeyNameIndex
) {
1848 switch (aKeyNameIndex
) {
1849 case KEY_NAME_INDEX_Alt
:
1850 return MODIFIER_ALT
;
1851 case KEY_NAME_INDEX_AltGraph
:
1852 return MODIFIER_ALTGRAPH
;
1853 case KEY_NAME_INDEX_CapsLock
:
1854 return MODIFIER_CAPSLOCK
;
1855 case KEY_NAME_INDEX_Control
:
1856 return MODIFIER_CONTROL
;
1857 case KEY_NAME_INDEX_Fn
:
1859 case KEY_NAME_INDEX_FnLock
:
1860 return MODIFIER_FNLOCK
;
1861 // case KEY_NAME_INDEX_Hyper:
1862 case KEY_NAME_INDEX_Meta
:
1863 return MODIFIER_META
;
1864 case KEY_NAME_INDEX_NumLock
:
1865 return MODIFIER_NUMLOCK
;
1866 case KEY_NAME_INDEX_OS
:
1868 case KEY_NAME_INDEX_ScrollLock
:
1869 return MODIFIER_SCROLLLOCK
;
1870 case KEY_NAME_INDEX_Shift
:
1871 return MODIFIER_SHIFT
;
1872 // case KEY_NAME_INDEX_Super:
1873 case KEY_NAME_INDEX_Symbol
:
1874 return MODIFIER_SYMBOL
;
1875 case KEY_NAME_INDEX_SymbolLock
:
1876 return MODIFIER_SYMBOLLOCK
;
1878 return MODIFIER_NONE
;
1883 bool WidgetKeyboardEvent::IsLockableModifier(KeyNameIndex aKeyNameIndex
) {
1884 switch (aKeyNameIndex
) {
1885 case KEY_NAME_INDEX_CapsLock
:
1886 case KEY_NAME_INDEX_FnLock
:
1887 case KEY_NAME_INDEX_NumLock
:
1888 case KEY_NAME_INDEX_ScrollLock
:
1889 case KEY_NAME_INDEX_SymbolLock
:
1896 /******************************************************************************
1897 * mozilla::InternalEditorInputEvent (TextEvents.h)
1898 ******************************************************************************/
1900 #define NS_DEFINE_INPUTTYPE(aCPPName, aDOMName) (u"" aDOMName),
1901 const char16_t
* const InternalEditorInputEvent::kInputTypeNames
[] = {
1902 #include "mozilla/InputTypeList.h"
1904 #undef NS_DEFINE_INPUTTYPE
1906 InternalEditorInputEvent::InputTypeHashtable
*
1907 InternalEditorInputEvent::sInputTypeHashtable
= nullptr;
1910 void InternalEditorInputEvent::Shutdown() {
1911 delete sInputTypeHashtable
;
1912 sInputTypeHashtable
= nullptr;
1916 void InternalEditorInputEvent::GetDOMInputTypeName(EditorInputType aInputType
,
1917 nsAString
& aInputTypeName
) {
1918 if (static_cast<size_t>(aInputType
) >=
1919 static_cast<size_t>(EditorInputType::eUnknown
)) {
1920 aInputTypeName
.Truncate();
1925 static_cast<size_t>(aInputType
) < ArrayLength(kInputTypeNames
),
1926 "Illegal input type enumeration value");
1927 aInputTypeName
.Assign(kInputTypeNames
[static_cast<size_t>(aInputType
)]);
1931 EditorInputType
InternalEditorInputEvent::GetEditorInputType(
1932 const nsAString
& aInputType
) {
1933 if (aInputType
.IsEmpty()) {
1934 return EditorInputType::eUnknown
;
1937 if (!sInputTypeHashtable
) {
1938 sInputTypeHashtable
= new InputTypeHashtable(ArrayLength(kInputTypeNames
));
1939 for (size_t i
= 0; i
< ArrayLength(kInputTypeNames
); i
++) {
1940 sInputTypeHashtable
->InsertOrUpdate(nsDependentString(kInputTypeNames
[i
]),
1941 static_cast<EditorInputType
>(i
));
1944 return sInputTypeHashtable
->MaybeGet(aInputType
)
1945 .valueOr(EditorInputType::eUnknown
);
1948 } // namespace mozilla