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_dom.h"
20 #include "mozilla/StaticPrefs_mousewheel.h"
21 #include "mozilla/StaticPrefs_ui.h"
22 #include "mozilla/WritingModes.h"
23 #include "mozilla/dom/KeyboardEventBinding.h"
24 #include "mozilla/dom/MouseEventBinding.h"
25 #include "mozilla/dom/WheelEventBinding.h"
26 #include "nsCommandParams.h"
27 #include "nsContentUtils.h"
28 #include "nsIContent.h"
29 #include "nsIDragSession.h"
30 #include "nsPrintfCString.h"
34 # include "winnetwk.h"
36 # include "WinUtils.h"
37 #endif // #if defined (XP_WIN)
39 #if defined(MOZ_WIDGET_GTK) || defined(XP_MACOSX)
40 # include "NativeKeyBindings.h"
41 #endif // #if defined(MOZ_WIDGET_GTK) || defined(XP_MACOSX)
45 /******************************************************************************
46 * Global helper methods
47 ******************************************************************************/
49 const char* ToChar(EventMessage aEventMessage
) {
50 switch (aEventMessage
) {
51 #define NS_EVENT_MESSAGE(aMessage) \
55 #include "mozilla/EventMessageList.h"
57 #undef NS_EVENT_MESSAGE
59 return "illegal event message";
63 bool IsPointerEventMessage(EventMessage aMessage
) {
73 case ePointerGotCapture
:
74 case ePointerLostCapture
:
77 case ePointerAuxClick
:
80 dom_w3c_pointer_events_dispatch_click_as_pointer_event();
86 bool IsPointerEventMessageOriginallyMouseEventMessage(EventMessage aMessage
) {
88 dom_w3c_pointer_events_dispatch_click_as_pointer_event() &&
89 (aMessage
== ePointerClick
|| aMessage
== ePointerAuxClick
||
90 aMessage
== eContextMenu
);
93 const char* ToChar(EventClassID aEventClassID
) {
94 switch (aEventClassID
) {
95 #define NS_ROOT_EVENT_CLASS(aPrefix, aName) \
96 case eBasic##aName##Class: \
97 return "eBasic" #aName "Class";
99 #define NS_EVENT_CLASS(aPrefix, aName) \
100 case e##aName##Class: \
101 return "e" #aName "Class";
103 #include "mozilla/EventClassList.h"
105 #undef NS_EVENT_CLASS
106 #undef NS_ROOT_EVENT_CLASS
108 return "illegal event class ID";
112 const nsCString
ToString(KeyNameIndex aKeyNameIndex
) {
113 if (aKeyNameIndex
== KEY_NAME_INDEX_USE_STRING
) {
114 return "USE_STRING"_ns
;
116 nsAutoString keyName
;
117 WidgetKeyboardEvent::GetDOMKeyName(aKeyNameIndex
, keyName
);
118 return NS_ConvertUTF16toUTF8(keyName
);
121 const nsCString
ToString(CodeNameIndex aCodeNameIndex
) {
122 if (aCodeNameIndex
== CODE_NAME_INDEX_USE_STRING
) {
123 return "USE_STRING"_ns
;
125 nsAutoString codeName
;
126 WidgetKeyboardEvent::GetDOMCodeName(aCodeNameIndex
, codeName
);
127 return NS_ConvertUTF16toUTF8(codeName
);
130 const char* ToChar(Command aCommand
) {
131 if (aCommand
== Command::DoNothing
) {
132 return "CommandDoNothing";
136 #define NS_DEFINE_COMMAND(aName, aCommandStr) \
137 case Command::aName: \
138 return "Command::" #aName;
139 #define NS_DEFINE_COMMAND_WITH_PARAM(aName, aCommandStr, aParam) \
140 case Command::aName: \
141 return "Command::" #aName;
142 #define NS_DEFINE_COMMAND_NO_EXEC_COMMAND(aName) \
143 case Command::aName: \
144 return "Command::" #aName;
146 #include "mozilla/CommandList.h"
148 #undef NS_DEFINE_COMMAND
149 #undef NS_DEFINE_COMMAND_WITH_PARAM
150 #undef NS_DEFINE_COMMAND_NO_EXEC_COMMAND
153 return "illegal command value";
157 const nsCString
GetDOMKeyCodeName(uint32_t aKeyCode
) {
159 #define NS_DISALLOW_SAME_KEYCODE
160 #define NS_DEFINE_VK(aDOMKeyName, aDOMKeyCode) \
162 return nsLiteralCString(#aDOMKeyName);
164 #include "mozilla/VirtualKeyCodeList.h"
167 #undef NS_DISALLOW_SAME_KEYCODE
170 return nsPrintfCString("Invalid DOM keyCode (0x%08X)", aKeyCode
);
174 bool IsValidRawTextRangeValue(RawTextRangeType aRawTextRangeType
) {
175 switch (static_cast<TextRangeType
>(aRawTextRangeType
)) {
176 case TextRangeType::eUninitialized
:
177 case TextRangeType::eCaret
:
178 case TextRangeType::eRawClause
:
179 case TextRangeType::eSelectedRawClause
:
180 case TextRangeType::eConvertedClause
:
181 case TextRangeType::eSelectedClause
:
188 RawTextRangeType
ToRawTextRangeType(TextRangeType aTextRangeType
) {
189 return static_cast<RawTextRangeType
>(aTextRangeType
);
192 TextRangeType
ToTextRangeType(RawTextRangeType aRawTextRangeType
) {
193 MOZ_ASSERT(IsValidRawTextRangeValue(aRawTextRangeType
));
194 return static_cast<TextRangeType
>(aRawTextRangeType
);
197 const char* ToChar(TextRangeType aTextRangeType
) {
198 switch (aTextRangeType
) {
199 case TextRangeType::eUninitialized
:
200 return "TextRangeType::eUninitialized";
201 case TextRangeType::eCaret
:
202 return "TextRangeType::eCaret";
203 case TextRangeType::eRawClause
:
204 return "TextRangeType::eRawClause";
205 case TextRangeType::eSelectedRawClause
:
206 return "TextRangeType::eSelectedRawClause";
207 case TextRangeType::eConvertedClause
:
208 return "TextRangeType::eConvertedClause";
209 case TextRangeType::eSelectedClause
:
210 return "TextRangeType::eSelectedClause";
212 return "Invalid TextRangeType";
216 SelectionType
ToSelectionType(TextRangeType aTextRangeType
) {
217 switch (aTextRangeType
) {
218 case TextRangeType::eRawClause
:
219 return SelectionType::eIMERawClause
;
220 case TextRangeType::eSelectedRawClause
:
221 return SelectionType::eIMESelectedRawClause
;
222 case TextRangeType::eConvertedClause
:
223 return SelectionType::eIMEConvertedClause
;
224 case TextRangeType::eSelectedClause
:
225 return SelectionType::eIMESelectedClause
;
227 MOZ_CRASH("TextRangeType is invalid");
228 return SelectionType::eNormal
;
232 /******************************************************************************
233 * non class method implementation
234 ******************************************************************************/
236 static nsTHashMap
<nsDepCharHashKey
, Command
>* sCommandHashtable
= nullptr;
238 Command
GetInternalCommand(const char* aCommandName
,
239 const nsCommandParams
* aCommandParams
) {
241 return Command::DoNothing
;
244 // Special cases for "cmd_align". It's mapped to multiple internal commands
245 // with additional param. Therefore, we cannot handle it with the hashtable.
246 if (!strcmp(aCommandName
, "cmd_align")) {
247 if (!aCommandParams
) {
248 // Note that if this is called by EditorCommand::IsCommandEnabled(),
249 // it cannot set aCommandParams. So, don't warn in this case even though
250 // this is illegal case for DoCommandParams().
251 return Command::FormatJustify
;
253 nsAutoCString cValue
;
254 nsresult rv
= aCommandParams
->GetCString("state_attribute", cValue
);
256 nsString value
; // Avoid copying the string buffer with using nsString.
257 rv
= aCommandParams
->GetString("state_attribute", value
);
259 return Command::FormatJustifyNone
;
261 CopyUTF16toUTF8(value
, cValue
);
263 if (cValue
.LowerCaseEqualsASCII("left")) {
264 return Command::FormatJustifyLeft
;
266 if (cValue
.LowerCaseEqualsASCII("right")) {
267 return Command::FormatJustifyRight
;
269 if (cValue
.LowerCaseEqualsASCII("center")) {
270 return Command::FormatJustifyCenter
;
272 if (cValue
.LowerCaseEqualsASCII("justify")) {
273 return Command::FormatJustifyFull
;
275 if (cValue
.IsEmpty()) {
276 return Command::FormatJustifyNone
;
278 return Command::DoNothing
;
281 if (!sCommandHashtable
) {
282 sCommandHashtable
= new nsTHashMap
<nsDepCharHashKey
, Command
>();
283 #define NS_DEFINE_COMMAND(aName, aCommandStr) \
284 sCommandHashtable->InsertOrUpdate(#aCommandStr, Command::aName);
286 #define NS_DEFINE_COMMAND_WITH_PARAM(aName, aCommandStr, aParam)
288 #define NS_DEFINE_COMMAND_NO_EXEC_COMMAND(aName)
290 #include "mozilla/CommandList.h"
292 #undef NS_DEFINE_COMMAND
293 #undef NS_DEFINE_COMMAND_WITH_PARAM
294 #undef NS_DEFINE_COMMAND_NO_EXEC_COMMAND
296 Command command
= Command::DoNothing
;
297 if (!sCommandHashtable
->Get(aCommandName
, &command
)) {
298 return Command::DoNothing
;
303 /******************************************************************************
304 * As*Event() implementation
305 ******************************************************************************/
307 #define NS_ROOT_EVENT_CLASS(aPrefix, aName)
308 #define NS_EVENT_CLASS(aPrefix, aName) \
309 aPrefix##aName* WidgetEvent::As##aName() { return nullptr; } \
311 const aPrefix##aName* WidgetEvent::As##aName() const { \
312 return const_cast<WidgetEvent*>(this)->As##aName(); \
315 #include "mozilla/EventClassList.h"
317 #undef NS_EVENT_CLASS
318 #undef NS_ROOT_EVENT_CLASS
320 /******************************************************************************
321 * mozilla::WidgetEvent
323 * Event struct type checking methods.
324 ******************************************************************************/
326 bool WidgetEvent::IsQueryContentEvent() const {
327 return mClass
== eQueryContentEventClass
;
330 bool WidgetEvent::IsSelectionEvent() const {
331 return mClass
== eSelectionEventClass
;
334 bool WidgetEvent::IsContentCommandEvent() const {
335 return mClass
== eContentCommandEventClass
;
338 /******************************************************************************
339 * mozilla::WidgetEvent
341 * Event message checking methods.
342 ******************************************************************************/
344 bool WidgetEvent::HasMouseEventMessage() const {
348 case eMouseDoubleClick
:
349 case eMouseEnterIntoWidget
:
350 case eMouseExitFromWidget
:
357 // TODO: Perhaps, we should rename this method.
359 case ePointerAuxClick
:
366 bool WidgetEvent::IsMouseEventClassOrHasClickRelatedPointerEvent() const {
367 return mClass
== eMouseEventClass
||
368 IsPointerEventMessageOriginallyMouseEventMessage(mMessage
);
371 bool WidgetEvent::HasDragEventMessage() const {
388 bool WidgetEvent::IsKeyEventMessage(EventMessage aMessage
) {
393 case eAccessKeyNotFound
:
400 bool WidgetEvent::HasIMEEventMessage() const {
402 case eCompositionStart
:
403 case eCompositionEnd
:
404 case eCompositionUpdate
:
405 case eCompositionChange
:
406 case eCompositionCommitAsIs
:
407 case eCompositionCommit
:
414 /******************************************************************************
415 * mozilla::WidgetEvent
417 * Specific event checking methods.
418 ******************************************************************************/
420 bool WidgetEvent::CanBeSentToRemoteProcess() const {
421 // If this event is explicitly marked as shouldn't be sent to remote process,
422 // just return false.
423 if (IsCrossProcessForwardingStopped()) {
427 if (mClass
== eKeyboardEventClass
|| mClass
== eWheelEventClass
) {
435 case eMouseExploreByTouch
:
437 case eMouseEnterIntoWidget
:
438 case eMouseExitFromWidget
:
439 case eMouseTouchDrag
:
453 bool WidgetEvent::WillBeSentToRemoteProcess() const {
454 // This event won't be posted to remote process if it's already explicitly
456 if (IsCrossProcessForwardingStopped()) {
460 // When mOriginalTarget is nullptr, this method shouldn't be used.
461 if (NS_WARN_IF(!mOriginalTarget
)) {
465 return EventStateManager::IsTopLevelRemoteTarget(
466 nsIContent::FromEventTarget(mOriginalTarget
));
469 bool WidgetEvent::IsIMERelatedEvent() const {
470 return HasIMEEventMessage() || IsQueryContentEvent() || IsSelectionEvent();
473 bool WidgetEvent::IsUsingCoordinates() const {
474 const WidgetMouseEvent
* mouseEvent
= AsMouseEvent();
476 return !mouseEvent
->IsContextMenuKeyEvent();
478 return !HasKeyEventMessage() && !IsIMERelatedEvent() &&
479 !IsContentCommandEvent();
482 bool WidgetEvent::IsTargetedAtFocusedWindow() const {
483 const WidgetMouseEvent
* mouseEvent
= AsMouseEvent();
485 return mouseEvent
->IsContextMenuKeyEvent();
487 return HasKeyEventMessage() || IsIMERelatedEvent() || IsContentCommandEvent();
490 bool WidgetEvent::IsTargetedAtFocusedContent() const {
491 const WidgetMouseEvent
* mouseEvent
= AsMouseEvent();
493 return mouseEvent
->IsContextMenuKeyEvent();
495 return HasKeyEventMessage() || IsIMERelatedEvent();
498 bool WidgetEvent::IsAllowedToDispatchDOMEvent() const {
500 case eMouseEventClass
:
501 if (mMessage
== eMouseTouchDrag
) {
505 case ePointerEventClass
:
506 // We want synthesized mouse moves to cause mouseover and mouseout
507 // DOM events (EventStateManager::PreHandleEvent), but not mousemove
509 // Synthesized button up events also do not cause DOM events because they
510 // do not have a reliable mRefPoint.
511 return AsMouseEvent()->mReason
== WidgetMouseEvent::eReal
;
513 case eWheelEventClass
: {
514 // wheel event whose all delta values are zero by user pref applied, it
515 // shouldn't cause a DOM event.
516 const WidgetWheelEvent
* wheelEvent
= AsWheelEvent();
517 return wheelEvent
->mDeltaX
!= 0.0 || wheelEvent
->mDeltaY
!= 0.0 ||
518 wheelEvent
->mDeltaZ
!= 0.0;
520 case eTouchEventClass
:
521 return mMessage
!= eTouchPointerCancel
;
522 // Following events are handled in EventStateManager, so, we don't need to
523 // dispatch DOM event for them into the DOM tree.
524 case eQueryContentEventClass
:
525 case eSelectionEventClass
:
526 case eContentCommandEventClass
:
534 bool WidgetEvent::IsAllowedToDispatchInSystemGroup() const {
535 // We don't expect to implement default behaviors with pointer events because
536 // if we do, prevent default on mouse events can't prevent default behaviors
538 return mClass
!= ePointerEventClass
||
539 IsPointerEventMessageOriginallyMouseEventMessage(mMessage
);
542 bool WidgetEvent::IsBlockedForFingerprintingResistance() const {
544 case eKeyboardEventClass
: {
545 const WidgetKeyboardEvent
* keyboardEvent
= AsKeyboardEvent();
547 return (keyboardEvent
->mKeyNameIndex
== KEY_NAME_INDEX_Alt
||
548 keyboardEvent
->mKeyNameIndex
== KEY_NAME_INDEX_Shift
||
549 keyboardEvent
->mKeyNameIndex
== KEY_NAME_INDEX_Control
||
550 keyboardEvent
->mKeyNameIndex
== KEY_NAME_INDEX_AltGraph
);
552 case ePointerEventClass
: {
553 if (IsPointerEventMessageOriginallyMouseEventMessage(mMessage
)) {
557 const WidgetPointerEvent
* pointerEvent
= AsPointerEvent();
559 // We suppress the pointer events if it is not primary for fingerprinting
560 // resistance. It is because of that we want to spoof any pointer event
561 // into a mouse pointer event and the mouse pointer event only has
562 // isPrimary as true.
563 return !pointerEvent
->mIsPrimary
;
570 bool WidgetEvent::AllowFlushingPendingNotifications() const {
571 if (mClass
!= eQueryContentEventClass
) {
574 // If the dispatcher does not want a flush of pending notifications, it may
575 // be caused by that it's unsafe. Therefore, we should allow handlers to
576 // flush pending things only when the dispatcher requires the latest content
578 return AsQueryContentEvent()->mNeedsToFlushLayout
;
581 /******************************************************************************
582 * mozilla::WidgetEvent
585 ******************************************************************************/
587 static dom::EventTarget
* GetTargetForDOMEvent(dom::EventTarget
* aTarget
) {
588 return aTarget
? aTarget
->GetTargetForDOMEvent() : nullptr;
591 dom::EventTarget
* WidgetEvent::GetDOMEventTarget() const {
592 return GetTargetForDOMEvent(mTarget
);
595 dom::EventTarget
* WidgetEvent::GetCurrentDOMEventTarget() const {
596 return GetTargetForDOMEvent(mCurrentTarget
);
599 dom::EventTarget
* WidgetEvent::GetOriginalDOMEventTarget() const {
600 if (mOriginalTarget
) {
601 return GetTargetForDOMEvent(mOriginalTarget
);
603 return GetDOMEventTarget();
606 void WidgetEvent::PreventDefault(bool aCalledByDefaultHandler
,
607 nsIPrincipal
* aPrincipal
) {
608 if (mMessage
== ePointerDown
) {
609 if (aCalledByDefaultHandler
) {
610 // Shouldn't prevent default on pointerdown by default handlers to stop
611 // firing legacy mouse events. Use MOZ_ASSERT to catch incorrect usages
617 nsAutoString addonId
;
618 Unused
<< NS_WARN_IF(NS_FAILED(aPrincipal
->GetAddonId(addonId
)));
619 if (!addonId
.IsEmpty()) {
620 // Ignore the case that it's called by a web extension.
625 mFlags
.PreventDefault(aCalledByDefaultHandler
);
628 bool WidgetEvent::IsUserAction() const {
632 // FYI: eMouseScrollEventClass and ePointerEventClass represent
633 // user action but they are synthesized events.
635 case eKeyboardEventClass
:
636 case eCompositionEventClass
:
637 case eMouseScrollEventClass
:
638 case eWheelEventClass
:
639 case eGestureNotifyEventClass
:
640 case eSimpleGestureEventClass
:
641 case eTouchEventClass
:
642 case eCommandEventClass
:
643 case eContentCommandEventClass
:
645 case eMouseEventClass
:
646 case eDragEventClass
:
647 case ePointerEventClass
:
648 return AsMouseEvent()->IsReal();
654 /******************************************************************************
655 * mozilla::WidgetInputEvent
656 ******************************************************************************/
659 Modifier
WidgetInputEvent::GetModifier(const nsAString
& aDOMKeyName
) {
660 if (aDOMKeyName
.EqualsLiteral("Accel")) {
661 return AccelModifier();
663 KeyNameIndex keyNameIndex
= WidgetKeyboardEvent::GetKeyNameIndex(aDOMKeyName
);
664 return WidgetKeyboardEvent::GetModifierForKeyName(keyNameIndex
);
668 Modifier
WidgetInputEvent::AccelModifier() {
669 static Modifier sAccelModifier
= MODIFIER_NONE
;
670 if (sAccelModifier
== MODIFIER_NONE
) {
671 switch (StaticPrefs::ui_key_accelKey()) {
672 case dom::KeyboardEvent_Binding::DOM_VK_META
:
673 case dom::KeyboardEvent_Binding::DOM_VK_WIN
:
674 sAccelModifier
= MODIFIER_META
;
676 case dom::KeyboardEvent_Binding::DOM_VK_ALT
:
677 sAccelModifier
= MODIFIER_ALT
;
679 case dom::KeyboardEvent_Binding::DOM_VK_CONTROL
:
680 sAccelModifier
= MODIFIER_CONTROL
;
684 sAccelModifier
= MODIFIER_META
;
686 sAccelModifier
= MODIFIER_CONTROL
;
691 return sAccelModifier
;
694 /******************************************************************************
695 * mozilla::WidgetMouseEventBase (MouseEvents.h)
696 ******************************************************************************/
698 bool WidgetMouseEventBase::InputSourceSupportsHover() const {
699 switch (mInputSource
) {
700 case dom::MouseEvent_Binding::MOZ_SOURCE_MOUSE
:
701 case dom::MouseEvent_Binding::MOZ_SOURCE_PEN
:
702 case dom::MouseEvent_Binding::MOZ_SOURCE_ERASER
:
704 case dom::MouseEvent_Binding::MOZ_SOURCE_TOUCH
:
705 case dom::MouseEvent_Binding::MOZ_SOURCE_UNKNOWN
:
706 case dom::MouseEvent_Binding::MOZ_SOURCE_KEYBOARD
:
707 case dom::MouseEvent_Binding::MOZ_SOURCE_CURSOR
:
713 /******************************************************************************
714 * mozilla::WidgetMouseEvent (MouseEvents.h)
715 ******************************************************************************/
718 bool WidgetMouseEvent::IsMiddleClickPasteEnabled() {
719 return Preferences::GetBool("middlemouse.paste", false);
723 void WidgetMouseEvent::AssertContextMenuEventButtonConsistency() const {
724 if (mMessage
!= eContextMenu
) {
728 if (mContextMenuTrigger
== eNormal
) {
729 NS_WARNING_ASSERTION(mButton
== MouseButton::eSecondary
,
730 "eContextMenu events with eNormal trigger should use "
731 "secondary mouse button");
733 NS_WARNING_ASSERTION(mButton
== MouseButton::ePrimary
,
734 "eContextMenu events with non-eNormal trigger should "
735 "use primary mouse button");
738 if (mContextMenuTrigger
== eControlClick
) {
739 NS_WARNING_ASSERTION(IsControl(),
740 "eContextMenu events with eControlClick trigger "
741 "should return true from IsControl()");
746 /******************************************************************************
747 * mozilla::WidgetDragEvent (MouseEvents.h)
748 ******************************************************************************/
750 void WidgetDragEvent::InitDropEffectForTests() {
751 MOZ_ASSERT(mFlags
.mIsSynthesizedForTests
);
753 nsCOMPtr
<nsIDragSession
> session
= nsContentUtils::GetDragSession();
754 if (NS_WARN_IF(!session
)) {
758 uint32_t effectAllowed
= session
->GetEffectAllowedForTests();
759 uint32_t desiredDropEffect
= nsIDragService::DRAGDROP_ACTION_NONE
;
762 desiredDropEffect
= IsMeta() ? nsIDragService::DRAGDROP_ACTION_LINK
763 : nsIDragService::DRAGDROP_ACTION_COPY
;
766 // On Linux, we know user's intention from API, but we should use
767 // same modifiers as Windows for tests because GNOME on Ubuntu use
768 // them and that makes each test simpler.
770 desiredDropEffect
= IsShift() ? nsIDragService::DRAGDROP_ACTION_LINK
771 : nsIDragService::DRAGDROP_ACTION_COPY
;
772 } else if (IsShift()) {
773 desiredDropEffect
= nsIDragService::DRAGDROP_ACTION_MOVE
;
775 #endif // #ifdef XP_MACOSX #else
776 // First, use modifier state for preferring action which is explicitly
777 // specified by the synthesizer.
778 if (!(desiredDropEffect
&= effectAllowed
)) {
779 // Otherwise, use an action which is allowed at starting the session.
780 desiredDropEffect
= effectAllowed
;
782 if (desiredDropEffect
& nsIDragService::DRAGDROP_ACTION_MOVE
) {
783 session
->SetDragAction(nsIDragService::DRAGDROP_ACTION_MOVE
);
784 } else if (desiredDropEffect
& nsIDragService::DRAGDROP_ACTION_COPY
) {
785 session
->SetDragAction(nsIDragService::DRAGDROP_ACTION_COPY
);
786 } else if (desiredDropEffect
& nsIDragService::DRAGDROP_ACTION_LINK
) {
787 session
->SetDragAction(nsIDragService::DRAGDROP_ACTION_LINK
);
789 session
->SetDragAction(nsIDragService::DRAGDROP_ACTION_NONE
);
793 /******************************************************************************
794 * mozilla::WidgetWheelEvent (MouseEvents.h)
795 ******************************************************************************/
798 double WidgetWheelEvent::ComputeOverriddenDelta(double aDelta
,
799 bool aIsForVertical
) {
800 if (!StaticPrefs::mousewheel_system_scroll_override_enabled()) {
805 ? StaticPrefs::mousewheel_system_scroll_override_vertical_factor()
806 : StaticPrefs::mousewheel_system_scroll_override_horizontal_factor();
807 // Making the scroll speed slower doesn't make sense. So, ignore odd factor
808 // which is less than 1.0.
809 if (intFactor
<= 100) {
812 double factor
= static_cast<double>(intFactor
) / 100;
813 return aDelta
* factor
;
816 double WidgetWheelEvent::OverriddenDeltaX() const {
817 if (!mAllowToOverrideSystemScrollSpeed
||
818 mDeltaMode
!= dom::WheelEvent_Binding::DOM_DELTA_LINE
||
819 mCustomizedByUserPrefs
) {
822 return ComputeOverriddenDelta(mDeltaX
, false);
825 double WidgetWheelEvent::OverriddenDeltaY() const {
826 if (!mAllowToOverrideSystemScrollSpeed
||
827 mDeltaMode
!= dom::WheelEvent_Binding::DOM_DELTA_LINE
||
828 mCustomizedByUserPrefs
) {
831 return ComputeOverriddenDelta(mDeltaY
, true);
834 /******************************************************************************
835 * mozilla::WidgetKeyboardEvent (TextEvents.h)
836 ******************************************************************************/
838 #define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) (u"" aDOMKeyName),
839 const char16_t
* const WidgetKeyboardEvent::kKeyNames
[] = {
840 #include "mozilla/KeyNameList.h"
842 #undef NS_DEFINE_KEYNAME
844 #define NS_DEFINE_PHYSICAL_KEY_CODE_NAME(aCPPName, aDOMCodeName) \
846 const char16_t
* const WidgetKeyboardEvent::kCodeNames
[] = {
847 #include "mozilla/PhysicalKeyCodeNameList.h"
849 #undef NS_DEFINE_PHYSICAL_KEY_CODE_NAME
851 WidgetKeyboardEvent::KeyNameIndexHashtable
*
852 WidgetKeyboardEvent::sKeyNameIndexHashtable
= nullptr;
853 WidgetKeyboardEvent::CodeNameIndexHashtable
*
854 WidgetKeyboardEvent::sCodeNameIndexHashtable
= nullptr;
856 void WidgetKeyboardEvent::InitAllEditCommands(
857 const Maybe
<WritingMode
>& aWritingMode
) {
858 // If this event is synthesized for tests, we don't need to retrieve the
859 // command via the main process. So, we don't need widget and can trust
861 if (!mFlags
.mIsSynthesizedForTests
) {
862 // If the event was created without widget, e.g., created event in chrome
863 // script, this shouldn't execute native key bindings.
864 if (NS_WARN_IF(!mWidget
)) {
868 // This event should be trusted event here and we shouldn't expose native
869 // key binding information to web contents with untrusted events.
870 if (NS_WARN_IF(!IsTrusted())) {
875 XRE_IsParentProcess(),
876 "It's too expensive to retrieve all edit commands from remote process");
877 MOZ_ASSERT(!AreAllEditCommandsInitialized(),
878 "Shouldn't be called two or more times");
881 DebugOnly
<bool> okIgnored
= InitEditCommandsFor(
882 NativeKeyBindingsType::SingleLineEditor
, aWritingMode
);
883 NS_WARNING_ASSERTION(okIgnored
,
884 "InitEditCommandsFor(NativeKeyBindingsType::"
885 "SingleLineEditor) failed, but ignored");
887 InitEditCommandsFor(NativeKeyBindingsType::MultiLineEditor
, aWritingMode
);
888 NS_WARNING_ASSERTION(okIgnored
,
889 "InitEditCommandsFor(NativeKeyBindingsType::"
890 "MultiLineEditor) failed, but ignored");
892 InitEditCommandsFor(NativeKeyBindingsType::RichTextEditor
, aWritingMode
);
893 NS_WARNING_ASSERTION(okIgnored
,
894 "InitEditCommandsFor(NativeKeyBindingsType::"
895 "RichTextEditor) failed, but ignored");
898 bool WidgetKeyboardEvent::InitEditCommandsFor(
899 NativeKeyBindingsType aType
, const Maybe
<WritingMode
>& aWritingMode
) {
900 bool& initialized
= IsEditCommandsInitializedRef(aType
);
904 nsTArray
<CommandInt
>& commands
= EditCommandsRef(aType
);
906 // If this event is synthesized for tests, we shouldn't access customized
907 // shortcut settings of the environment. Therefore, we don't need to check
908 // whether `widget` is set or not. And we can treat synthesized events are
910 if (mFlags
.mIsSynthesizedForTests
) {
911 MOZ_DIAGNOSTIC_ASSERT(IsTrusted());
912 #if defined(MOZ_WIDGET_GTK) || defined(XP_MACOSX)
913 // TODO: We should implement `NativeKeyBindings` for Windows and Android
914 // too in bug 1301497 for getting rid of the #if.
915 widget::NativeKeyBindings::GetEditCommandsForTests(aType
, *this,
916 aWritingMode
, commands
);
922 if (NS_WARN_IF(!mWidget
) || NS_WARN_IF(!IsTrusted())) {
925 // `nsIWidget::GetEditCommands()` will retrieve `WritingMode` at selection
926 // again, but it should be almost zero-cost since `TextEventDispatcher`
928 nsCOMPtr
<nsIWidget
> widget
= mWidget
;
929 initialized
= widget
->GetEditCommands(aType
, *this, commands
);
933 bool WidgetKeyboardEvent::ExecuteEditCommands(NativeKeyBindingsType aType
,
934 DoCommandCallback aCallback
,
935 void* aCallbackData
) {
936 // If the event was created without widget, e.g., created event in chrome
937 // script, this shouldn't execute native key bindings.
938 if (NS_WARN_IF(!mWidget
)) {
942 // This event should be trusted event here and we shouldn't expose native
943 // key binding information to web contents with untrusted events.
944 if (NS_WARN_IF(!IsTrusted())) {
948 if (!IsEditCommandsInitializedRef(aType
)) {
949 Maybe
<WritingMode
> writingMode
;
950 if (RefPtr
<widget::TextEventDispatcher
> textEventDispatcher
=
951 mWidget
->GetTextEventDispatcher()) {
952 writingMode
= textEventDispatcher
->MaybeQueryWritingModeAtSelection();
954 if (NS_WARN_IF(!InitEditCommandsFor(aType
, writingMode
))) {
959 const nsTArray
<CommandInt
>& commands
= EditCommandsRef(aType
);
960 if (commands
.IsEmpty()) {
964 for (CommandInt command
: commands
) {
965 aCallback(static_cast<Command
>(command
), aCallbackData
);
970 bool WidgetKeyboardEvent::ShouldCauseKeypressEvents() const {
971 // Currently, we don't dispatch keypress events of modifier keys and
973 switch (mKeyNameIndex
) {
974 case KEY_NAME_INDEX_Alt
:
975 case KEY_NAME_INDEX_AltGraph
:
976 case KEY_NAME_INDEX_CapsLock
:
977 case KEY_NAME_INDEX_Control
:
978 case KEY_NAME_INDEX_Fn
:
979 case KEY_NAME_INDEX_FnLock
:
980 // case KEY_NAME_INDEX_Hyper:
981 case KEY_NAME_INDEX_Meta
:
982 case KEY_NAME_INDEX_NumLock
:
983 case KEY_NAME_INDEX_ScrollLock
:
984 case KEY_NAME_INDEX_Shift
:
985 // case KEY_NAME_INDEX_Super:
986 case KEY_NAME_INDEX_Symbol
:
987 case KEY_NAME_INDEX_SymbolLock
:
988 case KEY_NAME_INDEX_Dead
:
995 static bool HasASCIIDigit(const ShortcutKeyCandidateArray
& aCandidates
) {
996 for (uint32_t i
= 0; i
< aCandidates
.Length(); ++i
) {
997 uint32_t ch
= aCandidates
[i
].mCharCode
;
998 if (ch
>= '0' && ch
<= '9') return true;
1003 static bool CharsCaseInsensitiveEqual(uint32_t aChar1
, uint32_t aChar2
) {
1004 return aChar1
== aChar2
|| (IS_IN_BMP(aChar1
) && IS_IN_BMP(aChar2
) &&
1005 ToLowerCase(static_cast<char16_t
>(aChar1
)) ==
1006 ToLowerCase(static_cast<char16_t
>(aChar2
)));
1009 static bool IsCaseChangeableChar(uint32_t aChar
) {
1010 return IS_IN_BMP(aChar
) && ToLowerCase(static_cast<char16_t
>(aChar
)) !=
1011 ToUpperCase(static_cast<char16_t
>(aChar
));
1014 void WidgetKeyboardEvent::GetShortcutKeyCandidates(
1015 ShortcutKeyCandidateArray
& aCandidates
) const {
1016 MOZ_ASSERT(aCandidates
.IsEmpty(), "aCandidates must be empty");
1018 using ShiftState
= ShortcutKeyCandidate::ShiftState
;
1019 using SkipIfEarlierHandlerDisabled
=
1020 ShortcutKeyCandidate::SkipIfEarlierHandlerDisabled
;
1022 // ShortcutKeyCandidate::mCharCode is a candidate charCode.
1023 // ShortcutKeyCandidate::mShiftState means the mCharCode should be tried to
1024 // execute a command with/without shift key state. If this is Ignorable,
1025 // the shifted key state should be ignored. Otherwise, don't ignore the state.
1026 // the priority of the charCodes are (shift key is not pressed):
1027 // 0: PseudoCharCode()/ShiftState::MatchExactly,
1028 // 1: unshiftedCharCodes[0]/ShiftState::MatchExactly,
1029 // 2: unshiftedCharCodes[1]/ShiftState::MatchExactly...
1030 // the priority of the charCodes are (shift key is pressed):
1031 // 0: PseudoCharCode()/ShiftState::MatchExactly,
1032 // 1: shiftedCharCodes[0]/ShiftState::MatchExactly,
1033 // 2: shiftedCharCodes[0]/ShiftState::Ignorable,
1034 // 3: shiftedCharCodes[1]/ShiftState::MatchExactly,
1035 // 4: shiftedCharCodes[1]/ShiftState::Ignorable...
1036 uint32_t pseudoCharCode
= PseudoCharCode();
1037 if (pseudoCharCode
) {
1038 ShortcutKeyCandidate
key(pseudoCharCode
, ShiftState::MatchExactly
,
1039 SkipIfEarlierHandlerDisabled::No
);
1040 aCandidates
.AppendElement(key
);
1043 uint32_t len
= mAlternativeCharCodes
.Length();
1045 for (uint32_t i
= 0; i
< len
; ++i
) {
1046 uint32_t ch
= mAlternativeCharCodes
[i
].mUnshiftedCharCode
;
1047 if (!ch
|| ch
== pseudoCharCode
) {
1050 ShortcutKeyCandidate
key(ch
, ShiftState::MatchExactly
,
1051 SkipIfEarlierHandlerDisabled::No
);
1052 aCandidates
.AppendElement(key
);
1054 // If unshiftedCharCodes doesn't have numeric but shiftedCharCode has it,
1055 // this keyboard layout is AZERTY or similar layout, probably.
1056 // In this case, Accel+[0-9] should be accessible without shift key.
1057 // However, the priority should be lowest.
1058 if (!HasASCIIDigit(aCandidates
)) {
1059 for (uint32_t i
= 0; i
< len
; ++i
) {
1060 uint32_t ch
= mAlternativeCharCodes
[i
].mShiftedCharCode
;
1061 if (ch
>= '0' && ch
<= '9') {
1062 ShortcutKeyCandidate
key(
1063 ch
, ShiftState::MatchExactly
,
1064 // Ctrl + `-` in the French keyboard layout should not match with
1065 // Ctrl + `6` shortcut when it's already fully zoomed out.
1066 SkipIfEarlierHandlerDisabled::Yes
);
1067 aCandidates
.AppendElement(key
);
1073 for (uint32_t i
= 0; i
< len
; ++i
) {
1074 uint32_t ch
= mAlternativeCharCodes
[i
].mShiftedCharCode
;
1079 if (ch
!= pseudoCharCode
) {
1080 ShortcutKeyCandidate
key(ch
, ShiftState::MatchExactly
,
1081 SkipIfEarlierHandlerDisabled::No
);
1082 aCandidates
.AppendElement(key
);
1085 // If the char is an alphabet, the shift key state should not be
1086 // ignored. E.g., Ctrl+Shift+C should not execute Ctrl+C.
1088 // And checking the charCode is same as unshiftedCharCode too.
1089 // E.g., for Ctrl+Shift+(Plus of Numpad) should not run Ctrl+Plus.
1090 uint32_t unshiftCh
= mAlternativeCharCodes
[i
].mUnshiftedCharCode
;
1091 if (CharsCaseInsensitiveEqual(ch
, unshiftCh
)) {
1095 // On the Hebrew keyboard layout on Windows, the unshifted char is a
1096 // localized character but the shifted char is a Latin alphabet,
1097 // then, we should not execute without the shift state. See bug 433192.
1098 if (IsCaseChangeableChar(ch
)) {
1102 // Setting the alternative charCode candidates for retry without shift
1103 // key state only when the shift key is pressed.
1104 ShortcutKeyCandidate
key(ch
, ShiftState::Ignorable
,
1105 SkipIfEarlierHandlerDisabled::No
);
1106 aCandidates
.AppendElement(key
);
1110 // Special case for "Space" key. With some keyboard layouts, "Space" with
1111 // or without Shift key causes non-ASCII space. For such keyboard layouts,
1112 // we should guarantee that the key press works as an ASCII white space key
1113 // press. However, if the space key is assigned to a function key, it
1114 // shouldn't work as a space key.
1115 if (mKeyNameIndex
== KEY_NAME_INDEX_USE_STRING
&&
1116 mCodeNameIndex
== CODE_NAME_INDEX_Space
&& pseudoCharCode
!= ' ') {
1117 ShortcutKeyCandidate
spaceKey(' ', ShiftState::MatchExactly
,
1118 SkipIfEarlierHandlerDisabled::No
);
1119 aCandidates
.AppendElement(spaceKey
);
1123 void WidgetKeyboardEvent::GetAccessKeyCandidates(
1124 nsTArray
<uint32_t>& aCandidates
) const {
1125 MOZ_ASSERT(aCandidates
.IsEmpty(), "aCandidates must be empty");
1127 // return the lower cased charCode candidates for access keys.
1128 // the priority of the charCodes are:
1129 // 0: charCode, 1: unshiftedCharCodes[0], 2: shiftedCharCodes[0]
1130 // 3: unshiftedCharCodes[1], 4: shiftedCharCodes[1],...
1131 uint32_t pseudoCharCode
= PseudoCharCode();
1132 if (pseudoCharCode
) {
1133 uint32_t ch
= pseudoCharCode
;
1134 if (IS_IN_BMP(ch
)) {
1135 ch
= ToLowerCase(static_cast<char16_t
>(ch
));
1137 aCandidates
.AppendElement(ch
);
1139 for (uint32_t i
= 0; i
< mAlternativeCharCodes
.Length(); ++i
) {
1140 uint32_t ch
[2] = {mAlternativeCharCodes
[i
].mUnshiftedCharCode
,
1141 mAlternativeCharCodes
[i
].mShiftedCharCode
};
1142 for (uint32_t j
= 0; j
< 2; ++j
) {
1146 if (IS_IN_BMP(ch
[j
])) {
1147 ch
[j
] = ToLowerCase(static_cast<char16_t
>(ch
[j
]));
1149 // Don't append the charcode that was already appended.
1150 if (aCandidates
.IndexOf(ch
[j
]) == aCandidates
.NoIndex
) {
1151 aCandidates
.AppendElement(ch
[j
]);
1155 // Special case for "Space" key. With some keyboard layouts, "Space" with
1156 // or without Shift key causes non-ASCII space. For such keyboard layouts,
1157 // we should guarantee that the key press works as an ASCII white space key
1158 // press. However, if the space key is assigned to a function key, it
1159 // shouldn't work as a space key.
1160 if (mKeyNameIndex
== KEY_NAME_INDEX_USE_STRING
&&
1161 mCodeNameIndex
== CODE_NAME_INDEX_Space
&& pseudoCharCode
!= ' ') {
1162 aCandidates
.AppendElement(' ');
1166 // mask values for ui.key.chromeAccess and ui.key.contentAccess
1167 #define NS_MODIFIER_SHIFT 1
1168 #define NS_MODIFIER_CONTROL 2
1169 #define NS_MODIFIER_ALT 4
1170 #define NS_MODIFIER_META 8
1172 static Modifiers
PrefFlagsToModifiers(int32_t aPrefFlags
) {
1173 Modifiers result
= 0;
1174 if (aPrefFlags
& NS_MODIFIER_SHIFT
) {
1175 result
|= MODIFIER_SHIFT
;
1177 if (aPrefFlags
& NS_MODIFIER_CONTROL
) {
1178 result
|= MODIFIER_CONTROL
;
1180 if (aPrefFlags
& NS_MODIFIER_ALT
) {
1181 result
|= MODIFIER_ALT
;
1183 if (aPrefFlags
& NS_MODIFIER_META
) {
1184 result
|= MODIFIER_META
;
1189 bool WidgetKeyboardEvent::ModifiersMatchWithAccessKey(
1190 AccessKeyType aType
) const {
1191 if (!ModifiersForAccessKeyMatching()) {
1194 return ModifiersForAccessKeyMatching() == AccessKeyModifiers(aType
);
1197 Modifiers
WidgetKeyboardEvent::ModifiersForAccessKeyMatching() const {
1198 static const Modifiers kModifierMask
=
1199 MODIFIER_SHIFT
| MODIFIER_CONTROL
| MODIFIER_ALT
| MODIFIER_META
;
1200 return mModifiers
& kModifierMask
;
1204 Modifiers
WidgetKeyboardEvent::AccessKeyModifiers(AccessKeyType aType
) {
1205 switch (StaticPrefs::ui_key_generalAccessKey()) {
1207 break; // use the individual prefs
1209 return MODIFIER_SHIFT
;
1211 return MODIFIER_CONTROL
;
1213 return MODIFIER_ALT
;
1216 return MODIFIER_META
;
1218 return MODIFIER_NONE
;
1222 case AccessKeyType::eChrome
:
1223 return PrefFlagsToModifiers(StaticPrefs::ui_key_chromeAccess());
1224 case AccessKeyType::eContent
:
1225 return PrefFlagsToModifiers(StaticPrefs::ui_key_contentAccess());
1227 return MODIFIER_NONE
;
1232 void WidgetKeyboardEvent::Shutdown() {
1233 delete sKeyNameIndexHashtable
;
1234 sKeyNameIndexHashtable
= nullptr;
1235 delete sCodeNameIndexHashtable
;
1236 sCodeNameIndexHashtable
= nullptr;
1237 // Although sCommandHashtable is not a member of WidgetKeyboardEvent, but
1238 // let's delete it here since we need to do it at same time.
1239 delete sCommandHashtable
;
1240 sCommandHashtable
= nullptr;
1244 void WidgetKeyboardEvent::GetDOMKeyName(KeyNameIndex aKeyNameIndex
,
1245 nsAString
& aKeyName
) {
1246 if (aKeyNameIndex
>= KEY_NAME_INDEX_USE_STRING
) {
1247 aKeyName
.Truncate();
1252 static_cast<size_t>(aKeyNameIndex
) < ArrayLength(kKeyNames
),
1253 "Illegal key enumeration value");
1254 aKeyName
= kKeyNames
[aKeyNameIndex
];
1258 void WidgetKeyboardEvent::GetDOMCodeName(CodeNameIndex aCodeNameIndex
,
1259 nsAString
& aCodeName
) {
1260 if (aCodeNameIndex
>= CODE_NAME_INDEX_USE_STRING
) {
1261 aCodeName
.Truncate();
1266 static_cast<size_t>(aCodeNameIndex
) < ArrayLength(kCodeNames
),
1267 "Illegal physical code enumeration value");
1269 // Generate some continuous runs of codes, rather than looking them up.
1270 if (aCodeNameIndex
>= CODE_NAME_INDEX_KeyA
&&
1271 aCodeNameIndex
<= CODE_NAME_INDEX_KeyZ
) {
1272 uint32_t index
= aCodeNameIndex
- CODE_NAME_INDEX_KeyA
;
1273 aCodeName
.AssignLiteral(u
"Key");
1274 aCodeName
.Append(u
'A' + index
);
1277 if (aCodeNameIndex
>= CODE_NAME_INDEX_Digit0
&&
1278 aCodeNameIndex
<= CODE_NAME_INDEX_Digit9
) {
1279 uint32_t index
= aCodeNameIndex
- CODE_NAME_INDEX_Digit0
;
1280 aCodeName
.AssignLiteral(u
"Digit");
1281 aCodeName
.AppendInt(index
);
1284 if (aCodeNameIndex
>= CODE_NAME_INDEX_Numpad0
&&
1285 aCodeNameIndex
<= CODE_NAME_INDEX_Numpad9
) {
1286 uint32_t index
= aCodeNameIndex
- CODE_NAME_INDEX_Numpad0
;
1287 aCodeName
.AssignLiteral(u
"Numpad");
1288 aCodeName
.AppendInt(index
);
1291 if (aCodeNameIndex
>= CODE_NAME_INDEX_F1
&&
1292 aCodeNameIndex
<= CODE_NAME_INDEX_F24
) {
1293 uint32_t index
= aCodeNameIndex
- CODE_NAME_INDEX_F1
;
1294 aCodeName
.Assign(u
'F');
1295 aCodeName
.AppendInt(index
+ 1);
1299 aCodeName
= kCodeNames
[aCodeNameIndex
];
1303 KeyNameIndex
WidgetKeyboardEvent::GetKeyNameIndex(const nsAString
& aKeyValue
) {
1304 if (!sKeyNameIndexHashtable
) {
1305 sKeyNameIndexHashtable
= new KeyNameIndexHashtable(ArrayLength(kKeyNames
));
1306 for (size_t i
= 0; i
< ArrayLength(kKeyNames
); i
++) {
1307 sKeyNameIndexHashtable
->InsertOrUpdate(nsDependentString(kKeyNames
[i
]),
1308 static_cast<KeyNameIndex
>(i
));
1311 return sKeyNameIndexHashtable
->MaybeGet(aKeyValue
).valueOr(
1312 KEY_NAME_INDEX_USE_STRING
);
1316 CodeNameIndex
WidgetKeyboardEvent::GetCodeNameIndex(
1317 const nsAString
& aCodeValue
) {
1318 if (!sCodeNameIndexHashtable
) {
1319 sCodeNameIndexHashtable
=
1320 new CodeNameIndexHashtable(ArrayLength(kCodeNames
));
1321 for (size_t i
= 0; i
< ArrayLength(kCodeNames
); i
++) {
1322 sCodeNameIndexHashtable
->InsertOrUpdate(nsDependentString(kCodeNames
[i
]),
1323 static_cast<CodeNameIndex
>(i
));
1326 return sCodeNameIndexHashtable
->MaybeGet(aCodeValue
)
1327 .valueOr(CODE_NAME_INDEX_USE_STRING
);
1331 uint32_t WidgetKeyboardEvent::GetFallbackKeyCodeOfPunctuationKey(
1332 CodeNameIndex aCodeNameIndex
) {
1333 switch (aCodeNameIndex
) {
1334 case CODE_NAME_INDEX_Semicolon
: // VK_OEM_1 on Windows
1335 return dom::KeyboardEvent_Binding::DOM_VK_SEMICOLON
;
1336 case CODE_NAME_INDEX_Equal
: // VK_OEM_PLUS on Windows
1337 return dom::KeyboardEvent_Binding::DOM_VK_EQUALS
;
1338 case CODE_NAME_INDEX_Comma
: // VK_OEM_COMMA on Windows
1339 return dom::KeyboardEvent_Binding::DOM_VK_COMMA
;
1340 case CODE_NAME_INDEX_Minus
: // VK_OEM_MINUS on Windows
1341 return dom::KeyboardEvent_Binding::DOM_VK_HYPHEN_MINUS
;
1342 case CODE_NAME_INDEX_Period
: // VK_OEM_PERIOD on Windows
1343 return dom::KeyboardEvent_Binding::DOM_VK_PERIOD
;
1344 case CODE_NAME_INDEX_Slash
: // VK_OEM_2 on Windows
1345 return dom::KeyboardEvent_Binding::DOM_VK_SLASH
;
1346 case CODE_NAME_INDEX_Backquote
: // VK_OEM_3 on Windows
1347 return dom::KeyboardEvent_Binding::DOM_VK_BACK_QUOTE
;
1348 case CODE_NAME_INDEX_BracketLeft
: // VK_OEM_4 on Windows
1349 return dom::KeyboardEvent_Binding::DOM_VK_OPEN_BRACKET
;
1350 case CODE_NAME_INDEX_Backslash
: // VK_OEM_5 on Windows
1351 return dom::KeyboardEvent_Binding::DOM_VK_BACK_SLASH
;
1352 case CODE_NAME_INDEX_BracketRight
: // VK_OEM_6 on Windows
1353 return dom::KeyboardEvent_Binding::DOM_VK_CLOSE_BRACKET
;
1354 case CODE_NAME_INDEX_Quote
: // VK_OEM_7 on Windows
1355 return dom::KeyboardEvent_Binding::DOM_VK_QUOTE
;
1356 case CODE_NAME_INDEX_IntlBackslash
: // VK_OEM_5 on Windows (ABNT, etc)
1357 case CODE_NAME_INDEX_IntlYen
: // VK_OEM_5 on Windows (JIS)
1358 case CODE_NAME_INDEX_IntlRo
: // VK_OEM_102 on Windows
1359 return dom::KeyboardEvent_Binding::DOM_VK_BACK_SLASH
;
1365 /* static */ const char* WidgetKeyboardEvent::GetCommandStr(Command aCommand
) {
1366 #define NS_DEFINE_COMMAND(aName, aCommandStr) , #aCommandStr
1367 #define NS_DEFINE_COMMAND_WITH_PARAM(aName, aCommandStr, aParam) , #aCommandStr
1368 #define NS_DEFINE_COMMAND_NO_EXEC_COMMAND(aName) , ""
1369 static const char* const kCommands
[] = {
1371 #include "mozilla/CommandList.h"
1373 #undef NS_DEFINE_COMMAND
1374 #undef NS_DEFINE_COMMAND_WITH_PARAM
1375 #undef NS_DEFINE_COMMAND_NO_EXEC_COMMAND
1377 MOZ_RELEASE_ASSERT(static_cast<size_t>(aCommand
) < ArrayLength(kCommands
),
1378 "Illegal command enumeration value");
1379 return kCommands
[static_cast<CommandInt
>(aCommand
)];
1383 uint32_t WidgetKeyboardEvent::ComputeLocationFromCodeValue(
1384 CodeNameIndex aCodeNameIndex
) {
1385 // Following commented out cases are not defined in PhysicalKeyCodeNameList.h
1386 // but are defined by D3E spec. So, they should be uncommented when the
1387 // code values are defined in the header.
1388 switch (aCodeNameIndex
) {
1389 case CODE_NAME_INDEX_AltLeft
:
1390 case CODE_NAME_INDEX_ControlLeft
:
1391 case CODE_NAME_INDEX_MetaLeft
:
1392 case CODE_NAME_INDEX_ShiftLeft
:
1393 return eKeyLocationLeft
;
1394 case CODE_NAME_INDEX_AltRight
:
1395 case CODE_NAME_INDEX_ControlRight
:
1396 case CODE_NAME_INDEX_MetaRight
:
1397 case CODE_NAME_INDEX_ShiftRight
:
1398 return eKeyLocationRight
;
1399 case CODE_NAME_INDEX_Numpad0
:
1400 case CODE_NAME_INDEX_Numpad1
:
1401 case CODE_NAME_INDEX_Numpad2
:
1402 case CODE_NAME_INDEX_Numpad3
:
1403 case CODE_NAME_INDEX_Numpad4
:
1404 case CODE_NAME_INDEX_Numpad5
:
1405 case CODE_NAME_INDEX_Numpad6
:
1406 case CODE_NAME_INDEX_Numpad7
:
1407 case CODE_NAME_INDEX_Numpad8
:
1408 case CODE_NAME_INDEX_Numpad9
:
1409 case CODE_NAME_INDEX_NumpadAdd
:
1410 case CODE_NAME_INDEX_NumpadBackspace
:
1411 case CODE_NAME_INDEX_NumpadClear
:
1412 case CODE_NAME_INDEX_NumpadClearEntry
:
1413 case CODE_NAME_INDEX_NumpadComma
:
1414 case CODE_NAME_INDEX_NumpadDecimal
:
1415 case CODE_NAME_INDEX_NumpadDivide
:
1416 case CODE_NAME_INDEX_NumpadEnter
:
1417 case CODE_NAME_INDEX_NumpadEqual
:
1418 case CODE_NAME_INDEX_NumpadMemoryAdd
:
1419 case CODE_NAME_INDEX_NumpadMemoryClear
:
1420 case CODE_NAME_INDEX_NumpadMemoryRecall
:
1421 case CODE_NAME_INDEX_NumpadMemoryStore
:
1422 case CODE_NAME_INDEX_NumpadMemorySubtract
:
1423 case CODE_NAME_INDEX_NumpadMultiply
:
1424 case CODE_NAME_INDEX_NumpadParenLeft
:
1425 case CODE_NAME_INDEX_NumpadParenRight
:
1426 case CODE_NAME_INDEX_NumpadSubtract
:
1427 return eKeyLocationNumpad
;
1429 return eKeyLocationStandard
;
1434 uint32_t WidgetKeyboardEvent::ComputeKeyCodeFromKeyNameIndex(
1435 KeyNameIndex aKeyNameIndex
) {
1436 switch (aKeyNameIndex
) {
1437 case KEY_NAME_INDEX_Cancel
:
1438 return dom::KeyboardEvent_Binding::DOM_VK_CANCEL
;
1439 case KEY_NAME_INDEX_Help
:
1440 return dom::KeyboardEvent_Binding::DOM_VK_HELP
;
1441 case KEY_NAME_INDEX_Backspace
:
1442 return dom::KeyboardEvent_Binding::DOM_VK_BACK_SPACE
;
1443 case KEY_NAME_INDEX_Tab
:
1444 return dom::KeyboardEvent_Binding::DOM_VK_TAB
;
1445 case KEY_NAME_INDEX_Clear
:
1446 return dom::KeyboardEvent_Binding::DOM_VK_CLEAR
;
1447 case KEY_NAME_INDEX_Enter
:
1448 return dom::KeyboardEvent_Binding::DOM_VK_RETURN
;
1449 case KEY_NAME_INDEX_Shift
:
1450 return dom::KeyboardEvent_Binding::DOM_VK_SHIFT
;
1451 case KEY_NAME_INDEX_Control
:
1452 return dom::KeyboardEvent_Binding::DOM_VK_CONTROL
;
1453 case KEY_NAME_INDEX_Alt
:
1454 return dom::KeyboardEvent_Binding::DOM_VK_ALT
;
1455 case KEY_NAME_INDEX_Pause
:
1456 return dom::KeyboardEvent_Binding::DOM_VK_PAUSE
;
1457 case KEY_NAME_INDEX_CapsLock
:
1458 return dom::KeyboardEvent_Binding::DOM_VK_CAPS_LOCK
;
1459 case KEY_NAME_INDEX_Hiragana
:
1460 case KEY_NAME_INDEX_Katakana
:
1461 case KEY_NAME_INDEX_HiraganaKatakana
:
1462 case KEY_NAME_INDEX_KanaMode
:
1463 return dom::KeyboardEvent_Binding::DOM_VK_KANA
;
1464 case KEY_NAME_INDEX_HangulMode
:
1465 return dom::KeyboardEvent_Binding::DOM_VK_HANGUL
;
1466 case KEY_NAME_INDEX_Eisu
:
1467 return dom::KeyboardEvent_Binding::DOM_VK_EISU
;
1468 case KEY_NAME_INDEX_JunjaMode
:
1469 return dom::KeyboardEvent_Binding::DOM_VK_JUNJA
;
1470 case KEY_NAME_INDEX_FinalMode
:
1471 return dom::KeyboardEvent_Binding::DOM_VK_FINAL
;
1472 case KEY_NAME_INDEX_HanjaMode
:
1473 return dom::KeyboardEvent_Binding::DOM_VK_HANJA
;
1474 case KEY_NAME_INDEX_KanjiMode
:
1475 return dom::KeyboardEvent_Binding::DOM_VK_KANJI
;
1476 case KEY_NAME_INDEX_Escape
:
1477 return dom::KeyboardEvent_Binding::DOM_VK_ESCAPE
;
1478 case KEY_NAME_INDEX_Convert
:
1479 return dom::KeyboardEvent_Binding::DOM_VK_CONVERT
;
1480 case KEY_NAME_INDEX_NonConvert
:
1481 return dom::KeyboardEvent_Binding::DOM_VK_NONCONVERT
;
1482 case KEY_NAME_INDEX_Accept
:
1483 return dom::KeyboardEvent_Binding::DOM_VK_ACCEPT
;
1484 case KEY_NAME_INDEX_ModeChange
:
1485 return dom::KeyboardEvent_Binding::DOM_VK_MODECHANGE
;
1486 case KEY_NAME_INDEX_PageUp
:
1487 return dom::KeyboardEvent_Binding::DOM_VK_PAGE_UP
;
1488 case KEY_NAME_INDEX_PageDown
:
1489 return dom::KeyboardEvent_Binding::DOM_VK_PAGE_DOWN
;
1490 case KEY_NAME_INDEX_End
:
1491 return dom::KeyboardEvent_Binding::DOM_VK_END
;
1492 case KEY_NAME_INDEX_Home
:
1493 return dom::KeyboardEvent_Binding::DOM_VK_HOME
;
1494 case KEY_NAME_INDEX_ArrowLeft
:
1495 return dom::KeyboardEvent_Binding::DOM_VK_LEFT
;
1496 case KEY_NAME_INDEX_ArrowUp
:
1497 return dom::KeyboardEvent_Binding::DOM_VK_UP
;
1498 case KEY_NAME_INDEX_ArrowRight
:
1499 return dom::KeyboardEvent_Binding::DOM_VK_RIGHT
;
1500 case KEY_NAME_INDEX_ArrowDown
:
1501 return dom::KeyboardEvent_Binding::DOM_VK_DOWN
;
1502 case KEY_NAME_INDEX_Select
:
1503 return dom::KeyboardEvent_Binding::DOM_VK_SELECT
;
1504 case KEY_NAME_INDEX_Print
:
1505 return dom::KeyboardEvent_Binding::DOM_VK_PRINT
;
1506 case KEY_NAME_INDEX_Execute
:
1507 return dom::KeyboardEvent_Binding::DOM_VK_EXECUTE
;
1508 case KEY_NAME_INDEX_PrintScreen
:
1509 return dom::KeyboardEvent_Binding::DOM_VK_PRINTSCREEN
;
1510 case KEY_NAME_INDEX_Insert
:
1511 return dom::KeyboardEvent_Binding::DOM_VK_INSERT
;
1512 case KEY_NAME_INDEX_Delete
:
1513 return dom::KeyboardEvent_Binding::DOM_VK_DELETE
;
1514 case KEY_NAME_INDEX_ContextMenu
:
1515 return dom::KeyboardEvent_Binding::DOM_VK_CONTEXT_MENU
;
1516 case KEY_NAME_INDEX_Standby
:
1517 return dom::KeyboardEvent_Binding::DOM_VK_SLEEP
;
1518 case KEY_NAME_INDEX_F1
:
1519 return dom::KeyboardEvent_Binding::DOM_VK_F1
;
1520 case KEY_NAME_INDEX_F2
:
1521 return dom::KeyboardEvent_Binding::DOM_VK_F2
;
1522 case KEY_NAME_INDEX_F3
:
1523 return dom::KeyboardEvent_Binding::DOM_VK_F3
;
1524 case KEY_NAME_INDEX_F4
:
1525 return dom::KeyboardEvent_Binding::DOM_VK_F4
;
1526 case KEY_NAME_INDEX_F5
:
1527 return dom::KeyboardEvent_Binding::DOM_VK_F5
;
1528 case KEY_NAME_INDEX_F6
:
1529 return dom::KeyboardEvent_Binding::DOM_VK_F6
;
1530 case KEY_NAME_INDEX_F7
:
1531 return dom::KeyboardEvent_Binding::DOM_VK_F7
;
1532 case KEY_NAME_INDEX_F8
:
1533 return dom::KeyboardEvent_Binding::DOM_VK_F8
;
1534 case KEY_NAME_INDEX_F9
:
1535 return dom::KeyboardEvent_Binding::DOM_VK_F9
;
1536 case KEY_NAME_INDEX_F10
:
1537 return dom::KeyboardEvent_Binding::DOM_VK_F10
;
1538 case KEY_NAME_INDEX_F11
:
1539 return dom::KeyboardEvent_Binding::DOM_VK_F11
;
1540 case KEY_NAME_INDEX_F12
:
1541 return dom::KeyboardEvent_Binding::DOM_VK_F12
;
1542 case KEY_NAME_INDEX_F13
:
1543 return dom::KeyboardEvent_Binding::DOM_VK_F13
;
1544 case KEY_NAME_INDEX_F14
:
1545 return dom::KeyboardEvent_Binding::DOM_VK_F14
;
1546 case KEY_NAME_INDEX_F15
:
1547 return dom::KeyboardEvent_Binding::DOM_VK_F15
;
1548 case KEY_NAME_INDEX_F16
:
1549 return dom::KeyboardEvent_Binding::DOM_VK_F16
;
1550 case KEY_NAME_INDEX_F17
:
1551 return dom::KeyboardEvent_Binding::DOM_VK_F17
;
1552 case KEY_NAME_INDEX_F18
:
1553 return dom::KeyboardEvent_Binding::DOM_VK_F18
;
1554 case KEY_NAME_INDEX_F19
:
1555 return dom::KeyboardEvent_Binding::DOM_VK_F19
;
1556 case KEY_NAME_INDEX_F20
:
1557 return dom::KeyboardEvent_Binding::DOM_VK_F20
;
1558 case KEY_NAME_INDEX_F21
:
1559 return dom::KeyboardEvent_Binding::DOM_VK_F21
;
1560 case KEY_NAME_INDEX_F22
:
1561 return dom::KeyboardEvent_Binding::DOM_VK_F22
;
1562 case KEY_NAME_INDEX_F23
:
1563 return dom::KeyboardEvent_Binding::DOM_VK_F23
;
1564 case KEY_NAME_INDEX_F24
:
1565 return dom::KeyboardEvent_Binding::DOM_VK_F24
;
1566 case KEY_NAME_INDEX_NumLock
:
1567 return dom::KeyboardEvent_Binding::DOM_VK_NUM_LOCK
;
1568 case KEY_NAME_INDEX_ScrollLock
:
1569 return dom::KeyboardEvent_Binding::DOM_VK_SCROLL_LOCK
;
1570 case KEY_NAME_INDEX_AudioVolumeMute
:
1571 return dom::KeyboardEvent_Binding::DOM_VK_VOLUME_MUTE
;
1572 case KEY_NAME_INDEX_AudioVolumeDown
:
1573 return dom::KeyboardEvent_Binding::DOM_VK_VOLUME_DOWN
;
1574 case KEY_NAME_INDEX_AudioVolumeUp
:
1575 return dom::KeyboardEvent_Binding::DOM_VK_VOLUME_UP
;
1576 case KEY_NAME_INDEX_Meta
:
1577 #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
1578 return dom::KeyboardEvent_Binding::DOM_VK_WIN
;
1580 return dom::KeyboardEvent_Binding::DOM_VK_META
;
1582 case KEY_NAME_INDEX_AltGraph
:
1583 return dom::KeyboardEvent_Binding::DOM_VK_ALTGR
;
1584 case KEY_NAME_INDEX_Process
:
1585 return dom::KeyboardEvent_Binding::DOM_VK_PROCESSKEY
;
1586 case KEY_NAME_INDEX_Attn
:
1587 return dom::KeyboardEvent_Binding::DOM_VK_ATTN
;
1588 case KEY_NAME_INDEX_CrSel
:
1589 return dom::KeyboardEvent_Binding::DOM_VK_CRSEL
;
1590 case KEY_NAME_INDEX_ExSel
:
1591 return dom::KeyboardEvent_Binding::DOM_VK_EXSEL
;
1592 case KEY_NAME_INDEX_EraseEof
:
1593 return dom::KeyboardEvent_Binding::DOM_VK_EREOF
;
1594 case KEY_NAME_INDEX_Play
:
1595 return dom::KeyboardEvent_Binding::DOM_VK_PLAY
;
1596 case KEY_NAME_INDEX_ZoomToggle
:
1597 case KEY_NAME_INDEX_ZoomIn
:
1598 case KEY_NAME_INDEX_ZoomOut
:
1599 return dom::KeyboardEvent_Binding::DOM_VK_ZOOM
;
1606 CodeNameIndex
WidgetKeyboardEvent::ComputeCodeNameIndexFromKeyNameIndex(
1607 KeyNameIndex aKeyNameIndex
, const Maybe
<uint32_t>& aLocation
) {
1608 if (aLocation
.isSome() &&
1609 aLocation
.value() ==
1610 dom::KeyboardEvent_Binding::DOM_KEY_LOCATION_NUMPAD
) {
1611 // On macOS, NumLock is not supported. Therefore, this handles
1612 // control key values except "Enter" only on non-macOS platforms.
1613 switch (aKeyNameIndex
) {
1615 case KEY_NAME_INDEX_Insert
:
1616 return CODE_NAME_INDEX_Numpad0
;
1617 case KEY_NAME_INDEX_End
:
1618 return CODE_NAME_INDEX_Numpad1
;
1619 case KEY_NAME_INDEX_ArrowDown
:
1620 return CODE_NAME_INDEX_Numpad2
;
1621 case KEY_NAME_INDEX_PageDown
:
1622 return CODE_NAME_INDEX_Numpad3
;
1623 case KEY_NAME_INDEX_ArrowLeft
:
1624 return CODE_NAME_INDEX_Numpad4
;
1625 case KEY_NAME_INDEX_Clear
:
1626 // FYI: "Clear" on macOS should be DOM_KEY_LOCATION_STANDARD.
1627 return CODE_NAME_INDEX_Numpad5
;
1628 case KEY_NAME_INDEX_ArrowRight
:
1629 return CODE_NAME_INDEX_Numpad6
;
1630 case KEY_NAME_INDEX_Home
:
1631 return CODE_NAME_INDEX_Numpad7
;
1632 case KEY_NAME_INDEX_ArrowUp
:
1633 return CODE_NAME_INDEX_Numpad8
;
1634 case KEY_NAME_INDEX_PageUp
:
1635 return CODE_NAME_INDEX_Numpad9
;
1636 case KEY_NAME_INDEX_Delete
:
1637 return CODE_NAME_INDEX_NumpadDecimal
;
1638 #endif // #ifndef XP_MACOSX
1639 case KEY_NAME_INDEX_Enter
:
1640 return CODE_NAME_INDEX_NumpadEnter
;
1642 return CODE_NAME_INDEX_UNKNOWN
;
1646 if (WidgetKeyboardEvent::IsLeftOrRightModiferKeyNameIndex(aKeyNameIndex
)) {
1647 if (aLocation
.isSome() &&
1648 (aLocation
.value() !=
1649 dom::KeyboardEvent_Binding::DOM_KEY_LOCATION_LEFT
&&
1650 aLocation
.value() !=
1651 dom::KeyboardEvent_Binding::DOM_KEY_LOCATION_RIGHT
)) {
1652 return CODE_NAME_INDEX_UNKNOWN
;
1655 aLocation
.isSome() &&
1656 aLocation
.value() == dom::KeyboardEvent_Binding::DOM_KEY_LOCATION_RIGHT
;
1657 switch (aKeyNameIndex
) {
1658 case KEY_NAME_INDEX_Alt
:
1659 return isRight
? CODE_NAME_INDEX_AltRight
: CODE_NAME_INDEX_AltLeft
;
1660 case KEY_NAME_INDEX_Control
:
1661 return isRight
? CODE_NAME_INDEX_ControlRight
1662 : CODE_NAME_INDEX_ControlLeft
;
1663 case KEY_NAME_INDEX_Shift
:
1664 return isRight
? CODE_NAME_INDEX_ShiftRight
: CODE_NAME_INDEX_ShiftLeft
;
1665 case KEY_NAME_INDEX_Meta
:
1666 return isRight
? CODE_NAME_INDEX_MetaRight
: CODE_NAME_INDEX_MetaLeft
;
1668 return CODE_NAME_INDEX_UNKNOWN
;
1672 if (aLocation
.isSome() &&
1673 aLocation
.value() !=
1674 dom::KeyboardEvent_Binding::DOM_KEY_LOCATION_STANDARD
) {
1675 return CODE_NAME_INDEX_UNKNOWN
;
1678 switch (aKeyNameIndex
) {
1679 // Standard section:
1680 case KEY_NAME_INDEX_Escape
:
1681 return CODE_NAME_INDEX_Escape
;
1682 case KEY_NAME_INDEX_Tab
:
1683 return CODE_NAME_INDEX_Tab
;
1684 case KEY_NAME_INDEX_CapsLock
:
1685 return CODE_NAME_INDEX_CapsLock
;
1686 case KEY_NAME_INDEX_ContextMenu
:
1687 return CODE_NAME_INDEX_ContextMenu
;
1688 case KEY_NAME_INDEX_Backspace
:
1689 return CODE_NAME_INDEX_Backspace
;
1690 case KEY_NAME_INDEX_Enter
:
1691 return CODE_NAME_INDEX_Enter
;
1693 // Although, macOS does not fire native key event of "Fn" key, we support
1694 // Fn key event if it's sent by other apps directly.
1695 case KEY_NAME_INDEX_Fn
:
1696 return CODE_NAME_INDEX_Fn
;
1699 // Arrow Pad section:
1700 case KEY_NAME_INDEX_ArrowLeft
:
1701 return CODE_NAME_INDEX_ArrowLeft
;
1702 case KEY_NAME_INDEX_ArrowUp
:
1703 return CODE_NAME_INDEX_ArrowUp
;
1704 case KEY_NAME_INDEX_ArrowDown
:
1705 return CODE_NAME_INDEX_ArrowDown
;
1706 case KEY_NAME_INDEX_ArrowRight
:
1707 return CODE_NAME_INDEX_ArrowRight
;
1709 // Control Pad section:
1711 case KEY_NAME_INDEX_Insert
:
1712 return CODE_NAME_INDEX_Insert
;
1714 case KEY_NAME_INDEX_Help
:
1715 return CODE_NAME_INDEX_Help
;
1716 #endif // #ifndef XP_MACOSX #else
1717 case KEY_NAME_INDEX_Delete
:
1718 return CODE_NAME_INDEX_Delete
;
1719 case KEY_NAME_INDEX_Home
:
1720 return CODE_NAME_INDEX_Home
;
1721 case KEY_NAME_INDEX_End
:
1722 return CODE_NAME_INDEX_End
;
1723 case KEY_NAME_INDEX_PageUp
:
1724 return CODE_NAME_INDEX_PageUp
;
1725 case KEY_NAME_INDEX_PageDown
:
1726 return CODE_NAME_INDEX_PageDown
;
1729 case KEY_NAME_INDEX_F1
:
1730 return CODE_NAME_INDEX_F1
;
1731 case KEY_NAME_INDEX_F2
:
1732 return CODE_NAME_INDEX_F2
;
1733 case KEY_NAME_INDEX_F3
:
1734 return CODE_NAME_INDEX_F3
;
1735 case KEY_NAME_INDEX_F4
:
1736 return CODE_NAME_INDEX_F4
;
1737 case KEY_NAME_INDEX_F5
:
1738 return CODE_NAME_INDEX_F5
;
1739 case KEY_NAME_INDEX_F6
:
1740 return CODE_NAME_INDEX_F6
;
1741 case KEY_NAME_INDEX_F7
:
1742 return CODE_NAME_INDEX_F7
;
1743 case KEY_NAME_INDEX_F8
:
1744 return CODE_NAME_INDEX_F8
;
1745 case KEY_NAME_INDEX_F9
:
1746 return CODE_NAME_INDEX_F9
;
1747 case KEY_NAME_INDEX_F10
:
1748 return CODE_NAME_INDEX_F10
;
1749 case KEY_NAME_INDEX_F11
:
1750 return CODE_NAME_INDEX_F11
;
1751 case KEY_NAME_INDEX_F12
:
1752 return CODE_NAME_INDEX_F12
;
1753 case KEY_NAME_INDEX_F13
:
1754 return CODE_NAME_INDEX_F13
;
1755 case KEY_NAME_INDEX_F14
:
1756 return CODE_NAME_INDEX_F14
;
1757 case KEY_NAME_INDEX_F15
:
1758 return CODE_NAME_INDEX_F15
;
1759 case KEY_NAME_INDEX_F16
:
1760 return CODE_NAME_INDEX_F16
;
1761 case KEY_NAME_INDEX_F17
:
1762 return CODE_NAME_INDEX_F17
;
1763 case KEY_NAME_INDEX_F18
:
1764 return CODE_NAME_INDEX_F18
;
1765 case KEY_NAME_INDEX_F19
:
1766 return CODE_NAME_INDEX_F19
;
1767 case KEY_NAME_INDEX_F20
:
1768 return CODE_NAME_INDEX_F20
;
1770 case KEY_NAME_INDEX_F21
:
1771 return CODE_NAME_INDEX_F21
;
1772 case KEY_NAME_INDEX_F22
:
1773 return CODE_NAME_INDEX_F22
;
1774 case KEY_NAME_INDEX_F23
:
1775 return CODE_NAME_INDEX_F23
;
1776 case KEY_NAME_INDEX_F24
:
1777 return CODE_NAME_INDEX_F24
;
1778 case KEY_NAME_INDEX_Pause
:
1779 return CODE_NAME_INDEX_Pause
;
1780 case KEY_NAME_INDEX_PrintScreen
:
1781 return CODE_NAME_INDEX_PrintScreen
;
1782 case KEY_NAME_INDEX_ScrollLock
:
1783 return CODE_NAME_INDEX_ScrollLock
;
1784 #endif // #ifndef XP_MACOSX
1788 case KEY_NAME_INDEX_NumLock
:
1789 return CODE_NAME_INDEX_NumLock
;
1791 case KEY_NAME_INDEX_Clear
:
1792 return CODE_NAME_INDEX_NumLock
;
1793 #endif // #ifndef XP_MACOSX #else
1796 case KEY_NAME_INDEX_AudioVolumeDown
:
1797 return CODE_NAME_INDEX_VolumeDown
;
1798 case KEY_NAME_INDEX_AudioVolumeMute
:
1799 return CODE_NAME_INDEX_VolumeMute
;
1800 case KEY_NAME_INDEX_AudioVolumeUp
:
1801 return CODE_NAME_INDEX_VolumeUp
;
1803 case KEY_NAME_INDEX_BrowserBack
:
1804 return CODE_NAME_INDEX_BrowserBack
;
1805 case KEY_NAME_INDEX_BrowserFavorites
:
1806 return CODE_NAME_INDEX_BrowserFavorites
;
1807 case KEY_NAME_INDEX_BrowserForward
:
1808 return CODE_NAME_INDEX_BrowserForward
;
1809 case KEY_NAME_INDEX_BrowserRefresh
:
1810 return CODE_NAME_INDEX_BrowserRefresh
;
1811 case KEY_NAME_INDEX_BrowserSearch
:
1812 return CODE_NAME_INDEX_BrowserSearch
;
1813 case KEY_NAME_INDEX_BrowserStop
:
1814 return CODE_NAME_INDEX_BrowserStop
;
1815 case KEY_NAME_INDEX_MediaPlayPause
:
1816 return CODE_NAME_INDEX_MediaPlayPause
;
1817 case KEY_NAME_INDEX_MediaStop
:
1818 return CODE_NAME_INDEX_MediaStop
;
1819 case KEY_NAME_INDEX_MediaTrackNext
:
1820 return CODE_NAME_INDEX_MediaTrackNext
;
1821 case KEY_NAME_INDEX_MediaTrackPrevious
:
1822 return CODE_NAME_INDEX_MediaTrackPrevious
;
1823 case KEY_NAME_INDEX_LaunchApplication1
:
1824 return CODE_NAME_INDEX_LaunchApp1
;
1825 #endif // #ifndef XP_MACOSX
1827 // Only Windows and GTK supports the following multimedia keys.
1828 #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
1829 case KEY_NAME_INDEX_BrowserHome
:
1830 return CODE_NAME_INDEX_BrowserHome
;
1831 case KEY_NAME_INDEX_LaunchApplication2
:
1832 return CODE_NAME_INDEX_LaunchApp2
;
1833 #endif // #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
1835 // Only GTK and Android supports the following multimedia keys.
1836 #if defined(MOZ_WIDGET_GTK) || defined(ANDROID)
1837 case KEY_NAME_INDEX_Eject
:
1838 return CODE_NAME_INDEX_Eject
;
1839 case KEY_NAME_INDEX_WakeUp
:
1840 return CODE_NAME_INDEX_WakeUp
;
1841 #endif // #if defined(MOZ_WIDGET_GTK) || defined(ANDROID)
1843 // Only Windows does not support Help key (and macOS handled above).
1844 #if !defined(XP_WIN) && !defined(XP_MACOSX)
1845 case KEY_NAME_INDEX_Help
:
1846 return CODE_NAME_INDEX_Help
;
1847 #endif // #if !defined(XP_WIN) && !defined(XP_MACOSX)
1849 // IME specific keys:
1851 case KEY_NAME_INDEX_Convert
:
1852 return CODE_NAME_INDEX_Convert
;
1853 case KEY_NAME_INDEX_NonConvert
:
1854 return CODE_NAME_INDEX_NonConvert
;
1855 case KEY_NAME_INDEX_Alphanumeric
:
1856 return CODE_NAME_INDEX_CapsLock
;
1857 case KEY_NAME_INDEX_KanaMode
:
1858 case KEY_NAME_INDEX_Romaji
:
1859 case KEY_NAME_INDEX_Katakana
:
1860 case KEY_NAME_INDEX_Hiragana
:
1861 return CODE_NAME_INDEX_KanaMode
;
1862 case KEY_NAME_INDEX_Hankaku
:
1863 case KEY_NAME_INDEX_Zenkaku
:
1864 case KEY_NAME_INDEX_KanjiMode
:
1865 return CODE_NAME_INDEX_Backquote
;
1866 case KEY_NAME_INDEX_HanjaMode
:
1867 return CODE_NAME_INDEX_Lang2
;
1868 case KEY_NAME_INDEX_HangulMode
:
1869 return CODE_NAME_INDEX_Lang1
;
1870 #endif // #ifdef XP_WIN
1872 #ifdef MOZ_WIDGET_GTK
1873 case KEY_NAME_INDEX_Convert
:
1874 return CODE_NAME_INDEX_Convert
;
1875 case KEY_NAME_INDEX_NonConvert
:
1876 return CODE_NAME_INDEX_NonConvert
;
1877 case KEY_NAME_INDEX_Alphanumeric
:
1878 return CODE_NAME_INDEX_CapsLock
;
1879 case KEY_NAME_INDEX_HiraganaKatakana
:
1880 return CODE_NAME_INDEX_KanaMode
;
1881 case KEY_NAME_INDEX_ZenkakuHankaku
:
1882 return CODE_NAME_INDEX_Backquote
;
1883 #endif // #ifdef MOZ_WIDGET_GTK
1886 case KEY_NAME_INDEX_Convert
:
1887 return CODE_NAME_INDEX_Convert
;
1888 case KEY_NAME_INDEX_NonConvert
:
1889 return CODE_NAME_INDEX_NonConvert
;
1890 case KEY_NAME_INDEX_HiraganaKatakana
:
1891 return CODE_NAME_INDEX_KanaMode
;
1892 case KEY_NAME_INDEX_ZenkakuHankaku
:
1893 return CODE_NAME_INDEX_Backquote
;
1894 case KEY_NAME_INDEX_Eisu
:
1895 return CODE_NAME_INDEX_Lang2
;
1896 case KEY_NAME_INDEX_KanjiMode
:
1897 return CODE_NAME_INDEX_Lang1
;
1898 #endif // #ifdef ANDROID
1901 case KEY_NAME_INDEX_Eisu
:
1902 return CODE_NAME_INDEX_Lang2
;
1903 case KEY_NAME_INDEX_KanjiMode
:
1904 return CODE_NAME_INDEX_Lang1
;
1905 #endif // #ifdef XP_MACOSX
1908 return CODE_NAME_INDEX_UNKNOWN
;
1913 Modifier
WidgetKeyboardEvent::GetModifierForKeyName(
1914 KeyNameIndex aKeyNameIndex
) {
1915 switch (aKeyNameIndex
) {
1916 case KEY_NAME_INDEX_Alt
:
1917 return MODIFIER_ALT
;
1918 case KEY_NAME_INDEX_AltGraph
:
1919 return MODIFIER_ALTGRAPH
;
1920 case KEY_NAME_INDEX_CapsLock
:
1921 return MODIFIER_CAPSLOCK
;
1922 case KEY_NAME_INDEX_Control
:
1923 return MODIFIER_CONTROL
;
1924 case KEY_NAME_INDEX_Fn
:
1926 case KEY_NAME_INDEX_FnLock
:
1927 return MODIFIER_FNLOCK
;
1928 // case KEY_NAME_INDEX_Hyper:
1929 case KEY_NAME_INDEX_Meta
:
1930 return MODIFIER_META
;
1931 case KEY_NAME_INDEX_NumLock
:
1932 return MODIFIER_NUMLOCK
;
1933 case KEY_NAME_INDEX_ScrollLock
:
1934 return MODIFIER_SCROLLLOCK
;
1935 case KEY_NAME_INDEX_Shift
:
1936 return MODIFIER_SHIFT
;
1937 // case KEY_NAME_INDEX_Super:
1938 case KEY_NAME_INDEX_Symbol
:
1939 return MODIFIER_SYMBOL
;
1940 case KEY_NAME_INDEX_SymbolLock
:
1941 return MODIFIER_SYMBOLLOCK
;
1943 return MODIFIER_NONE
;
1948 bool WidgetKeyboardEvent::IsLockableModifier(KeyNameIndex aKeyNameIndex
) {
1949 switch (aKeyNameIndex
) {
1950 case KEY_NAME_INDEX_CapsLock
:
1951 case KEY_NAME_INDEX_FnLock
:
1952 case KEY_NAME_INDEX_NumLock
:
1953 case KEY_NAME_INDEX_ScrollLock
:
1954 case KEY_NAME_INDEX_SymbolLock
:
1961 /******************************************************************************
1962 * mozilla::InternalEditorInputEvent (TextEvents.h)
1963 ******************************************************************************/
1965 #define NS_DEFINE_INPUTTYPE(aCPPName, aDOMName) (u"" aDOMName),
1966 const char16_t
* const InternalEditorInputEvent::kInputTypeNames
[] = {
1967 #include "mozilla/InputTypeList.h"
1969 #undef NS_DEFINE_INPUTTYPE
1971 InternalEditorInputEvent::InputTypeHashtable
*
1972 InternalEditorInputEvent::sInputTypeHashtable
= nullptr;
1975 void InternalEditorInputEvent::Shutdown() {
1976 delete sInputTypeHashtable
;
1977 sInputTypeHashtable
= nullptr;
1981 void InternalEditorInputEvent::GetDOMInputTypeName(EditorInputType aInputType
,
1982 nsAString
& aInputTypeName
) {
1983 if (static_cast<size_t>(aInputType
) >=
1984 static_cast<size_t>(EditorInputType::eUnknown
)) {
1985 aInputTypeName
.Truncate();
1990 static_cast<size_t>(aInputType
) < ArrayLength(kInputTypeNames
),
1991 "Illegal input type enumeration value");
1992 aInputTypeName
.Assign(kInputTypeNames
[static_cast<size_t>(aInputType
)]);
1996 EditorInputType
InternalEditorInputEvent::GetEditorInputType(
1997 const nsAString
& aInputType
) {
1998 if (aInputType
.IsEmpty()) {
1999 return EditorInputType::eUnknown
;
2002 if (!sInputTypeHashtable
) {
2003 sInputTypeHashtable
= new InputTypeHashtable(ArrayLength(kInputTypeNames
));
2004 for (size_t i
= 0; i
< ArrayLength(kInputTypeNames
); i
++) {
2005 sInputTypeHashtable
->InsertOrUpdate(nsDependentString(kInputTypeNames
[i
]),
2006 static_cast<EditorInputType
>(i
));
2009 return sInputTypeHashtable
->MaybeGet(aInputType
)
2010 .valueOr(EditorInputType::eUnknown
);
2013 } // namespace mozilla