Bug 1462329 [wpt PR 10991] - Server-Timing: test TAO:* for cross-origin resource...
[gecko.git] / widget / WidgetEventImpl.cpp
blob92fcc70a7aaf70f761f03ead17e0bdff564bbc39
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 "gfxPrefs.h"
7 #include "mozilla/BasicEvents.h"
8 #include "mozilla/ContentEvents.h"
9 #include "mozilla/EventStateManager.h"
10 #include "mozilla/InternalMutationEvent.h"
11 #include "mozilla/MiscEvents.h"
12 #include "mozilla/MouseEvents.h"
13 #include "mozilla/Preferences.h"
14 #include "mozilla/TextEvents.h"
15 #include "mozilla/TouchEvents.h"
16 #include "mozilla/dom/KeyboardEventBinding.h"
17 #include "nsContentUtils.h"
18 #include "nsIContent.h"
19 #include "nsPrintfCString.h"
21 namespace mozilla {
23 /******************************************************************************
24 * Global helper methods
25 ******************************************************************************/
27 const char*
28 ToChar(EventMessage aEventMessage)
30 switch (aEventMessage) {
32 #define NS_EVENT_MESSAGE(aMessage) \
33 case aMessage: \
34 return #aMessage;
36 #include "mozilla/EventMessageList.h"
38 #undef NS_EVENT_MESSAGE
39 default:
40 return "illegal event message";
44 const char*
45 ToChar(EventClassID aEventClassID)
47 switch (aEventClassID) {
49 #define NS_ROOT_EVENT_CLASS(aPrefix, aName) \
50 case eBasic##aName##Class: \
51 return "eBasic" #aName "Class";
53 #define NS_EVENT_CLASS(aPrefix, aName) \
54 case e##aName##Class: \
55 return "e" #aName "Class";
57 #include "mozilla/EventClassList.h"
59 #undef NS_EVENT_CLASS
60 #undef NS_ROOT_EVENT_CLASS
61 default:
62 return "illegal event class ID";
66 const nsCString
67 ToString(KeyNameIndex aKeyNameIndex)
69 if (aKeyNameIndex == KEY_NAME_INDEX_USE_STRING) {
70 return NS_LITERAL_CSTRING("USE_STRING");
72 nsAutoString keyName;
73 WidgetKeyboardEvent::GetDOMKeyName(aKeyNameIndex, keyName);
74 return NS_ConvertUTF16toUTF8(keyName);
77 const nsCString
78 ToString(CodeNameIndex aCodeNameIndex)
80 if (aCodeNameIndex == CODE_NAME_INDEX_USE_STRING) {
81 return NS_LITERAL_CSTRING("USE_STRING");
83 nsAutoString codeName;
84 WidgetKeyboardEvent::GetDOMCodeName(aCodeNameIndex, codeName);
85 return NS_ConvertUTF16toUTF8(codeName);
88 const char*
89 ToChar(Command aCommand)
91 if (aCommand == CommandDoNothing) {
92 return "CommandDoNothing";
95 switch (aCommand) {
97 #define NS_DEFINE_COMMAND(aName, aCommandStr) \
98 case Command##aName: \
99 return "Command" #aName;
100 #define NS_DEFINE_COMMAND_NO_EXEC_COMMAND(aName) \
101 case Command##aName: \
102 return "Command" #aName;
104 #include "mozilla/CommandList.h"
106 #undef NS_DEFINE_COMMAND
107 #undef NS_DEFINE_COMMAND_NO_EXEC_COMMAND
109 default:
110 return "illegal command value";
114 const nsCString
115 GetDOMKeyCodeName(uint32_t aKeyCode)
117 switch (aKeyCode) {
118 #define NS_DISALLOW_SAME_KEYCODE
119 #define NS_DEFINE_VK(aDOMKeyName, aDOMKeyCode) \
120 case aDOMKeyCode: \
121 return NS_LITERAL_CSTRING(#aDOMKeyName);
123 #include "mozilla/VirtualKeyCodeList.h"
125 #undef NS_DEFINE_VK
126 #undef NS_DISALLOW_SAME_KEYCODE
128 default:
129 return nsPrintfCString("Invalid DOM keyCode (0x%08X)", aKeyCode);
133 bool
134 IsValidRawTextRangeValue(RawTextRangeType aRawTextRangeType)
136 switch (static_cast<TextRangeType>(aRawTextRangeType)) {
137 case TextRangeType::eUninitialized:
138 case TextRangeType::eCaret:
139 case TextRangeType::eRawClause:
140 case TextRangeType::eSelectedRawClause:
141 case TextRangeType::eConvertedClause:
142 case TextRangeType::eSelectedClause:
143 return true;
144 default:
145 return false;
149 RawTextRangeType
150 ToRawTextRangeType(TextRangeType aTextRangeType)
152 return static_cast<RawTextRangeType>(aTextRangeType);
155 TextRangeType
156 ToTextRangeType(RawTextRangeType aRawTextRangeType)
158 MOZ_ASSERT(IsValidRawTextRangeValue(aRawTextRangeType));
159 return static_cast<TextRangeType>(aRawTextRangeType);
162 const char*
163 ToChar(TextRangeType aTextRangeType)
165 switch (aTextRangeType) {
166 case TextRangeType::eUninitialized:
167 return "TextRangeType::eUninitialized";
168 case TextRangeType::eCaret:
169 return "TextRangeType::eCaret";
170 case TextRangeType::eRawClause:
171 return "TextRangeType::eRawClause";
172 case TextRangeType::eSelectedRawClause:
173 return "TextRangeType::eSelectedRawClause";
174 case TextRangeType::eConvertedClause:
175 return "TextRangeType::eConvertedClause";
176 case TextRangeType::eSelectedClause:
177 return "TextRangeType::eSelectedClause";
178 default:
179 return "Invalid TextRangeType";
183 SelectionType
184 ToSelectionType(TextRangeType aTextRangeType)
186 switch (aTextRangeType) {
187 case TextRangeType::eRawClause:
188 return SelectionType::eIMERawClause;
189 case TextRangeType::eSelectedRawClause:
190 return SelectionType::eIMESelectedRawClause;
191 case TextRangeType::eConvertedClause:
192 return SelectionType::eIMEConvertedClause;
193 case TextRangeType::eSelectedClause:
194 return SelectionType::eIMESelectedClause;
195 default:
196 MOZ_CRASH("TextRangeType is invalid");
197 return SelectionType::eNormal;
201 /******************************************************************************
202 * As*Event() implementation
203 ******************************************************************************/
205 #define NS_ROOT_EVENT_CLASS(aPrefix, aName)
206 #define NS_EVENT_CLASS(aPrefix, aName) \
207 aPrefix##aName* \
208 WidgetEvent::As##aName() \
210 return nullptr; \
213 const aPrefix##aName* \
214 WidgetEvent::As##aName() const \
216 return const_cast<WidgetEvent*>(this)->As##aName(); \
219 #include "mozilla/EventClassList.h"
221 #undef NS_EVENT_CLASS
222 #undef NS_ROOT_EVENT_CLASS
224 /******************************************************************************
225 * mozilla::WidgetEvent
227 * Event struct type checking methods.
228 ******************************************************************************/
230 bool
231 WidgetEvent::IsQueryContentEvent() const
233 return mClass == eQueryContentEventClass;
236 bool
237 WidgetEvent::IsSelectionEvent() const
239 return mClass == eSelectionEventClass;
242 bool
243 WidgetEvent::IsContentCommandEvent() const
245 return mClass == eContentCommandEventClass;
248 bool
249 WidgetEvent::IsNativeEventDelivererForPlugin() const
251 return mClass == ePluginEventClass;
255 /******************************************************************************
256 * mozilla::WidgetEvent
258 * Event message checking methods.
259 ******************************************************************************/
261 bool
262 WidgetEvent::HasMouseEventMessage() const
264 switch (mMessage) {
265 case eMouseDown:
266 case eMouseUp:
267 case eMouseClick:
268 case eMouseDoubleClick:
269 case eMouseAuxClick:
270 case eMouseEnterIntoWidget:
271 case eMouseExitFromWidget:
272 case eMouseActivate:
273 case eMouseOver:
274 case eMouseOut:
275 case eMouseHitTest:
276 case eMouseMove:
277 return true;
278 default:
279 return false;
283 bool
284 WidgetEvent::HasDragEventMessage() const
286 switch (mMessage) {
287 case eDragEnter:
288 case eDragOver:
289 case eDragExit:
290 case eDrag:
291 case eDragEnd:
292 case eDragStart:
293 case eDrop:
294 case eDragLeave:
295 return true;
296 default:
297 return false;
301 /* static */
302 bool
303 WidgetEvent::IsKeyEventMessage(EventMessage aMessage)
305 switch (aMessage) {
306 case eKeyDown:
307 case eKeyPress:
308 case eKeyUp:
309 case eKeyDownOnPlugin:
310 case eKeyUpOnPlugin:
311 case eAccessKeyNotFound:
312 return true;
313 default:
314 return false;
318 bool
319 WidgetEvent::HasIMEEventMessage() const
321 switch (mMessage) {
322 case eCompositionStart:
323 case eCompositionEnd:
324 case eCompositionUpdate:
325 case eCompositionChange:
326 case eCompositionCommitAsIs:
327 case eCompositionCommit:
328 return true;
329 default:
330 return false;
334 bool
335 WidgetEvent::HasPluginActivationEventMessage() const
337 return mMessage == ePluginActivate ||
338 mMessage == ePluginFocus;
341 /******************************************************************************
342 * mozilla::WidgetEvent
344 * Specific event checking methods.
345 ******************************************************************************/
347 bool
348 WidgetEvent::CanBeSentToRemoteProcess() const
350 // If this event is explicitly marked as shouldn't be sent to remote process,
351 // just return false.
352 if (IsCrossProcessForwardingStopped()) {
353 return false;
356 if (mClass == eKeyboardEventClass ||
357 mClass == eWheelEventClass) {
358 return true;
361 switch (mMessage) {
362 case eMouseDown:
363 case eMouseUp:
364 case eMouseMove:
365 case eContextMenu:
366 case eMouseEnterIntoWidget:
367 case eMouseExitFromWidget:
368 case eMouseTouchDrag:
369 case eTouchStart:
370 case eTouchMove:
371 case eTouchEnd:
372 case eTouchCancel:
373 case eDragOver:
374 case eDragExit:
375 case eDrop:
376 return true;
377 default:
378 return false;
382 bool
383 WidgetEvent::WillBeSentToRemoteProcess() const
385 // This event won't be posted to remote process if it's already explicitly
386 // stopped.
387 if (IsCrossProcessForwardingStopped()) {
388 return false;
391 // When mOriginalTarget is nullptr, this method shouldn't be used.
392 if (NS_WARN_IF(!mOriginalTarget)) {
393 return false;
396 nsCOMPtr<nsIContent> originalTarget = do_QueryInterface(mOriginalTarget);
397 return EventStateManager::IsRemoteTarget(originalTarget);
400 bool
401 WidgetEvent::IsRetargetedNativeEventDelivererForPlugin() const
403 const WidgetPluginEvent* pluginEvent = AsPluginEvent();
404 return pluginEvent && pluginEvent->mRetargetToFocusedDocument;
407 bool
408 WidgetEvent::IsNonRetargetedNativeEventDelivererForPlugin() const
410 const WidgetPluginEvent* pluginEvent = AsPluginEvent();
411 return pluginEvent && !pluginEvent->mRetargetToFocusedDocument;
414 bool
415 WidgetEvent::IsIMERelatedEvent() const
417 return HasIMEEventMessage() || IsQueryContentEvent() || IsSelectionEvent();
420 bool
421 WidgetEvent::IsUsingCoordinates() const
423 const WidgetMouseEvent* mouseEvent = AsMouseEvent();
424 if (mouseEvent) {
425 return !mouseEvent->IsContextMenuKeyEvent();
427 return !HasKeyEventMessage() && !IsIMERelatedEvent() &&
428 !HasPluginActivationEventMessage() &&
429 !IsNativeEventDelivererForPlugin() &&
430 !IsContentCommandEvent();
433 bool
434 WidgetEvent::IsTargetedAtFocusedWindow() const
436 const WidgetMouseEvent* mouseEvent = AsMouseEvent();
437 if (mouseEvent) {
438 return mouseEvent->IsContextMenuKeyEvent();
440 return HasKeyEventMessage() || IsIMERelatedEvent() ||
441 IsContentCommandEvent() ||
442 IsRetargetedNativeEventDelivererForPlugin();
445 bool
446 WidgetEvent::IsTargetedAtFocusedContent() const
448 const WidgetMouseEvent* mouseEvent = AsMouseEvent();
449 if (mouseEvent) {
450 return mouseEvent->IsContextMenuKeyEvent();
452 return HasKeyEventMessage() || IsIMERelatedEvent() ||
453 IsRetargetedNativeEventDelivererForPlugin();
456 bool
457 WidgetEvent::IsAllowedToDispatchDOMEvent() const
459 switch (mClass) {
460 case eMouseEventClass:
461 if (mMessage == eMouseTouchDrag) {
462 return false;
464 MOZ_FALLTHROUGH;
465 case ePointerEventClass:
466 // We want synthesized mouse moves to cause mouseover and mouseout
467 // DOM events (EventStateManager::PreHandleEvent), but not mousemove
468 // DOM events.
469 // Synthesized button up events also do not cause DOM events because they
470 // do not have a reliable mRefPoint.
471 return AsMouseEvent()->mReason == WidgetMouseEvent::eReal;
473 case eWheelEventClass: {
474 // wheel event whose all delta values are zero by user pref applied, it
475 // shouldn't cause a DOM event.
476 const WidgetWheelEvent* wheelEvent = AsWheelEvent();
477 return wheelEvent->mDeltaX != 0.0 || wheelEvent->mDeltaY != 0.0 ||
478 wheelEvent->mDeltaZ != 0.0;
480 case eTouchEventClass:
481 return mMessage != eTouchPointerCancel;
482 // Following events are handled in EventStateManager, so, we don't need to
483 // dispatch DOM event for them into the DOM tree.
484 case eQueryContentEventClass:
485 case eSelectionEventClass:
486 case eContentCommandEventClass:
487 return false;
489 default:
490 return true;
494 bool
495 WidgetEvent::IsAllowedToDispatchInSystemGroup() const
497 // We don't expect to implement default behaviors with pointer events because
498 // if we do, prevent default on mouse events can't prevent default behaviors
499 // anymore.
500 return mClass != ePointerEventClass;
503 bool
504 WidgetEvent::IsBlockedForFingerprintingResistance() const
506 if (mClass == eKeyboardEventClass &&
507 nsContentUtils::ShouldResistFingerprinting()) {
508 const WidgetKeyboardEvent* keyboardEvent = AsKeyboardEvent();
510 if (keyboardEvent->mKeyNameIndex == KEY_NAME_INDEX_Alt ||
511 keyboardEvent->mKeyNameIndex == KEY_NAME_INDEX_Shift ||
512 keyboardEvent->mKeyNameIndex == KEY_NAME_INDEX_Control ||
513 keyboardEvent->mKeyNameIndex == KEY_NAME_INDEX_AltGraph) {
514 return true;
518 return false;
521 /******************************************************************************
522 * mozilla::WidgetEvent
524 * Misc methods.
525 ******************************************************************************/
527 static dom::EventTarget*
528 GetTargetForDOMEvent(dom::EventTarget* aTarget)
530 return aTarget ? aTarget->GetTargetForDOMEvent() : nullptr;
533 dom::EventTarget*
534 WidgetEvent::GetDOMEventTarget() const
536 return GetTargetForDOMEvent(mTarget);
539 dom::EventTarget*
540 WidgetEvent::GetCurrentDOMEventTarget() const
542 return GetTargetForDOMEvent(mCurrentTarget);
545 dom::EventTarget*
546 WidgetEvent::GetOriginalDOMEventTarget() const
548 if (mOriginalTarget) {
549 return GetTargetForDOMEvent(mOriginalTarget);
551 return GetDOMEventTarget();
554 void
555 WidgetEvent::PreventDefault(bool aCalledByDefaultHandler,
556 nsIPrincipal* aPrincipal)
558 if (mMessage == ePointerDown) {
559 if (aCalledByDefaultHandler) {
560 // Shouldn't prevent default on pointerdown by default handlers to stop
561 // firing legacy mouse events. Use MOZ_ASSERT to catch incorrect usages
562 // in debug builds.
563 MOZ_ASSERT(false);
564 return;
566 if (aPrincipal) {
567 nsAutoString addonId;
568 Unused << NS_WARN_IF(NS_FAILED(aPrincipal->GetAddonId(addonId)));
569 if (!addonId.IsEmpty()) {
570 // Ignore the case that it's called by a web extension.
571 return;
575 mFlags.PreventDefault(aCalledByDefaultHandler);
578 bool
579 WidgetEvent::IsUserAction() const
581 if (!IsTrusted()) {
582 return false;
584 // FYI: eMouseScrollEventClass and ePointerEventClass represent
585 // user action but they are synthesized events.
586 switch (mClass) {
587 case eKeyboardEventClass:
588 case eCompositionEventClass:
589 case eMouseScrollEventClass:
590 case eWheelEventClass:
591 case eGestureNotifyEventClass:
592 case eSimpleGestureEventClass:
593 case eTouchEventClass:
594 case eCommandEventClass:
595 case eContentCommandEventClass:
596 case ePluginEventClass:
597 return true;
598 case eMouseEventClass:
599 case eDragEventClass:
600 case ePointerEventClass:
601 return AsMouseEvent()->IsReal();
602 default:
603 return false;
607 /******************************************************************************
608 * mozilla::WidgetInputEvent
609 ******************************************************************************/
611 /* static */
612 Modifier
613 WidgetInputEvent::GetModifier(const nsAString& aDOMKeyName)
615 if (aDOMKeyName.EqualsLiteral("Accel")) {
616 return AccelModifier();
618 KeyNameIndex keyNameIndex = WidgetKeyboardEvent::GetKeyNameIndex(aDOMKeyName);
619 return WidgetKeyboardEvent::GetModifierForKeyName(keyNameIndex);
622 /* static */
623 Modifier
624 WidgetInputEvent::AccelModifier()
626 static Modifier sAccelModifier = MODIFIER_NONE;
627 if (sAccelModifier == MODIFIER_NONE) {
628 switch (Preferences::GetInt("ui.key.accelKey", 0)) {
629 case dom::KeyboardEventBinding::DOM_VK_META:
630 sAccelModifier = MODIFIER_META;
631 break;
632 case dom::KeyboardEventBinding::DOM_VK_WIN:
633 sAccelModifier = MODIFIER_OS;
634 break;
635 case dom::KeyboardEventBinding::DOM_VK_ALT:
636 sAccelModifier = MODIFIER_ALT;
637 break;
638 case dom::KeyboardEventBinding::DOM_VK_CONTROL:
639 sAccelModifier = MODIFIER_CONTROL;
640 break;
641 default:
642 #ifdef XP_MACOSX
643 sAccelModifier = MODIFIER_META;
644 #else
645 sAccelModifier = MODIFIER_CONTROL;
646 #endif
647 break;
650 return sAccelModifier;
653 /******************************************************************************
654 * mozilla::WidgetWheelEvent (MouseEvents.h)
655 ******************************************************************************/
657 /* static */ double
658 WidgetWheelEvent::ComputeOverriddenDelta(double aDelta, bool aIsForVertical)
660 if (!gfxPrefs::MouseWheelHasRootScrollDeltaOverride()) {
661 return aDelta;
663 int32_t intFactor = aIsForVertical
664 ? gfxPrefs::MouseWheelRootScrollVerticalFactor()
665 : gfxPrefs::MouseWheelRootScrollHorizontalFactor();
666 // Making the scroll speed slower doesn't make sense. So, ignore odd factor
667 // which is less than 1.0.
668 if (intFactor <= 100) {
669 return aDelta;
671 double factor = static_cast<double>(intFactor) / 100;
672 return aDelta * factor;
675 double
676 WidgetWheelEvent::OverriddenDeltaX() const
678 if (!mAllowToOverrideSystemScrollSpeed) {
679 return mDeltaX;
681 return ComputeOverriddenDelta(mDeltaX, false);
684 double
685 WidgetWheelEvent::OverriddenDeltaY() const
687 if (!mAllowToOverrideSystemScrollSpeed) {
688 return mDeltaY;
690 return ComputeOverriddenDelta(mDeltaY, true);
693 /******************************************************************************
694 * mozilla::WidgetKeyboardEvent (TextEvents.h)
695 ******************************************************************************/
697 #define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) (u"" aDOMKeyName),
698 const char16_t* const WidgetKeyboardEvent::kKeyNames[] = {
699 #include "mozilla/KeyNameList.h"
701 #undef NS_DEFINE_KEYNAME
703 #define NS_DEFINE_PHYSICAL_KEY_CODE_NAME(aCPPName, aDOMCodeName) \
704 (u"" aDOMCodeName),
705 const char16_t* const WidgetKeyboardEvent::kCodeNames[] = {
706 #include "mozilla/PhysicalKeyCodeNameList.h"
708 #undef NS_DEFINE_PHYSICAL_KEY_CODE_NAME
710 WidgetKeyboardEvent::KeyNameIndexHashtable*
711 WidgetKeyboardEvent::sKeyNameIndexHashtable = nullptr;
712 WidgetKeyboardEvent::CodeNameIndexHashtable*
713 WidgetKeyboardEvent::sCodeNameIndexHashtable = nullptr;
715 void
716 WidgetKeyboardEvent::InitAllEditCommands()
718 // If the event was created without widget, e.g., created event in chrome
719 // script, this shouldn't execute native key bindings.
720 if (NS_WARN_IF(!mWidget)) {
721 return;
724 // This event should be trusted event here and we shouldn't expose native
725 // key binding information to web contents with untrusted events.
726 if (NS_WARN_IF(!IsTrusted())) {
727 return;
730 MOZ_ASSERT(XRE_IsParentProcess(),
731 "It's too expensive to retrieve all edit commands from remote process");
732 MOZ_ASSERT(!AreAllEditCommandsInitialized(),
733 "Shouldn't be called two or more times");
735 InitEditCommandsFor(nsIWidget::NativeKeyBindingsForSingleLineEditor);
736 InitEditCommandsFor(nsIWidget::NativeKeyBindingsForMultiLineEditor);
737 InitEditCommandsFor(nsIWidget::NativeKeyBindingsForRichTextEditor);
740 void
741 WidgetKeyboardEvent::InitEditCommandsFor(nsIWidget::NativeKeyBindingsType aType)
743 if (NS_WARN_IF(!mWidget) || NS_WARN_IF(!IsTrusted())) {
744 return;
747 bool& initialized = IsEditCommandsInitializedRef(aType);
748 if (initialized) {
749 return;
751 nsTArray<CommandInt>& commands = EditCommandsRef(aType);
752 mWidget->GetEditCommands(aType, *this, commands);
753 initialized = true;
756 bool
757 WidgetKeyboardEvent::ExecuteEditCommands(nsIWidget::NativeKeyBindingsType aType,
758 DoCommandCallback aCallback,
759 void* aCallbackData)
761 // If the event was created without widget, e.g., created event in chrome
762 // script, this shouldn't execute native key bindings.
763 if (NS_WARN_IF(!mWidget)) {
764 return false;
767 // This event should be trusted event here and we shouldn't expose native
768 // key binding information to web contents with untrusted events.
769 if (NS_WARN_IF(!IsTrusted())) {
770 return false;
773 InitEditCommandsFor(aType);
775 const nsTArray<CommandInt>& commands = EditCommandsRef(aType);
776 if (commands.IsEmpty()) {
777 return false;
780 for (CommandInt command : commands) {
781 aCallback(static_cast<Command>(command), aCallbackData);
783 return true;
786 bool
787 WidgetKeyboardEvent::ShouldCauseKeypressEvents() const
789 // Currently, we don't dispatch keypress events of modifier keys and
790 // dead keys.
791 switch (mKeyNameIndex) {
792 case KEY_NAME_INDEX_Alt:
793 case KEY_NAME_INDEX_AltGraph:
794 case KEY_NAME_INDEX_CapsLock:
795 case KEY_NAME_INDEX_Control:
796 case KEY_NAME_INDEX_Fn:
797 case KEY_NAME_INDEX_FnLock:
798 // case KEY_NAME_INDEX_Hyper:
799 case KEY_NAME_INDEX_Meta:
800 case KEY_NAME_INDEX_NumLock:
801 case KEY_NAME_INDEX_OS:
802 case KEY_NAME_INDEX_ScrollLock:
803 case KEY_NAME_INDEX_Shift:
804 // case KEY_NAME_INDEX_Super:
805 case KEY_NAME_INDEX_Symbol:
806 case KEY_NAME_INDEX_SymbolLock:
807 case KEY_NAME_INDEX_Dead:
808 return false;
809 default:
810 return true;
814 static bool
815 HasASCIIDigit(const ShortcutKeyCandidateArray& aCandidates)
817 for (uint32_t i = 0; i < aCandidates.Length(); ++i) {
818 uint32_t ch = aCandidates[i].mCharCode;
819 if (ch >= '0' && ch <= '9')
820 return true;
822 return false;
825 static bool
826 CharsCaseInsensitiveEqual(uint32_t aChar1, uint32_t aChar2)
828 return aChar1 == aChar2 ||
829 (IS_IN_BMP(aChar1) && IS_IN_BMP(aChar2) &&
830 ToLowerCase(static_cast<char16_t>(aChar1)) ==
831 ToLowerCase(static_cast<char16_t>(aChar2)));
834 static bool
835 IsCaseChangeableChar(uint32_t aChar)
837 return IS_IN_BMP(aChar) &&
838 ToLowerCase(static_cast<char16_t>(aChar)) !=
839 ToUpperCase(static_cast<char16_t>(aChar));
842 void
843 WidgetKeyboardEvent::GetShortcutKeyCandidates(
844 ShortcutKeyCandidateArray& aCandidates) const
846 MOZ_ASSERT(aCandidates.IsEmpty(), "aCandidates must be empty");
848 // ShortcutKeyCandidate::mCharCode is a candidate charCode.
849 // ShortcutKeyCandidate::mIgnoreShift means the mCharCode should be tried to
850 // execute a command with/without shift key state. If this is TRUE, the
851 // shifted key state should be ignored. Otherwise, don't ignore the state.
852 // the priority of the charCodes are (shift key is not pressed):
853 // 0: PseudoCharCode()/false,
854 // 1: unshiftedCharCodes[0]/false, 2: unshiftedCharCodes[1]/false...
855 // the priority of the charCodes are (shift key is pressed):
856 // 0: PseudoCharCode()/false,
857 // 1: shiftedCharCodes[0]/false, 2: shiftedCharCodes[0]/true,
858 // 3: shiftedCharCodes[1]/false, 4: shiftedCharCodes[1]/true...
859 uint32_t pseudoCharCode = PseudoCharCode();
860 if (pseudoCharCode) {
861 ShortcutKeyCandidate key(pseudoCharCode, false);
862 aCandidates.AppendElement(key);
865 uint32_t len = mAlternativeCharCodes.Length();
866 if (!IsShift()) {
867 for (uint32_t i = 0; i < len; ++i) {
868 uint32_t ch = mAlternativeCharCodes[i].mUnshiftedCharCode;
869 if (!ch || ch == pseudoCharCode) {
870 continue;
872 ShortcutKeyCandidate key(ch, false);
873 aCandidates.AppendElement(key);
875 // If unshiftedCharCodes doesn't have numeric but shiftedCharCode has it,
876 // this keyboard layout is AZERTY or similar layout, probably.
877 // In this case, Accel+[0-9] should be accessible without shift key.
878 // However, the priority should be lowest.
879 if (!HasASCIIDigit(aCandidates)) {
880 for (uint32_t i = 0; i < len; ++i) {
881 uint32_t ch = mAlternativeCharCodes[i].mShiftedCharCode;
882 if (ch >= '0' && ch <= '9') {
883 ShortcutKeyCandidate key(ch, false);
884 aCandidates.AppendElement(key);
885 break;
889 } else {
890 for (uint32_t i = 0; i < len; ++i) {
891 uint32_t ch = mAlternativeCharCodes[i].mShiftedCharCode;
892 if (!ch) {
893 continue;
896 if (ch != pseudoCharCode) {
897 ShortcutKeyCandidate key(ch, false);
898 aCandidates.AppendElement(key);
901 // If the char is an alphabet, the shift key state should not be
902 // ignored. E.g., Ctrl+Shift+C should not execute Ctrl+C.
904 // And checking the charCode is same as unshiftedCharCode too.
905 // E.g., for Ctrl+Shift+(Plus of Numpad) should not run Ctrl+Plus.
906 uint32_t unshiftCh = mAlternativeCharCodes[i].mUnshiftedCharCode;
907 if (CharsCaseInsensitiveEqual(ch, unshiftCh)) {
908 continue;
911 // On the Hebrew keyboard layout on Windows, the unshifted char is a
912 // localized character but the shifted char is a Latin alphabet,
913 // then, we should not execute without the shift state. See bug 433192.
914 if (IsCaseChangeableChar(ch)) {
915 continue;
918 // Setting the alternative charCode candidates for retry without shift
919 // key state only when the shift key is pressed.
920 ShortcutKeyCandidate key(ch, true);
921 aCandidates.AppendElement(key);
925 // Special case for "Space" key. With some keyboard layouts, "Space" with
926 // or without Shift key causes non-ASCII space. For such keyboard layouts,
927 // we should guarantee that the key press works as an ASCII white space key
928 // press. However, if the space key is assigned to a function key, it
929 // shouldn't work as a space key.
930 if (mKeyNameIndex == KEY_NAME_INDEX_USE_STRING &&
931 mCodeNameIndex == CODE_NAME_INDEX_Space && pseudoCharCode != ' ') {
932 ShortcutKeyCandidate spaceKey(' ', false);
933 aCandidates.AppendElement(spaceKey);
937 void
938 WidgetKeyboardEvent::GetAccessKeyCandidates(nsTArray<uint32_t>& aCandidates) const
940 MOZ_ASSERT(aCandidates.IsEmpty(), "aCandidates must be empty");
942 // return the lower cased charCode candidates for access keys.
943 // the priority of the charCodes are:
944 // 0: charCode, 1: unshiftedCharCodes[0], 2: shiftedCharCodes[0]
945 // 3: unshiftedCharCodes[1], 4: shiftedCharCodes[1],...
946 uint32_t pseudoCharCode = PseudoCharCode();
947 if (pseudoCharCode) {
948 uint32_t ch = pseudoCharCode;
949 if (IS_IN_BMP(ch)) {
950 ch = ToLowerCase(static_cast<char16_t>(ch));
952 aCandidates.AppendElement(ch);
954 for (uint32_t i = 0; i < mAlternativeCharCodes.Length(); ++i) {
955 uint32_t ch[2] =
956 { mAlternativeCharCodes[i].mUnshiftedCharCode,
957 mAlternativeCharCodes[i].mShiftedCharCode };
958 for (uint32_t j = 0; j < 2; ++j) {
959 if (!ch[j]) {
960 continue;
962 if (IS_IN_BMP(ch[j])) {
963 ch[j] = ToLowerCase(static_cast<char16_t>(ch[j]));
965 // Don't append the charcode that was already appended.
966 if (aCandidates.IndexOf(ch[j]) == aCandidates.NoIndex) {
967 aCandidates.AppendElement(ch[j]);
971 // Special case for "Space" key. With some keyboard layouts, "Space" with
972 // or without Shift key causes non-ASCII space. For such keyboard layouts,
973 // we should guarantee that the key press works as an ASCII white space key
974 // press. However, if the space key is assigned to a function key, it
975 // shouldn't work as a space key.
976 if (mKeyNameIndex == KEY_NAME_INDEX_USE_STRING &&
977 mCodeNameIndex == CODE_NAME_INDEX_Space && pseudoCharCode != ' ') {
978 aCandidates.AppendElement(' ');
982 // mask values for ui.key.chromeAccess and ui.key.contentAccess
983 #define NS_MODIFIER_SHIFT 1
984 #define NS_MODIFIER_CONTROL 2
985 #define NS_MODIFIER_ALT 4
986 #define NS_MODIFIER_META 8
987 #define NS_MODIFIER_OS 16
989 static Modifiers PrefFlagsToModifiers(int32_t aPrefFlags)
991 Modifiers result = 0;
992 if (aPrefFlags & NS_MODIFIER_SHIFT) {
993 result |= MODIFIER_SHIFT;
995 if (aPrefFlags & NS_MODIFIER_CONTROL) {
996 result |= MODIFIER_CONTROL;
998 if (aPrefFlags & NS_MODIFIER_ALT) {
999 result |= MODIFIER_ALT;
1001 if (aPrefFlags & NS_MODIFIER_META) {
1002 result |= MODIFIER_META;
1004 if (aPrefFlags & NS_MODIFIER_OS) {
1005 result |= MODIFIER_OS;
1007 return result;
1010 bool
1011 WidgetKeyboardEvent::ModifiersMatchWithAccessKey(AccessKeyType aType) const
1013 if (!ModifiersForAccessKeyMatching()) {
1014 return false;
1016 return ModifiersForAccessKeyMatching() == AccessKeyModifiers(aType);
1019 Modifiers
1020 WidgetKeyboardEvent::ModifiersForAccessKeyMatching() const
1022 static const Modifiers kModifierMask =
1023 MODIFIER_SHIFT | MODIFIER_CONTROL |
1024 MODIFIER_ALT | MODIFIER_META | MODIFIER_OS;
1025 return mModifiers & kModifierMask;
1028 /* static */
1029 Modifiers
1030 WidgetKeyboardEvent::AccessKeyModifiers(AccessKeyType aType)
1032 switch (GenericAccessModifierKeyPref()) {
1033 case -1:
1034 break; // use the individual prefs
1035 case NS_VK_SHIFT:
1036 return MODIFIER_SHIFT;
1037 case NS_VK_CONTROL:
1038 return MODIFIER_CONTROL;
1039 case NS_VK_ALT:
1040 return MODIFIER_ALT;
1041 case NS_VK_META:
1042 return MODIFIER_META;
1043 case NS_VK_WIN:
1044 return MODIFIER_OS;
1045 default:
1046 return MODIFIER_NONE;
1049 switch (aType) {
1050 case AccessKeyType::eChrome:
1051 return PrefFlagsToModifiers(ChromeAccessModifierMaskPref());
1052 case AccessKeyType::eContent:
1053 return PrefFlagsToModifiers(ContentAccessModifierMaskPref());
1054 default:
1055 return MODIFIER_NONE;
1059 /* static */
1060 int32_t
1061 WidgetKeyboardEvent::GenericAccessModifierKeyPref()
1063 static bool sInitialized = false;
1064 static int32_t sValue = -1;
1065 if (!sInitialized) {
1066 nsresult rv =
1067 Preferences::AddIntVarCache(&sValue, "ui.key.generalAccessKey", sValue);
1068 sInitialized = NS_SUCCEEDED(rv);
1069 MOZ_ASSERT(sInitialized);
1071 return sValue;
1074 /* static */
1075 int32_t
1076 WidgetKeyboardEvent::ChromeAccessModifierMaskPref()
1078 static bool sInitialized = false;
1079 static int32_t sValue = 0;
1080 if (!sInitialized) {
1081 nsresult rv =
1082 Preferences::AddIntVarCache(&sValue, "ui.key.chromeAccess", sValue);
1083 sInitialized = NS_SUCCEEDED(rv);
1084 MOZ_ASSERT(sInitialized);
1086 return sValue;
1089 /* static */
1090 int32_t
1091 WidgetKeyboardEvent::ContentAccessModifierMaskPref()
1093 static bool sInitialized = false;
1094 static int32_t sValue = 0;
1095 if (!sInitialized) {
1096 nsresult rv =
1097 Preferences::AddIntVarCache(&sValue, "ui.key.contentAccess", sValue);
1098 sInitialized = NS_SUCCEEDED(rv);
1099 MOZ_ASSERT(sInitialized);
1101 return sValue;
1104 /* static */ void
1105 WidgetKeyboardEvent::Shutdown()
1107 delete sKeyNameIndexHashtable;
1108 sKeyNameIndexHashtable = nullptr;
1109 delete sCodeNameIndexHashtable;
1110 sCodeNameIndexHashtable = nullptr;
1113 /* static */ void
1114 WidgetKeyboardEvent::GetDOMKeyName(KeyNameIndex aKeyNameIndex,
1115 nsAString& aKeyName)
1117 if (aKeyNameIndex >= KEY_NAME_INDEX_USE_STRING) {
1118 aKeyName.Truncate();
1119 return;
1122 MOZ_RELEASE_ASSERT(static_cast<size_t>(aKeyNameIndex) <
1123 ArrayLength(kKeyNames),
1124 "Illegal key enumeration value");
1125 aKeyName = kKeyNames[aKeyNameIndex];
1128 /* static */ void
1129 WidgetKeyboardEvent::GetDOMCodeName(CodeNameIndex aCodeNameIndex,
1130 nsAString& aCodeName)
1132 if (aCodeNameIndex >= CODE_NAME_INDEX_USE_STRING) {
1133 aCodeName.Truncate();
1134 return;
1137 MOZ_RELEASE_ASSERT(static_cast<size_t>(aCodeNameIndex) <
1138 ArrayLength(kCodeNames),
1139 "Illegal physical code enumeration value");
1140 aCodeName = kCodeNames[aCodeNameIndex];
1143 /* static */ KeyNameIndex
1144 WidgetKeyboardEvent::GetKeyNameIndex(const nsAString& aKeyValue)
1146 if (!sKeyNameIndexHashtable) {
1147 sKeyNameIndexHashtable =
1148 new KeyNameIndexHashtable(ArrayLength(kKeyNames));
1149 for (size_t i = 0; i < ArrayLength(kKeyNames); i++) {
1150 sKeyNameIndexHashtable->Put(nsDependentString(kKeyNames[i]),
1151 static_cast<KeyNameIndex>(i));
1154 KeyNameIndex result = KEY_NAME_INDEX_USE_STRING;
1155 sKeyNameIndexHashtable->Get(aKeyValue, &result);
1156 return result;
1159 /* static */ CodeNameIndex
1160 WidgetKeyboardEvent::GetCodeNameIndex(const nsAString& aCodeValue)
1162 if (!sCodeNameIndexHashtable) {
1163 sCodeNameIndexHashtable =
1164 new CodeNameIndexHashtable(ArrayLength(kCodeNames));
1165 for (size_t i = 0; i < ArrayLength(kCodeNames); i++) {
1166 sCodeNameIndexHashtable->Put(nsDependentString(kCodeNames[i]),
1167 static_cast<CodeNameIndex>(i));
1170 CodeNameIndex result = CODE_NAME_INDEX_USE_STRING;
1171 sCodeNameIndexHashtable->Get(aCodeValue, &result);
1172 return result;
1175 /* static */ uint32_t
1176 WidgetKeyboardEvent::GetFallbackKeyCodeOfPunctuationKey(
1177 CodeNameIndex aCodeNameIndex)
1179 switch (aCodeNameIndex) {
1180 case CODE_NAME_INDEX_Semicolon: // VK_OEM_1 on Windows
1181 return dom::KeyboardEventBinding::DOM_VK_SEMICOLON;
1182 case CODE_NAME_INDEX_Equal: // VK_OEM_PLUS on Windows
1183 return dom::KeyboardEventBinding::DOM_VK_EQUALS;
1184 case CODE_NAME_INDEX_Comma: // VK_OEM_COMMA on Windows
1185 return dom::KeyboardEventBinding::DOM_VK_COMMA;
1186 case CODE_NAME_INDEX_Minus: // VK_OEM_MINUS on Windows
1187 return dom::KeyboardEventBinding::DOM_VK_HYPHEN_MINUS;
1188 case CODE_NAME_INDEX_Period: // VK_OEM_PERIOD on Windows
1189 return dom::KeyboardEventBinding::DOM_VK_PERIOD;
1190 case CODE_NAME_INDEX_Slash: // VK_OEM_2 on Windows
1191 return dom::KeyboardEventBinding::DOM_VK_SLASH;
1192 case CODE_NAME_INDEX_Backquote: // VK_OEM_3 on Windows
1193 return dom::KeyboardEventBinding::DOM_VK_BACK_QUOTE;
1194 case CODE_NAME_INDEX_BracketLeft: // VK_OEM_4 on Windows
1195 return dom::KeyboardEventBinding::DOM_VK_OPEN_BRACKET;
1196 case CODE_NAME_INDEX_Backslash: // VK_OEM_5 on Windows
1197 return dom::KeyboardEventBinding::DOM_VK_BACK_SLASH;
1198 case CODE_NAME_INDEX_BracketRight: // VK_OEM_6 on Windows
1199 return dom::KeyboardEventBinding::DOM_VK_CLOSE_BRACKET;
1200 case CODE_NAME_INDEX_Quote: // VK_OEM_7 on Windows
1201 return dom::KeyboardEventBinding::DOM_VK_QUOTE;
1202 case CODE_NAME_INDEX_IntlBackslash: // VK_OEM_5 on Windows (ABNT, etc)
1203 case CODE_NAME_INDEX_IntlYen: // VK_OEM_5 on Windows (JIS)
1204 case CODE_NAME_INDEX_IntlRo: // VK_OEM_102 on Windows
1205 return dom::KeyboardEventBinding::DOM_VK_BACK_SLASH;
1206 default:
1207 return 0;
1211 /* static */ const char*
1212 WidgetKeyboardEvent::GetCommandStr(Command aCommand)
1214 #define NS_DEFINE_COMMAND(aName, aCommandStr) , #aCommandStr
1215 #define NS_DEFINE_COMMAND_NO_EXEC_COMMAND(aName)
1216 static const char* const kCommands[] = {
1217 "" // CommandDoNothing
1218 #include "mozilla/CommandList.h"
1220 #undef NS_DEFINE_COMMAND
1221 #undef NS_DEFINE_COMMAND_NO_EXEC_COMMAND
1223 MOZ_RELEASE_ASSERT(static_cast<size_t>(aCommand) < ArrayLength(kCommands),
1224 "Illegal command enumeration value");
1225 return kCommands[aCommand];
1228 /* static */ uint32_t
1229 WidgetKeyboardEvent::ComputeLocationFromCodeValue(CodeNameIndex aCodeNameIndex)
1231 // Following commented out cases are not defined in PhysicalKeyCodeNameList.h
1232 // but are defined by D3E spec. So, they should be uncommented when the
1233 // code values are defined in the header.
1234 switch (aCodeNameIndex) {
1235 case CODE_NAME_INDEX_AltLeft:
1236 case CODE_NAME_INDEX_ControlLeft:
1237 case CODE_NAME_INDEX_OSLeft:
1238 case CODE_NAME_INDEX_ShiftLeft:
1239 return eKeyLocationLeft;
1240 case CODE_NAME_INDEX_AltRight:
1241 case CODE_NAME_INDEX_ControlRight:
1242 case CODE_NAME_INDEX_OSRight:
1243 case CODE_NAME_INDEX_ShiftRight:
1244 return eKeyLocationRight;
1245 case CODE_NAME_INDEX_Numpad0:
1246 case CODE_NAME_INDEX_Numpad1:
1247 case CODE_NAME_INDEX_Numpad2:
1248 case CODE_NAME_INDEX_Numpad3:
1249 case CODE_NAME_INDEX_Numpad4:
1250 case CODE_NAME_INDEX_Numpad5:
1251 case CODE_NAME_INDEX_Numpad6:
1252 case CODE_NAME_INDEX_Numpad7:
1253 case CODE_NAME_INDEX_Numpad8:
1254 case CODE_NAME_INDEX_Numpad9:
1255 case CODE_NAME_INDEX_NumpadAdd:
1256 case CODE_NAME_INDEX_NumpadBackspace:
1257 case CODE_NAME_INDEX_NumpadClear:
1258 case CODE_NAME_INDEX_NumpadClearEntry:
1259 case CODE_NAME_INDEX_NumpadComma:
1260 case CODE_NAME_INDEX_NumpadDecimal:
1261 case CODE_NAME_INDEX_NumpadDivide:
1262 case CODE_NAME_INDEX_NumpadEnter:
1263 case CODE_NAME_INDEX_NumpadEqual:
1264 case CODE_NAME_INDEX_NumpadMemoryAdd:
1265 case CODE_NAME_INDEX_NumpadMemoryClear:
1266 case CODE_NAME_INDEX_NumpadMemoryRecall:
1267 case CODE_NAME_INDEX_NumpadMemoryStore:
1268 case CODE_NAME_INDEX_NumpadMemorySubtract:
1269 case CODE_NAME_INDEX_NumpadMultiply:
1270 case CODE_NAME_INDEX_NumpadParenLeft:
1271 case CODE_NAME_INDEX_NumpadParenRight:
1272 case CODE_NAME_INDEX_NumpadSubtract:
1273 return eKeyLocationNumpad;
1274 default:
1275 return eKeyLocationStandard;
1279 /* static */ uint32_t
1280 WidgetKeyboardEvent::ComputeKeyCodeFromKeyNameIndex(KeyNameIndex aKeyNameIndex)
1282 switch (aKeyNameIndex) {
1283 case KEY_NAME_INDEX_Cancel:
1284 return dom::KeyboardEventBinding::DOM_VK_CANCEL;
1285 case KEY_NAME_INDEX_Help:
1286 return dom::KeyboardEventBinding::DOM_VK_HELP;
1287 case KEY_NAME_INDEX_Backspace:
1288 return dom::KeyboardEventBinding::DOM_VK_BACK_SPACE;
1289 case KEY_NAME_INDEX_Tab:
1290 return dom::KeyboardEventBinding::DOM_VK_TAB;
1291 case KEY_NAME_INDEX_Clear:
1292 return dom::KeyboardEventBinding::DOM_VK_CLEAR;
1293 case KEY_NAME_INDEX_Enter:
1294 return dom::KeyboardEventBinding::DOM_VK_RETURN;
1295 case KEY_NAME_INDEX_Shift:
1296 return dom::KeyboardEventBinding::DOM_VK_SHIFT;
1297 case KEY_NAME_INDEX_Control:
1298 return dom::KeyboardEventBinding::DOM_VK_CONTROL;
1299 case KEY_NAME_INDEX_Alt:
1300 return dom::KeyboardEventBinding::DOM_VK_ALT;
1301 case KEY_NAME_INDEX_Pause:
1302 return dom::KeyboardEventBinding::DOM_VK_PAUSE;
1303 case KEY_NAME_INDEX_CapsLock:
1304 return dom::KeyboardEventBinding::DOM_VK_CAPS_LOCK;
1305 case KEY_NAME_INDEX_Hiragana:
1306 case KEY_NAME_INDEX_Katakana:
1307 case KEY_NAME_INDEX_HiraganaKatakana:
1308 case KEY_NAME_INDEX_KanaMode:
1309 return dom::KeyboardEventBinding::DOM_VK_KANA;
1310 case KEY_NAME_INDEX_HangulMode:
1311 return dom::KeyboardEventBinding::DOM_VK_HANGUL;
1312 case KEY_NAME_INDEX_Eisu:
1313 return dom::KeyboardEventBinding::DOM_VK_EISU;
1314 case KEY_NAME_INDEX_JunjaMode:
1315 return dom::KeyboardEventBinding::DOM_VK_JUNJA;
1316 case KEY_NAME_INDEX_FinalMode:
1317 return dom::KeyboardEventBinding::DOM_VK_FINAL;
1318 case KEY_NAME_INDEX_HanjaMode:
1319 return dom::KeyboardEventBinding::DOM_VK_HANJA;
1320 case KEY_NAME_INDEX_KanjiMode:
1321 return dom::KeyboardEventBinding::DOM_VK_KANJI;
1322 case KEY_NAME_INDEX_Escape:
1323 return dom::KeyboardEventBinding::DOM_VK_ESCAPE;
1324 case KEY_NAME_INDEX_Convert:
1325 return dom::KeyboardEventBinding::DOM_VK_CONVERT;
1326 case KEY_NAME_INDEX_NonConvert:
1327 return dom::KeyboardEventBinding::DOM_VK_NONCONVERT;
1328 case KEY_NAME_INDEX_Accept:
1329 return dom::KeyboardEventBinding::DOM_VK_ACCEPT;
1330 case KEY_NAME_INDEX_ModeChange:
1331 return dom::KeyboardEventBinding::DOM_VK_MODECHANGE;
1332 case KEY_NAME_INDEX_PageUp:
1333 return dom::KeyboardEventBinding::DOM_VK_PAGE_UP;
1334 case KEY_NAME_INDEX_PageDown:
1335 return dom::KeyboardEventBinding::DOM_VK_PAGE_DOWN;
1336 case KEY_NAME_INDEX_End:
1337 return dom::KeyboardEventBinding::DOM_VK_END;
1338 case KEY_NAME_INDEX_Home:
1339 return dom::KeyboardEventBinding::DOM_VK_HOME;
1340 case KEY_NAME_INDEX_ArrowLeft:
1341 return dom::KeyboardEventBinding::DOM_VK_LEFT;
1342 case KEY_NAME_INDEX_ArrowUp:
1343 return dom::KeyboardEventBinding::DOM_VK_UP;
1344 case KEY_NAME_INDEX_ArrowRight:
1345 return dom::KeyboardEventBinding::DOM_VK_RIGHT;
1346 case KEY_NAME_INDEX_ArrowDown:
1347 return dom::KeyboardEventBinding::DOM_VK_DOWN;
1348 case KEY_NAME_INDEX_Select:
1349 return dom::KeyboardEventBinding::DOM_VK_SELECT;
1350 case KEY_NAME_INDEX_Print:
1351 return dom::KeyboardEventBinding::DOM_VK_PRINT;
1352 case KEY_NAME_INDEX_Execute:
1353 return dom::KeyboardEventBinding::DOM_VK_EXECUTE;
1354 case KEY_NAME_INDEX_PrintScreen:
1355 return dom::KeyboardEventBinding::DOM_VK_PRINTSCREEN;
1356 case KEY_NAME_INDEX_Insert:
1357 return dom::KeyboardEventBinding::DOM_VK_INSERT;
1358 case KEY_NAME_INDEX_Delete:
1359 return dom::KeyboardEventBinding::DOM_VK_DELETE;
1360 case KEY_NAME_INDEX_OS:
1361 // case KEY_NAME_INDEX_Super:
1362 // case KEY_NAME_INDEX_Hyper:
1363 return dom::KeyboardEventBinding::DOM_VK_WIN;
1364 case KEY_NAME_INDEX_ContextMenu:
1365 return dom::KeyboardEventBinding::DOM_VK_CONTEXT_MENU;
1366 case KEY_NAME_INDEX_Standby:
1367 return dom::KeyboardEventBinding::DOM_VK_SLEEP;
1368 case KEY_NAME_INDEX_F1:
1369 return dom::KeyboardEventBinding::DOM_VK_F1;
1370 case KEY_NAME_INDEX_F2:
1371 return dom::KeyboardEventBinding::DOM_VK_F2;
1372 case KEY_NAME_INDEX_F3:
1373 return dom::KeyboardEventBinding::DOM_VK_F3;
1374 case KEY_NAME_INDEX_F4:
1375 return dom::KeyboardEventBinding::DOM_VK_F4;
1376 case KEY_NAME_INDEX_F5:
1377 return dom::KeyboardEventBinding::DOM_VK_F5;
1378 case KEY_NAME_INDEX_F6:
1379 return dom::KeyboardEventBinding::DOM_VK_F6;
1380 case KEY_NAME_INDEX_F7:
1381 return dom::KeyboardEventBinding::DOM_VK_F7;
1382 case KEY_NAME_INDEX_F8:
1383 return dom::KeyboardEventBinding::DOM_VK_F8;
1384 case KEY_NAME_INDEX_F9:
1385 return dom::KeyboardEventBinding::DOM_VK_F9;
1386 case KEY_NAME_INDEX_F10:
1387 return dom::KeyboardEventBinding::DOM_VK_F10;
1388 case KEY_NAME_INDEX_F11:
1389 return dom::KeyboardEventBinding::DOM_VK_F11;
1390 case KEY_NAME_INDEX_F12:
1391 return dom::KeyboardEventBinding::DOM_VK_F12;
1392 case KEY_NAME_INDEX_F13:
1393 return dom::KeyboardEventBinding::DOM_VK_F13;
1394 case KEY_NAME_INDEX_F14:
1395 return dom::KeyboardEventBinding::DOM_VK_F14;
1396 case KEY_NAME_INDEX_F15:
1397 return dom::KeyboardEventBinding::DOM_VK_F15;
1398 case KEY_NAME_INDEX_F16:
1399 return dom::KeyboardEventBinding::DOM_VK_F16;
1400 case KEY_NAME_INDEX_F17:
1401 return dom::KeyboardEventBinding::DOM_VK_F17;
1402 case KEY_NAME_INDEX_F18:
1403 return dom::KeyboardEventBinding::DOM_VK_F18;
1404 case KEY_NAME_INDEX_F19:
1405 return dom::KeyboardEventBinding::DOM_VK_F19;
1406 case KEY_NAME_INDEX_F20:
1407 return dom::KeyboardEventBinding::DOM_VK_F20;
1408 case KEY_NAME_INDEX_F21:
1409 return dom::KeyboardEventBinding::DOM_VK_F21;
1410 case KEY_NAME_INDEX_F22:
1411 return dom::KeyboardEventBinding::DOM_VK_F22;
1412 case KEY_NAME_INDEX_F23:
1413 return dom::KeyboardEventBinding::DOM_VK_F23;
1414 case KEY_NAME_INDEX_F24:
1415 return dom::KeyboardEventBinding::DOM_VK_F24;
1416 case KEY_NAME_INDEX_NumLock:
1417 return dom::KeyboardEventBinding::DOM_VK_NUM_LOCK;
1418 case KEY_NAME_INDEX_ScrollLock:
1419 return dom::KeyboardEventBinding::DOM_VK_SCROLL_LOCK;
1420 case KEY_NAME_INDEX_AudioVolumeMute:
1421 return dom::KeyboardEventBinding::DOM_VK_VOLUME_MUTE;
1422 case KEY_NAME_INDEX_AudioVolumeDown:
1423 return dom::KeyboardEventBinding::DOM_VK_VOLUME_DOWN;
1424 case KEY_NAME_INDEX_AudioVolumeUp:
1425 return dom::KeyboardEventBinding::DOM_VK_VOLUME_UP;
1426 case KEY_NAME_INDEX_Meta:
1427 return dom::KeyboardEventBinding::DOM_VK_META;
1428 case KEY_NAME_INDEX_AltGraph:
1429 return dom::KeyboardEventBinding::DOM_VK_ALTGR;
1430 case KEY_NAME_INDEX_Process:
1431 return dom::KeyboardEventBinding::DOM_VK_PROCESSKEY;
1432 case KEY_NAME_INDEX_Attn:
1433 return dom::KeyboardEventBinding::DOM_VK_ATTN;
1434 case KEY_NAME_INDEX_CrSel:
1435 return dom::KeyboardEventBinding::DOM_VK_CRSEL;
1436 case KEY_NAME_INDEX_ExSel:
1437 return dom::KeyboardEventBinding::DOM_VK_EXSEL;
1438 case KEY_NAME_INDEX_EraseEof:
1439 return dom::KeyboardEventBinding::DOM_VK_EREOF;
1440 case KEY_NAME_INDEX_Play:
1441 return dom::KeyboardEventBinding::DOM_VK_PLAY;
1442 case KEY_NAME_INDEX_ZoomToggle:
1443 case KEY_NAME_INDEX_ZoomIn:
1444 case KEY_NAME_INDEX_ZoomOut:
1445 return dom::KeyboardEventBinding::DOM_VK_ZOOM;
1446 default:
1447 return 0;
1451 /* static */ Modifier
1452 WidgetKeyboardEvent::GetModifierForKeyName(KeyNameIndex aKeyNameIndex)
1454 switch (aKeyNameIndex) {
1455 case KEY_NAME_INDEX_Alt:
1456 return MODIFIER_ALT;
1457 case KEY_NAME_INDEX_AltGraph:
1458 return MODIFIER_ALTGRAPH;
1459 case KEY_NAME_INDEX_CapsLock:
1460 return MODIFIER_CAPSLOCK;
1461 case KEY_NAME_INDEX_Control:
1462 return MODIFIER_CONTROL;
1463 case KEY_NAME_INDEX_Fn:
1464 return MODIFIER_FN;
1465 case KEY_NAME_INDEX_FnLock:
1466 return MODIFIER_FNLOCK;
1467 // case KEY_NAME_INDEX_Hyper:
1468 case KEY_NAME_INDEX_Meta:
1469 return MODIFIER_META;
1470 case KEY_NAME_INDEX_NumLock:
1471 return MODIFIER_NUMLOCK;
1472 case KEY_NAME_INDEX_OS:
1473 return MODIFIER_OS;
1474 case KEY_NAME_INDEX_ScrollLock:
1475 return MODIFIER_SCROLLLOCK;
1476 case KEY_NAME_INDEX_Shift:
1477 return MODIFIER_SHIFT;
1478 // case KEY_NAME_INDEX_Super:
1479 case KEY_NAME_INDEX_Symbol:
1480 return MODIFIER_SYMBOL;
1481 case KEY_NAME_INDEX_SymbolLock:
1482 return MODIFIER_SYMBOLLOCK;
1483 default:
1484 return MODIFIER_NONE;
1488 /* static */ bool
1489 WidgetKeyboardEvent::IsLockableModifier(KeyNameIndex aKeyNameIndex)
1491 switch (aKeyNameIndex) {
1492 case KEY_NAME_INDEX_CapsLock:
1493 case KEY_NAME_INDEX_FnLock:
1494 case KEY_NAME_INDEX_NumLock:
1495 case KEY_NAME_INDEX_ScrollLock:
1496 case KEY_NAME_INDEX_SymbolLock:
1497 return true;
1498 default:
1499 return false;
1503 } // namespace mozilla