Line data Source code
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/. */
5 :
6 : #include "gfxPrefs.h"
7 : #include "mozilla/BasicEvents.h"
8 : #include "mozilla/ContentEvents.h"
9 : #include "mozilla/InternalMutationEvent.h"
10 : #include "mozilla/MiscEvents.h"
11 : #include "mozilla/MouseEvents.h"
12 : #include "mozilla/Preferences.h"
13 : #include "mozilla/TextEvents.h"
14 : #include "mozilla/TouchEvents.h"
15 : #include "nsIDOMEventTarget.h"
16 : #include "nsPrintfCString.h"
17 :
18 : namespace mozilla {
19 :
20 : /******************************************************************************
21 : * Global helper methods
22 : ******************************************************************************/
23 :
24 : const char*
25 0 : ToChar(EventMessage aEventMessage)
26 : {
27 0 : switch (aEventMessage) {
28 :
29 : #define NS_EVENT_MESSAGE(aMessage) \
30 : case aMessage: \
31 : return #aMessage;
32 :
33 : #include "mozilla/EventMessageList.h"
34 :
35 : #undef NS_EVENT_MESSAGE
36 : default:
37 0 : return "illegal event message";
38 : }
39 : }
40 :
41 : const char*
42 0 : ToChar(EventClassID aEventClassID)
43 : {
44 0 : switch (aEventClassID) {
45 :
46 : #define NS_ROOT_EVENT_CLASS(aPrefix, aName) \
47 : case eBasic##aName##Class: \
48 : return "eBasic" #aName "Class";
49 :
50 : #define NS_EVENT_CLASS(aPrefix, aName) \
51 : case e##aName##Class: \
52 : return "e" #aName "Class";
53 :
54 : #include "mozilla/EventClassList.h"
55 :
56 : #undef NS_EVENT_CLASS
57 : #undef NS_ROOT_EVENT_CLASS
58 : default:
59 0 : return "illegal event class ID";
60 : }
61 : }
62 :
63 : const nsCString
64 0 : ToString(KeyNameIndex aKeyNameIndex)
65 : {
66 0 : if (aKeyNameIndex == KEY_NAME_INDEX_USE_STRING) {
67 0 : return NS_LITERAL_CSTRING("USE_STRING");
68 : }
69 0 : nsAutoString keyName;
70 0 : WidgetKeyboardEvent::GetDOMKeyName(aKeyNameIndex, keyName);
71 0 : return NS_ConvertUTF16toUTF8(keyName);
72 : }
73 :
74 : const nsCString
75 0 : ToString(CodeNameIndex aCodeNameIndex)
76 : {
77 0 : if (aCodeNameIndex == CODE_NAME_INDEX_USE_STRING) {
78 0 : return NS_LITERAL_CSTRING("USE_STRING");
79 : }
80 0 : nsAutoString codeName;
81 0 : WidgetKeyboardEvent::GetDOMCodeName(aCodeNameIndex, codeName);
82 0 : return NS_ConvertUTF16toUTF8(codeName);
83 : }
84 :
85 : const nsCString
86 0 : GetDOMKeyCodeName(uint32_t aKeyCode)
87 : {
88 0 : switch (aKeyCode) {
89 : #define NS_DISALLOW_SAME_KEYCODE
90 : #define NS_DEFINE_VK(aDOMKeyName, aDOMKeyCode) \
91 : case aDOMKeyCode: \
92 : return NS_LITERAL_CSTRING(#aDOMKeyName);
93 :
94 : #include "mozilla/VirtualKeyCodeList.h"
95 :
96 : #undef NS_DEFINE_VK
97 : #undef NS_DISALLOW_SAME_KEYCODE
98 :
99 : default:
100 0 : return nsPrintfCString("Invalid DOM keyCode (0x%08X)", aKeyCode);
101 : }
102 : }
103 :
104 : bool
105 0 : IsValidRawTextRangeValue(RawTextRangeType aRawTextRangeType)
106 : {
107 0 : switch (static_cast<TextRangeType>(aRawTextRangeType)) {
108 : case TextRangeType::eUninitialized:
109 : case TextRangeType::eCaret:
110 : case TextRangeType::eRawClause:
111 : case TextRangeType::eSelectedRawClause:
112 : case TextRangeType::eConvertedClause:
113 : case TextRangeType::eSelectedClause:
114 0 : return true;
115 : default:
116 0 : return false;
117 : }
118 : }
119 :
120 : RawTextRangeType
121 0 : ToRawTextRangeType(TextRangeType aTextRangeType)
122 : {
123 0 : return static_cast<RawTextRangeType>(aTextRangeType);
124 : }
125 :
126 : TextRangeType
127 0 : ToTextRangeType(RawTextRangeType aRawTextRangeType)
128 : {
129 0 : MOZ_ASSERT(IsValidRawTextRangeValue(aRawTextRangeType));
130 0 : return static_cast<TextRangeType>(aRawTextRangeType);
131 : }
132 :
133 : const char*
134 0 : ToChar(TextRangeType aTextRangeType)
135 : {
136 0 : switch (aTextRangeType) {
137 : case TextRangeType::eUninitialized:
138 0 : return "TextRangeType::eUninitialized";
139 : case TextRangeType::eCaret:
140 0 : return "TextRangeType::eCaret";
141 : case TextRangeType::eRawClause:
142 0 : return "TextRangeType::eRawClause";
143 : case TextRangeType::eSelectedRawClause:
144 0 : return "TextRangeType::eSelectedRawClause";
145 : case TextRangeType::eConvertedClause:
146 0 : return "TextRangeType::eConvertedClause";
147 : case TextRangeType::eSelectedClause:
148 0 : return "TextRangeType::eSelectedClause";
149 : default:
150 0 : return "Invalid TextRangeType";
151 : }
152 : }
153 :
154 : SelectionType
155 0 : ToSelectionType(TextRangeType aTextRangeType)
156 : {
157 0 : switch (aTextRangeType) {
158 : case TextRangeType::eRawClause:
159 0 : return SelectionType::eIMERawClause;
160 : case TextRangeType::eSelectedRawClause:
161 0 : return SelectionType::eIMESelectedRawClause;
162 : case TextRangeType::eConvertedClause:
163 0 : return SelectionType::eIMEConvertedClause;
164 : case TextRangeType::eSelectedClause:
165 0 : return SelectionType::eIMESelectedClause;
166 : default:
167 0 : MOZ_CRASH("TextRangeType is invalid");
168 : return SelectionType::eNormal;
169 : }
170 : }
171 :
172 : /******************************************************************************
173 : * As*Event() implementation
174 : ******************************************************************************/
175 :
176 : #define NS_ROOT_EVENT_CLASS(aPrefix, aName)
177 : #define NS_EVENT_CLASS(aPrefix, aName) \
178 : aPrefix##aName* \
179 : WidgetEvent::As##aName() \
180 : { \
181 : return nullptr; \
182 : } \
183 : \
184 : const aPrefix##aName* \
185 : WidgetEvent::As##aName() const \
186 : { \
187 : return const_cast<WidgetEvent*>(this)->As##aName(); \
188 : }
189 :
190 : #include "mozilla/EventClassList.h"
191 :
192 : #undef NS_EVENT_CLASS
193 : #undef NS_ROOT_EVENT_CLASS
194 :
195 : /******************************************************************************
196 : * mozilla::WidgetEvent
197 : *
198 : * Event struct type checking methods.
199 : ******************************************************************************/
200 :
201 : bool
202 0 : WidgetEvent::IsQueryContentEvent() const
203 : {
204 0 : return mClass == eQueryContentEventClass;
205 : }
206 :
207 : bool
208 0 : WidgetEvent::IsSelectionEvent() const
209 : {
210 0 : return mClass == eSelectionEventClass;
211 : }
212 :
213 : bool
214 0 : WidgetEvent::IsContentCommandEvent() const
215 : {
216 0 : return mClass == eContentCommandEventClass;
217 : }
218 :
219 : bool
220 0 : WidgetEvent::IsNativeEventDelivererForPlugin() const
221 : {
222 0 : return mClass == ePluginEventClass;
223 : }
224 :
225 :
226 : /******************************************************************************
227 : * mozilla::WidgetEvent
228 : *
229 : * Event message checking methods.
230 : ******************************************************************************/
231 :
232 : bool
233 6 : WidgetEvent::HasMouseEventMessage() const
234 : {
235 6 : switch (mMessage) {
236 : case eMouseDown:
237 : case eMouseUp:
238 : case eMouseClick:
239 : case eMouseDoubleClick:
240 : case eMouseAuxClick:
241 : case eMouseEnterIntoWidget:
242 : case eMouseExitFromWidget:
243 : case eMouseActivate:
244 : case eMouseOver:
245 : case eMouseOut:
246 : case eMouseHitTest:
247 : case eMouseMove:
248 6 : return true;
249 : default:
250 0 : return false;
251 : }
252 : }
253 :
254 : bool
255 10 : WidgetEvent::HasDragEventMessage() const
256 : {
257 10 : switch (mMessage) {
258 : case eDragEnter:
259 : case eDragOver:
260 : case eDragExit:
261 : case eDrag:
262 : case eDragEnd:
263 : case eDragStart:
264 : case eDrop:
265 : case eDragLeave:
266 0 : return true;
267 : default:
268 10 : return false;
269 : }
270 : }
271 :
272 : bool
273 4 : WidgetEvent::HasKeyEventMessage() const
274 : {
275 4 : switch (mMessage) {
276 : case eKeyDown:
277 : case eKeyPress:
278 : case eKeyUp:
279 : case eKeyDownOnPlugin:
280 : case eKeyUpOnPlugin:
281 : case eAccessKeyNotFound:
282 0 : return true;
283 : default:
284 4 : return false;
285 : }
286 : }
287 :
288 : bool
289 4 : WidgetEvent::HasIMEEventMessage() const
290 : {
291 4 : switch (mMessage) {
292 : case eCompositionStart:
293 : case eCompositionEnd:
294 : case eCompositionUpdate:
295 : case eCompositionChange:
296 : case eCompositionCommitAsIs:
297 : case eCompositionCommit:
298 0 : return true;
299 : default:
300 4 : return false;
301 : }
302 : }
303 :
304 : bool
305 10 : WidgetEvent::HasPluginActivationEventMessage() const
306 : {
307 20 : return mMessage == ePluginActivate ||
308 20 : mMessage == ePluginFocus;
309 : }
310 :
311 : /******************************************************************************
312 : * mozilla::WidgetEvent
313 : *
314 : * Specific event checking methods.
315 : ******************************************************************************/
316 :
317 : bool
318 12 : WidgetEvent::CanBeSentToRemoteProcess() const
319 : {
320 : // If this event is explicitly marked as shouldn't be sent to remote process,
321 : // just return false.
322 12 : if (IsCrossProcessForwardingStopped()) {
323 2 : return false;
324 : }
325 :
326 20 : if (mClass == eKeyboardEventClass ||
327 10 : mClass == eWheelEventClass) {
328 0 : return true;
329 : }
330 :
331 10 : switch (mMessage) {
332 : case eMouseDown:
333 : case eMouseUp:
334 : case eMouseMove:
335 : case eContextMenu:
336 : case eMouseEnterIntoWidget:
337 : case eMouseExitFromWidget:
338 : case eMouseTouchDrag:
339 : case eTouchStart:
340 : case eTouchMove:
341 : case eTouchEnd:
342 : case eTouchCancel:
343 : case eDragOver:
344 : case eDragExit:
345 : case eDrop:
346 6 : return true;
347 : default:
348 4 : return false;
349 : }
350 : }
351 :
352 : bool
353 0 : WidgetEvent::IsRetargetedNativeEventDelivererForPlugin() const
354 : {
355 0 : const WidgetPluginEvent* pluginEvent = AsPluginEvent();
356 0 : return pluginEvent && pluginEvent->mRetargetToFocusedDocument;
357 : }
358 :
359 : bool
360 0 : WidgetEvent::IsNonRetargetedNativeEventDelivererForPlugin() const
361 : {
362 0 : const WidgetPluginEvent* pluginEvent = AsPluginEvent();
363 0 : return pluginEvent && !pluginEvent->mRetargetToFocusedDocument;
364 : }
365 :
366 : bool
367 0 : WidgetEvent::IsIMERelatedEvent() const
368 : {
369 0 : return HasIMEEventMessage() || IsQueryContentEvent() || IsSelectionEvent();
370 : }
371 :
372 : bool
373 22 : WidgetEvent::IsUsingCoordinates() const
374 : {
375 22 : const WidgetMouseEvent* mouseEvent = AsMouseEvent();
376 22 : if (mouseEvent) {
377 22 : return !mouseEvent->IsContextMenuKeyEvent();
378 : }
379 0 : return !HasKeyEventMessage() && !IsIMERelatedEvent() &&
380 0 : !HasPluginActivationEventMessage() &&
381 0 : !IsNativeEventDelivererForPlugin() &&
382 0 : !IsContentCommandEvent();
383 : }
384 :
385 : bool
386 19 : WidgetEvent::IsTargetedAtFocusedWindow() const
387 : {
388 19 : const WidgetMouseEvent* mouseEvent = AsMouseEvent();
389 19 : if (mouseEvent) {
390 19 : return mouseEvent->IsContextMenuKeyEvent();
391 : }
392 0 : return HasKeyEventMessage() || IsIMERelatedEvent() ||
393 0 : IsContentCommandEvent() ||
394 0 : IsRetargetedNativeEventDelivererForPlugin();
395 : }
396 :
397 : bool
398 0 : WidgetEvent::IsTargetedAtFocusedContent() const
399 : {
400 0 : const WidgetMouseEvent* mouseEvent = AsMouseEvent();
401 0 : if (mouseEvent) {
402 0 : return mouseEvent->IsContextMenuKeyEvent();
403 : }
404 0 : return HasKeyEventMessage() || IsIMERelatedEvent() ||
405 0 : IsRetargetedNativeEventDelivererForPlugin();
406 : }
407 :
408 : bool
409 16 : WidgetEvent::IsAllowedToDispatchDOMEvent() const
410 : {
411 16 : switch (mClass) {
412 : case eMouseEventClass:
413 : // When content PreventDefault on ePointerDown, we will stop dispatching
414 : // the subsequent mouse events (eMouseDown, eMouseUp, eMouseMove). But we
415 : // still need the mouse events to be handled in EventStateManager to
416 : // generate other events (e.g. eMouseClick). So we only stop dispatching
417 : // them to DOM.
418 12 : if (DefaultPreventedByContent() &&
419 0 : (mMessage == eMouseMove || mMessage == eMouseDown ||
420 0 : mMessage == eMouseUp)) {
421 0 : return false;
422 : }
423 12 : if (mMessage == eMouseTouchDrag) {
424 0 : return false;
425 : }
426 : MOZ_FALLTHROUGH;
427 : case ePointerEventClass:
428 : // We want synthesized mouse moves to cause mouseover and mouseout
429 : // DOM events (EventStateManager::PreHandleEvent), but not mousemove
430 : // DOM events.
431 : // Synthesized button up events also do not cause DOM events because they
432 : // do not have a reliable mRefPoint.
433 16 : return AsMouseEvent()->mReason == WidgetMouseEvent::eReal;
434 :
435 : case eWheelEventClass: {
436 : // wheel event whose all delta values are zero by user pref applied, it
437 : // shouldn't cause a DOM event.
438 0 : const WidgetWheelEvent* wheelEvent = AsWheelEvent();
439 0 : return wheelEvent->mDeltaX != 0.0 || wheelEvent->mDeltaY != 0.0 ||
440 0 : wheelEvent->mDeltaZ != 0.0;
441 : }
442 : case eTouchEventClass:
443 0 : return mMessage != eTouchPointerCancel;
444 : // Following events are handled in EventStateManager, so, we don't need to
445 : // dispatch DOM event for them into the DOM tree.
446 : case eQueryContentEventClass:
447 : case eSelectionEventClass:
448 : case eContentCommandEventClass:
449 0 : return false;
450 :
451 : default:
452 0 : return true;
453 : }
454 : }
455 :
456 : bool
457 449 : WidgetEvent::IsAllowedToDispatchInSystemGroup() const
458 : {
459 : // We don't expect to implement default behaviors with pointer events because
460 : // if we do, prevent default on mouse events can't prevent default behaviors
461 : // anymore.
462 449 : return mClass != ePointerEventClass;
463 : }
464 :
465 : /******************************************************************************
466 : * mozilla::WidgetEvent
467 : *
468 : * Misc methods.
469 : ******************************************************************************/
470 :
471 : static dom::EventTarget*
472 82 : GetTargetForDOMEvent(nsIDOMEventTarget* aTarget)
473 : {
474 82 : return aTarget ? aTarget->GetTargetForDOMEvent() : nullptr;
475 : }
476 :
477 : dom::EventTarget*
478 45 : WidgetEvent::GetDOMEventTarget() const
479 : {
480 45 : return GetTargetForDOMEvent(mTarget);
481 : }
482 :
483 : dom::EventTarget*
484 30 : WidgetEvent::GetCurrentDOMEventTarget() const
485 : {
486 30 : return GetTargetForDOMEvent(mCurrentTarget);
487 : }
488 :
489 : dom::EventTarget*
490 7 : WidgetEvent::GetOriginalDOMEventTarget() const
491 : {
492 7 : if (mOriginalTarget) {
493 7 : return GetTargetForDOMEvent(mOriginalTarget);
494 : }
495 0 : return GetDOMEventTarget();
496 : }
497 :
498 : /******************************************************************************
499 : * mozilla::WidgetInputEvent
500 : ******************************************************************************/
501 :
502 : /* static */
503 : Modifier
504 0 : WidgetInputEvent::GetModifier(const nsAString& aDOMKeyName)
505 : {
506 0 : if (aDOMKeyName.EqualsLiteral("Accel")) {
507 0 : return AccelModifier();
508 : }
509 0 : KeyNameIndex keyNameIndex = WidgetKeyboardEvent::GetKeyNameIndex(aDOMKeyName);
510 0 : return WidgetKeyboardEvent::GetModifierForKeyName(keyNameIndex);
511 : }
512 :
513 : /* static */
514 : Modifier
515 0 : WidgetInputEvent::AccelModifier()
516 : {
517 : static Modifier sAccelModifier = MODIFIER_NONE;
518 0 : if (sAccelModifier == MODIFIER_NONE) {
519 0 : switch (Preferences::GetInt("ui.key.accelKey", 0)) {
520 : case nsIDOMKeyEvent::DOM_VK_META:
521 0 : sAccelModifier = MODIFIER_META;
522 0 : break;
523 : case nsIDOMKeyEvent::DOM_VK_WIN:
524 0 : sAccelModifier = MODIFIER_OS;
525 0 : break;
526 : case nsIDOMKeyEvent::DOM_VK_ALT:
527 0 : sAccelModifier = MODIFIER_ALT;
528 0 : break;
529 : case nsIDOMKeyEvent::DOM_VK_CONTROL:
530 0 : sAccelModifier = MODIFIER_CONTROL;
531 0 : break;
532 : default:
533 : #ifdef XP_MACOSX
534 : sAccelModifier = MODIFIER_META;
535 : #else
536 0 : sAccelModifier = MODIFIER_CONTROL;
537 : #endif
538 0 : break;
539 : }
540 : }
541 0 : return sAccelModifier;
542 : }
543 :
544 : /******************************************************************************
545 : * mozilla::WidgetWheelEvent (MouseEvents.h)
546 : ******************************************************************************/
547 :
548 : /* static */ double
549 0 : WidgetWheelEvent::ComputeOverriddenDelta(double aDelta, bool aIsForVertical)
550 : {
551 0 : if (!gfxPrefs::MouseWheelHasRootScrollDeltaOverride()) {
552 0 : return aDelta;
553 : }
554 : int32_t intFactor = aIsForVertical
555 0 : ? gfxPrefs::MouseWheelRootScrollVerticalFactor()
556 0 : : gfxPrefs::MouseWheelRootScrollHorizontalFactor();
557 : // Making the scroll speed slower doesn't make sense. So, ignore odd factor
558 : // which is less than 1.0.
559 0 : if (intFactor <= 100) {
560 0 : return aDelta;
561 : }
562 0 : double factor = static_cast<double>(intFactor) / 100;
563 0 : return aDelta * factor;
564 : }
565 :
566 : double
567 0 : WidgetWheelEvent::OverriddenDeltaX() const
568 : {
569 0 : if (!mAllowToOverrideSystemScrollSpeed) {
570 0 : return mDeltaX;
571 : }
572 0 : return ComputeOverriddenDelta(mDeltaX, false);
573 : }
574 :
575 : double
576 0 : WidgetWheelEvent::OverriddenDeltaY() const
577 : {
578 0 : if (!mAllowToOverrideSystemScrollSpeed) {
579 0 : return mDeltaY;
580 : }
581 0 : return ComputeOverriddenDelta(mDeltaY, true);
582 : }
583 :
584 : /******************************************************************************
585 : * mozilla::WidgetKeyboardEvent (TextEvents.h)
586 : ******************************************************************************/
587 :
588 : #define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) (u"" aDOMKeyName),
589 : const char16_t* const WidgetKeyboardEvent::kKeyNames[] = {
590 : #include "mozilla/KeyNameList.h"
591 : };
592 : #undef NS_DEFINE_KEYNAME
593 :
594 : #define NS_DEFINE_PHYSICAL_KEY_CODE_NAME(aCPPName, aDOMCodeName) \
595 : (u"" aDOMCodeName),
596 : const char16_t* const WidgetKeyboardEvent::kCodeNames[] = {
597 : #include "mozilla/PhysicalKeyCodeNameList.h"
598 : };
599 : #undef NS_DEFINE_PHYSICAL_KEY_CODE_NAME
600 :
601 : WidgetKeyboardEvent::KeyNameIndexHashtable*
602 : WidgetKeyboardEvent::sKeyNameIndexHashtable = nullptr;
603 : WidgetKeyboardEvent::CodeNameIndexHashtable*
604 : WidgetKeyboardEvent::sCodeNameIndexHashtable = nullptr;
605 :
606 : void
607 0 : WidgetKeyboardEvent::InitAllEditCommands()
608 : {
609 : // If the event was created without widget, e.g., created event in chrome
610 : // script, this shouldn't execute native key bindings.
611 0 : if (NS_WARN_IF(!mWidget)) {
612 0 : return;
613 : }
614 :
615 : // This event should be trusted event here and we shouldn't expose native
616 : // key binding information to web contents with untrusted events.
617 0 : if (NS_WARN_IF(!IsTrusted())) {
618 0 : return;
619 : }
620 :
621 0 : MOZ_ASSERT(XRE_IsParentProcess(),
622 : "It's too expensive to retrieve all edit commands from remote process");
623 0 : MOZ_ASSERT(!AreAllEditCommandsInitialized(),
624 : "Shouldn't be called two or more times");
625 :
626 0 : InitEditCommandsFor(nsIWidget::NativeKeyBindingsForSingleLineEditor);
627 0 : InitEditCommandsFor(nsIWidget::NativeKeyBindingsForMultiLineEditor);
628 0 : InitEditCommandsFor(nsIWidget::NativeKeyBindingsForRichTextEditor);
629 : }
630 :
631 : void
632 0 : WidgetKeyboardEvent::InitEditCommandsFor(nsIWidget::NativeKeyBindingsType aType)
633 : {
634 0 : if (NS_WARN_IF(!mWidget) || NS_WARN_IF(!IsTrusted())) {
635 0 : return;
636 : }
637 :
638 0 : bool& initialized = IsEditCommandsInitializedRef(aType);
639 0 : if (initialized) {
640 0 : return;
641 : }
642 0 : nsTArray<CommandInt>& commands = EditCommandsRef(aType);
643 0 : mWidget->GetEditCommands(aType, *this, commands);
644 0 : initialized = true;
645 : }
646 :
647 : bool
648 0 : WidgetKeyboardEvent::ExecuteEditCommands(nsIWidget::NativeKeyBindingsType aType,
649 : DoCommandCallback aCallback,
650 : void* aCallbackData)
651 : {
652 : // If the event was created without widget, e.g., created event in chrome
653 : // script, this shouldn't execute native key bindings.
654 0 : if (NS_WARN_IF(!mWidget)) {
655 0 : return false;
656 : }
657 :
658 : // This event should be trusted event here and we shouldn't expose native
659 : // key binding information to web contents with untrusted events.
660 0 : if (NS_WARN_IF(!IsTrusted())) {
661 0 : return false;
662 : }
663 :
664 0 : InitEditCommandsFor(aType);
665 :
666 0 : const nsTArray<CommandInt>& commands = EditCommandsRef(aType);
667 0 : if (commands.IsEmpty()) {
668 0 : return false;
669 : }
670 :
671 0 : for (CommandInt command : commands) {
672 0 : aCallback(static_cast<Command>(command), aCallbackData);
673 : }
674 0 : return true;
675 : }
676 :
677 : bool
678 0 : WidgetKeyboardEvent::ShouldCauseKeypressEvents() const
679 : {
680 : // Currently, we don't dispatch keypress events of modifier keys and
681 : // dead keys.
682 0 : switch (mKeyNameIndex) {
683 : case KEY_NAME_INDEX_Alt:
684 : case KEY_NAME_INDEX_AltGraph:
685 : case KEY_NAME_INDEX_CapsLock:
686 : case KEY_NAME_INDEX_Control:
687 : case KEY_NAME_INDEX_Fn:
688 : case KEY_NAME_INDEX_FnLock:
689 : // case KEY_NAME_INDEX_Hyper:
690 : case KEY_NAME_INDEX_Meta:
691 : case KEY_NAME_INDEX_NumLock:
692 : case KEY_NAME_INDEX_OS:
693 : case KEY_NAME_INDEX_ScrollLock:
694 : case KEY_NAME_INDEX_Shift:
695 : // case KEY_NAME_INDEX_Super:
696 : case KEY_NAME_INDEX_Symbol:
697 : case KEY_NAME_INDEX_SymbolLock:
698 : case KEY_NAME_INDEX_Dead:
699 0 : return false;
700 : default:
701 0 : return true;
702 : }
703 : }
704 :
705 : static bool
706 0 : HasASCIIDigit(const ShortcutKeyCandidateArray& aCandidates)
707 : {
708 0 : for (uint32_t i = 0; i < aCandidates.Length(); ++i) {
709 0 : uint32_t ch = aCandidates[i].mCharCode;
710 0 : if (ch >= '0' && ch <= '9')
711 0 : return true;
712 : }
713 0 : return false;
714 : }
715 :
716 : static bool
717 0 : CharsCaseInsensitiveEqual(uint32_t aChar1, uint32_t aChar2)
718 : {
719 0 : return aChar1 == aChar2 ||
720 0 : (IS_IN_BMP(aChar1) && IS_IN_BMP(aChar2) &&
721 0 : ToLowerCase(static_cast<char16_t>(aChar1)) ==
722 0 : ToLowerCase(static_cast<char16_t>(aChar2)));
723 : }
724 :
725 : static bool
726 0 : IsCaseChangeableChar(uint32_t aChar)
727 : {
728 0 : return IS_IN_BMP(aChar) &&
729 0 : ToLowerCase(static_cast<char16_t>(aChar)) !=
730 0 : ToUpperCase(static_cast<char16_t>(aChar));
731 : }
732 :
733 : void
734 0 : WidgetKeyboardEvent::GetShortcutKeyCandidates(
735 : ShortcutKeyCandidateArray& aCandidates) const
736 : {
737 0 : MOZ_ASSERT(aCandidates.IsEmpty(), "aCandidates must be empty");
738 :
739 : // ShortcutKeyCandidate::mCharCode is a candidate charCode.
740 : // ShortcutKeyCandidate::mIgnoreShift means the mCharCode should be tried to
741 : // execute a command with/without shift key state. If this is TRUE, the
742 : // shifted key state should be ignored. Otherwise, don't ignore the state.
743 : // the priority of the charCodes are (shift key is not pressed):
744 : // 0: PseudoCharCode()/false,
745 : // 1: unshiftedCharCodes[0]/false, 2: unshiftedCharCodes[1]/false...
746 : // the priority of the charCodes are (shift key is pressed):
747 : // 0: PseudoCharCode()/false,
748 : // 1: shiftedCharCodes[0]/false, 2: shiftedCharCodes[0]/true,
749 : // 3: shiftedCharCodes[1]/false, 4: shiftedCharCodes[1]/true...
750 0 : uint32_t pseudoCharCode = PseudoCharCode();
751 0 : if (pseudoCharCode) {
752 0 : ShortcutKeyCandidate key(pseudoCharCode, false);
753 0 : aCandidates.AppendElement(key);
754 : }
755 :
756 0 : uint32_t len = mAlternativeCharCodes.Length();
757 0 : if (!IsShift()) {
758 0 : for (uint32_t i = 0; i < len; ++i) {
759 0 : uint32_t ch = mAlternativeCharCodes[i].mUnshiftedCharCode;
760 0 : if (!ch || ch == pseudoCharCode) {
761 0 : continue;
762 : }
763 0 : ShortcutKeyCandidate key(ch, false);
764 0 : aCandidates.AppendElement(key);
765 : }
766 : // If unshiftedCharCodes doesn't have numeric but shiftedCharCode has it,
767 : // this keyboard layout is AZERTY or similar layout, probably.
768 : // In this case, Accel+[0-9] should be accessible without shift key.
769 : // However, the priority should be lowest.
770 0 : if (!HasASCIIDigit(aCandidates)) {
771 0 : for (uint32_t i = 0; i < len; ++i) {
772 0 : uint32_t ch = mAlternativeCharCodes[i].mShiftedCharCode;
773 0 : if (ch >= '0' && ch <= '9') {
774 0 : ShortcutKeyCandidate key(ch, false);
775 0 : aCandidates.AppendElement(key);
776 0 : break;
777 : }
778 : }
779 : }
780 : } else {
781 0 : for (uint32_t i = 0; i < len; ++i) {
782 0 : uint32_t ch = mAlternativeCharCodes[i].mShiftedCharCode;
783 0 : if (!ch) {
784 0 : continue;
785 : }
786 :
787 0 : if (ch != pseudoCharCode) {
788 0 : ShortcutKeyCandidate key(ch, false);
789 0 : aCandidates.AppendElement(key);
790 : }
791 :
792 : // If the char is an alphabet, the shift key state should not be
793 : // ignored. E.g., Ctrl+Shift+C should not execute Ctrl+C.
794 :
795 : // And checking the charCode is same as unshiftedCharCode too.
796 : // E.g., for Ctrl+Shift+(Plus of Numpad) should not run Ctrl+Plus.
797 0 : uint32_t unshiftCh = mAlternativeCharCodes[i].mUnshiftedCharCode;
798 0 : if (CharsCaseInsensitiveEqual(ch, unshiftCh)) {
799 0 : continue;
800 : }
801 :
802 : // On the Hebrew keyboard layout on Windows, the unshifted char is a
803 : // localized character but the shifted char is a Latin alphabet,
804 : // then, we should not execute without the shift state. See bug 433192.
805 0 : if (IsCaseChangeableChar(ch)) {
806 0 : continue;
807 : }
808 :
809 : // Setting the alternative charCode candidates for retry without shift
810 : // key state only when the shift key is pressed.
811 0 : ShortcutKeyCandidate key(ch, true);
812 0 : aCandidates.AppendElement(key);
813 : }
814 : }
815 :
816 : // Special case for "Space" key. With some keyboard layouts, "Space" with
817 : // or without Shift key causes non-ASCII space. For such keyboard layouts,
818 : // we should guarantee that the key press works as an ASCII white space key
819 : // press. However, if the space key is assigned to a function key, it
820 : // shouldn't work as a space key.
821 0 : if (mKeyNameIndex == KEY_NAME_INDEX_USE_STRING &&
822 0 : mCodeNameIndex == CODE_NAME_INDEX_Space && pseudoCharCode != ' ') {
823 0 : ShortcutKeyCandidate spaceKey(' ', false);
824 0 : aCandidates.AppendElement(spaceKey);
825 : }
826 0 : }
827 :
828 : void
829 0 : WidgetKeyboardEvent::GetAccessKeyCandidates(nsTArray<uint32_t>& aCandidates) const
830 : {
831 0 : MOZ_ASSERT(aCandidates.IsEmpty(), "aCandidates must be empty");
832 :
833 : // return the lower cased charCode candidates for access keys.
834 : // the priority of the charCodes are:
835 : // 0: charCode, 1: unshiftedCharCodes[0], 2: shiftedCharCodes[0]
836 : // 3: unshiftedCharCodes[1], 4: shiftedCharCodes[1],...
837 0 : if (mCharCode) {
838 0 : uint32_t ch = mCharCode;
839 0 : if (IS_IN_BMP(ch)) {
840 0 : ch = ToLowerCase(static_cast<char16_t>(ch));
841 : }
842 0 : aCandidates.AppendElement(ch);
843 : }
844 0 : for (uint32_t i = 0; i < mAlternativeCharCodes.Length(); ++i) {
845 : uint32_t ch[2] =
846 0 : { mAlternativeCharCodes[i].mUnshiftedCharCode,
847 0 : mAlternativeCharCodes[i].mShiftedCharCode };
848 0 : for (uint32_t j = 0; j < 2; ++j) {
849 0 : if (!ch[j]) {
850 0 : continue;
851 : }
852 0 : if (IS_IN_BMP(ch[j])) {
853 0 : ch[j] = ToLowerCase(static_cast<char16_t>(ch[j]));
854 : }
855 : // Don't append the mCharCode that was already appended.
856 0 : if (aCandidates.IndexOf(ch[j]) == aCandidates.NoIndex) {
857 0 : aCandidates.AppendElement(ch[j]);
858 : }
859 : }
860 : }
861 : // Special case for "Space" key. With some keyboard layouts, "Space" with
862 : // or without Shift key causes non-ASCII space. For such keyboard layouts,
863 : // we should guarantee that the key press works as an ASCII white space key
864 : // press. However, if the space key is assigned to a function key, it
865 : // shouldn't work as a space key.
866 0 : if (mKeyNameIndex == KEY_NAME_INDEX_USE_STRING &&
867 0 : mCodeNameIndex == CODE_NAME_INDEX_Space && mCharCode != ' ') {
868 0 : aCandidates.AppendElement(' ');
869 : }
870 0 : return;
871 : }
872 :
873 : /* static */ void
874 0 : WidgetKeyboardEvent::Shutdown()
875 : {
876 0 : delete sKeyNameIndexHashtable;
877 0 : sKeyNameIndexHashtable = nullptr;
878 0 : delete sCodeNameIndexHashtable;
879 0 : sCodeNameIndexHashtable = nullptr;
880 0 : }
881 :
882 : /* static */ void
883 0 : WidgetKeyboardEvent::GetDOMKeyName(KeyNameIndex aKeyNameIndex,
884 : nsAString& aKeyName)
885 : {
886 0 : if (aKeyNameIndex >= KEY_NAME_INDEX_USE_STRING) {
887 0 : aKeyName.Truncate();
888 0 : return;
889 : }
890 :
891 0 : MOZ_RELEASE_ASSERT(static_cast<size_t>(aKeyNameIndex) <
892 : ArrayLength(kKeyNames),
893 : "Illegal key enumeration value");
894 0 : aKeyName = kKeyNames[aKeyNameIndex];
895 : }
896 :
897 : /* static */ void
898 0 : WidgetKeyboardEvent::GetDOMCodeName(CodeNameIndex aCodeNameIndex,
899 : nsAString& aCodeName)
900 : {
901 0 : if (aCodeNameIndex >= CODE_NAME_INDEX_USE_STRING) {
902 0 : aCodeName.Truncate();
903 0 : return;
904 : }
905 :
906 0 : MOZ_RELEASE_ASSERT(static_cast<size_t>(aCodeNameIndex) <
907 : ArrayLength(kCodeNames),
908 : "Illegal physical code enumeration value");
909 0 : aCodeName = kCodeNames[aCodeNameIndex];
910 : }
911 :
912 : /* static */ KeyNameIndex
913 0 : WidgetKeyboardEvent::GetKeyNameIndex(const nsAString& aKeyValue)
914 : {
915 0 : if (!sKeyNameIndexHashtable) {
916 0 : sKeyNameIndexHashtable =
917 0 : new KeyNameIndexHashtable(ArrayLength(kKeyNames));
918 0 : for (size_t i = 0; i < ArrayLength(kKeyNames); i++) {
919 0 : sKeyNameIndexHashtable->Put(nsDependentString(kKeyNames[i]),
920 0 : static_cast<KeyNameIndex>(i));
921 : }
922 : }
923 0 : KeyNameIndex result = KEY_NAME_INDEX_USE_STRING;
924 0 : sKeyNameIndexHashtable->Get(aKeyValue, &result);
925 0 : return result;
926 : }
927 :
928 : /* static */ CodeNameIndex
929 0 : WidgetKeyboardEvent::GetCodeNameIndex(const nsAString& aCodeValue)
930 : {
931 0 : if (!sCodeNameIndexHashtable) {
932 0 : sCodeNameIndexHashtable =
933 0 : new CodeNameIndexHashtable(ArrayLength(kCodeNames));
934 0 : for (size_t i = 0; i < ArrayLength(kCodeNames); i++) {
935 0 : sCodeNameIndexHashtable->Put(nsDependentString(kCodeNames[i]),
936 0 : static_cast<CodeNameIndex>(i));
937 : }
938 : }
939 0 : CodeNameIndex result = CODE_NAME_INDEX_USE_STRING;
940 0 : sCodeNameIndexHashtable->Get(aCodeValue, &result);
941 0 : return result;
942 : }
943 :
944 : /* static */ const char*
945 0 : WidgetKeyboardEvent::GetCommandStr(Command aCommand)
946 : {
947 : #define NS_DEFINE_COMMAND(aName, aCommandStr) , #aCommandStr
948 : static const char* const kCommands[] = {
949 : "" // CommandDoNothing
950 : #include "mozilla/CommandList.h"
951 : };
952 : #undef NS_DEFINE_COMMAND
953 :
954 0 : MOZ_RELEASE_ASSERT(static_cast<size_t>(aCommand) < ArrayLength(kCommands),
955 : "Illegal command enumeration value");
956 0 : return kCommands[aCommand];
957 : }
958 :
959 : /* static */ uint32_t
960 0 : WidgetKeyboardEvent::ComputeLocationFromCodeValue(CodeNameIndex aCodeNameIndex)
961 : {
962 : // Following commented out cases are not defined in PhysicalKeyCodeNameList.h
963 : // but are defined by D3E spec. So, they should be uncommented when the
964 : // code values are defined in the header.
965 0 : switch (aCodeNameIndex) {
966 : case CODE_NAME_INDEX_AltLeft:
967 : case CODE_NAME_INDEX_ControlLeft:
968 : case CODE_NAME_INDEX_OSLeft:
969 : case CODE_NAME_INDEX_ShiftLeft:
970 0 : return eKeyLocationLeft;
971 : case CODE_NAME_INDEX_AltRight:
972 : case CODE_NAME_INDEX_ControlRight:
973 : case CODE_NAME_INDEX_OSRight:
974 : case CODE_NAME_INDEX_ShiftRight:
975 0 : return eKeyLocationRight;
976 : case CODE_NAME_INDEX_Numpad0:
977 : case CODE_NAME_INDEX_Numpad1:
978 : case CODE_NAME_INDEX_Numpad2:
979 : case CODE_NAME_INDEX_Numpad3:
980 : case CODE_NAME_INDEX_Numpad4:
981 : case CODE_NAME_INDEX_Numpad5:
982 : case CODE_NAME_INDEX_Numpad6:
983 : case CODE_NAME_INDEX_Numpad7:
984 : case CODE_NAME_INDEX_Numpad8:
985 : case CODE_NAME_INDEX_Numpad9:
986 : case CODE_NAME_INDEX_NumpadAdd:
987 : case CODE_NAME_INDEX_NumpadBackspace:
988 : case CODE_NAME_INDEX_NumpadClear:
989 : case CODE_NAME_INDEX_NumpadClearEntry:
990 : case CODE_NAME_INDEX_NumpadComma:
991 : case CODE_NAME_INDEX_NumpadDecimal:
992 : case CODE_NAME_INDEX_NumpadDivide:
993 : case CODE_NAME_INDEX_NumpadEnter:
994 : case CODE_NAME_INDEX_NumpadEqual:
995 : case CODE_NAME_INDEX_NumpadMemoryAdd:
996 : case CODE_NAME_INDEX_NumpadMemoryClear:
997 : case CODE_NAME_INDEX_NumpadMemoryRecall:
998 : case CODE_NAME_INDEX_NumpadMemoryStore:
999 : case CODE_NAME_INDEX_NumpadMemorySubtract:
1000 : case CODE_NAME_INDEX_NumpadMultiply:
1001 : case CODE_NAME_INDEX_NumpadParenLeft:
1002 : case CODE_NAME_INDEX_NumpadParenRight:
1003 : case CODE_NAME_INDEX_NumpadSubtract:
1004 0 : return eKeyLocationNumpad;
1005 : default:
1006 0 : return eKeyLocationStandard;
1007 : }
1008 : }
1009 :
1010 : /* static */ uint32_t
1011 0 : WidgetKeyboardEvent::ComputeKeyCodeFromKeyNameIndex(KeyNameIndex aKeyNameIndex)
1012 : {
1013 0 : switch (aKeyNameIndex) {
1014 : case KEY_NAME_INDEX_Cancel:
1015 0 : return nsIDOMKeyEvent::DOM_VK_CANCEL;
1016 : case KEY_NAME_INDEX_Help:
1017 0 : return nsIDOMKeyEvent::DOM_VK_HELP;
1018 : case KEY_NAME_INDEX_Backspace:
1019 0 : return nsIDOMKeyEvent::DOM_VK_BACK_SPACE;
1020 : case KEY_NAME_INDEX_Tab:
1021 0 : return nsIDOMKeyEvent::DOM_VK_TAB;
1022 : case KEY_NAME_INDEX_Clear:
1023 0 : return nsIDOMKeyEvent::DOM_VK_CLEAR;
1024 : case KEY_NAME_INDEX_Enter:
1025 0 : return nsIDOMKeyEvent::DOM_VK_RETURN;
1026 : case KEY_NAME_INDEX_Shift:
1027 0 : return nsIDOMKeyEvent::DOM_VK_SHIFT;
1028 : case KEY_NAME_INDEX_Control:
1029 0 : return nsIDOMKeyEvent::DOM_VK_CONTROL;
1030 : case KEY_NAME_INDEX_Alt:
1031 0 : return nsIDOMKeyEvent::DOM_VK_ALT;
1032 : case KEY_NAME_INDEX_Pause:
1033 0 : return nsIDOMKeyEvent::DOM_VK_PAUSE;
1034 : case KEY_NAME_INDEX_CapsLock:
1035 0 : return nsIDOMKeyEvent::DOM_VK_CAPS_LOCK;
1036 : case KEY_NAME_INDEX_Hiragana:
1037 : case KEY_NAME_INDEX_Katakana:
1038 : case KEY_NAME_INDEX_HiraganaKatakana:
1039 : case KEY_NAME_INDEX_KanaMode:
1040 0 : return nsIDOMKeyEvent::DOM_VK_KANA;
1041 : case KEY_NAME_INDEX_HangulMode:
1042 0 : return nsIDOMKeyEvent::DOM_VK_HANGUL;
1043 : case KEY_NAME_INDEX_Eisu:
1044 0 : return nsIDOMKeyEvent::DOM_VK_EISU;
1045 : case KEY_NAME_INDEX_JunjaMode:
1046 0 : return nsIDOMKeyEvent::DOM_VK_JUNJA;
1047 : case KEY_NAME_INDEX_FinalMode:
1048 0 : return nsIDOMKeyEvent::DOM_VK_FINAL;
1049 : case KEY_NAME_INDEX_HanjaMode:
1050 0 : return nsIDOMKeyEvent::DOM_VK_HANJA;
1051 : case KEY_NAME_INDEX_KanjiMode:
1052 0 : return nsIDOMKeyEvent::DOM_VK_KANJI;
1053 : case KEY_NAME_INDEX_Escape:
1054 0 : return nsIDOMKeyEvent::DOM_VK_ESCAPE;
1055 : case KEY_NAME_INDEX_Convert:
1056 0 : return nsIDOMKeyEvent::DOM_VK_CONVERT;
1057 : case KEY_NAME_INDEX_NonConvert:
1058 0 : return nsIDOMKeyEvent::DOM_VK_NONCONVERT;
1059 : case KEY_NAME_INDEX_Accept:
1060 0 : return nsIDOMKeyEvent::DOM_VK_ACCEPT;
1061 : case KEY_NAME_INDEX_ModeChange:
1062 0 : return nsIDOMKeyEvent::DOM_VK_MODECHANGE;
1063 : case KEY_NAME_INDEX_PageUp:
1064 0 : return nsIDOMKeyEvent::DOM_VK_PAGE_UP;
1065 : case KEY_NAME_INDEX_PageDown:
1066 0 : return nsIDOMKeyEvent::DOM_VK_PAGE_DOWN;
1067 : case KEY_NAME_INDEX_End:
1068 0 : return nsIDOMKeyEvent::DOM_VK_END;
1069 : case KEY_NAME_INDEX_Home:
1070 0 : return nsIDOMKeyEvent::DOM_VK_HOME;
1071 : case KEY_NAME_INDEX_ArrowLeft:
1072 0 : return nsIDOMKeyEvent::DOM_VK_LEFT;
1073 : case KEY_NAME_INDEX_ArrowUp:
1074 0 : return nsIDOMKeyEvent::DOM_VK_UP;
1075 : case KEY_NAME_INDEX_ArrowRight:
1076 0 : return nsIDOMKeyEvent::DOM_VK_RIGHT;
1077 : case KEY_NAME_INDEX_ArrowDown:
1078 0 : return nsIDOMKeyEvent::DOM_VK_DOWN;
1079 : case KEY_NAME_INDEX_Select:
1080 0 : return nsIDOMKeyEvent::DOM_VK_SELECT;
1081 : case KEY_NAME_INDEX_Print:
1082 0 : return nsIDOMKeyEvent::DOM_VK_PRINT;
1083 : case KEY_NAME_INDEX_Execute:
1084 0 : return nsIDOMKeyEvent::DOM_VK_EXECUTE;
1085 : case KEY_NAME_INDEX_PrintScreen:
1086 0 : return nsIDOMKeyEvent::DOM_VK_PRINTSCREEN;
1087 : case KEY_NAME_INDEX_Insert:
1088 0 : return nsIDOMKeyEvent::DOM_VK_INSERT;
1089 : case KEY_NAME_INDEX_Delete:
1090 0 : return nsIDOMKeyEvent::DOM_VK_DELETE;
1091 : case KEY_NAME_INDEX_OS:
1092 : // case KEY_NAME_INDEX_Super:
1093 : // case KEY_NAME_INDEX_Hyper:
1094 0 : return nsIDOMKeyEvent::DOM_VK_WIN;
1095 : case KEY_NAME_INDEX_ContextMenu:
1096 0 : return nsIDOMKeyEvent::DOM_VK_CONTEXT_MENU;
1097 : case KEY_NAME_INDEX_Standby:
1098 0 : return nsIDOMKeyEvent::DOM_VK_SLEEP;
1099 : case KEY_NAME_INDEX_F1:
1100 0 : return nsIDOMKeyEvent::DOM_VK_F1;
1101 : case KEY_NAME_INDEX_F2:
1102 0 : return nsIDOMKeyEvent::DOM_VK_F2;
1103 : case KEY_NAME_INDEX_F3:
1104 0 : return nsIDOMKeyEvent::DOM_VK_F3;
1105 : case KEY_NAME_INDEX_F4:
1106 0 : return nsIDOMKeyEvent::DOM_VK_F4;
1107 : case KEY_NAME_INDEX_F5:
1108 0 : return nsIDOMKeyEvent::DOM_VK_F5;
1109 : case KEY_NAME_INDEX_F6:
1110 0 : return nsIDOMKeyEvent::DOM_VK_F6;
1111 : case KEY_NAME_INDEX_F7:
1112 0 : return nsIDOMKeyEvent::DOM_VK_F7;
1113 : case KEY_NAME_INDEX_F8:
1114 0 : return nsIDOMKeyEvent::DOM_VK_F8;
1115 : case KEY_NAME_INDEX_F9:
1116 0 : return nsIDOMKeyEvent::DOM_VK_F9;
1117 : case KEY_NAME_INDEX_F10:
1118 0 : return nsIDOMKeyEvent::DOM_VK_F10;
1119 : case KEY_NAME_INDEX_F11:
1120 0 : return nsIDOMKeyEvent::DOM_VK_F11;
1121 : case KEY_NAME_INDEX_F12:
1122 0 : return nsIDOMKeyEvent::DOM_VK_F12;
1123 : case KEY_NAME_INDEX_F13:
1124 0 : return nsIDOMKeyEvent::DOM_VK_F13;
1125 : case KEY_NAME_INDEX_F14:
1126 0 : return nsIDOMKeyEvent::DOM_VK_F14;
1127 : case KEY_NAME_INDEX_F15:
1128 0 : return nsIDOMKeyEvent::DOM_VK_F15;
1129 : case KEY_NAME_INDEX_F16:
1130 0 : return nsIDOMKeyEvent::DOM_VK_F16;
1131 : case KEY_NAME_INDEX_F17:
1132 0 : return nsIDOMKeyEvent::DOM_VK_F17;
1133 : case KEY_NAME_INDEX_F18:
1134 0 : return nsIDOMKeyEvent::DOM_VK_F18;
1135 : case KEY_NAME_INDEX_F19:
1136 0 : return nsIDOMKeyEvent::DOM_VK_F19;
1137 : case KEY_NAME_INDEX_F20:
1138 0 : return nsIDOMKeyEvent::DOM_VK_F20;
1139 : case KEY_NAME_INDEX_F21:
1140 0 : return nsIDOMKeyEvent::DOM_VK_F21;
1141 : case KEY_NAME_INDEX_F22:
1142 0 : return nsIDOMKeyEvent::DOM_VK_F22;
1143 : case KEY_NAME_INDEX_F23:
1144 0 : return nsIDOMKeyEvent::DOM_VK_F23;
1145 : case KEY_NAME_INDEX_F24:
1146 0 : return nsIDOMKeyEvent::DOM_VK_F24;
1147 : case KEY_NAME_INDEX_NumLock:
1148 0 : return nsIDOMKeyEvent::DOM_VK_NUM_LOCK;
1149 : case KEY_NAME_INDEX_ScrollLock:
1150 0 : return nsIDOMKeyEvent::DOM_VK_SCROLL_LOCK;
1151 : case KEY_NAME_INDEX_AudioVolumeMute:
1152 0 : return nsIDOMKeyEvent::DOM_VK_VOLUME_MUTE;
1153 : case KEY_NAME_INDEX_AudioVolumeDown:
1154 0 : return nsIDOMKeyEvent::DOM_VK_VOLUME_DOWN;
1155 : case KEY_NAME_INDEX_AudioVolumeUp:
1156 0 : return nsIDOMKeyEvent::DOM_VK_VOLUME_UP;
1157 : case KEY_NAME_INDEX_Meta:
1158 0 : return nsIDOMKeyEvent::DOM_VK_META;
1159 : case KEY_NAME_INDEX_AltGraph:
1160 0 : return nsIDOMKeyEvent::DOM_VK_ALTGR;
1161 : case KEY_NAME_INDEX_Attn:
1162 0 : return nsIDOMKeyEvent::DOM_VK_ATTN;
1163 : case KEY_NAME_INDEX_CrSel:
1164 0 : return nsIDOMKeyEvent::DOM_VK_CRSEL;
1165 : case KEY_NAME_INDEX_ExSel:
1166 0 : return nsIDOMKeyEvent::DOM_VK_EXSEL;
1167 : case KEY_NAME_INDEX_EraseEof:
1168 0 : return nsIDOMKeyEvent::DOM_VK_EREOF;
1169 : case KEY_NAME_INDEX_Play:
1170 0 : return nsIDOMKeyEvent::DOM_VK_PLAY;
1171 : case KEY_NAME_INDEX_ZoomToggle:
1172 : case KEY_NAME_INDEX_ZoomIn:
1173 : case KEY_NAME_INDEX_ZoomOut:
1174 0 : return nsIDOMKeyEvent::DOM_VK_ZOOM;
1175 : default:
1176 0 : return 0;
1177 : }
1178 : }
1179 :
1180 : /* static */ Modifier
1181 0 : WidgetKeyboardEvent::GetModifierForKeyName(KeyNameIndex aKeyNameIndex)
1182 : {
1183 0 : switch (aKeyNameIndex) {
1184 : case KEY_NAME_INDEX_Alt:
1185 0 : return MODIFIER_ALT;
1186 : case KEY_NAME_INDEX_AltGraph:
1187 0 : return MODIFIER_ALTGRAPH;
1188 : case KEY_NAME_INDEX_CapsLock:
1189 0 : return MODIFIER_CAPSLOCK;
1190 : case KEY_NAME_INDEX_Control:
1191 0 : return MODIFIER_CONTROL;
1192 : case KEY_NAME_INDEX_Fn:
1193 0 : return MODIFIER_FN;
1194 : case KEY_NAME_INDEX_FnLock:
1195 0 : return MODIFIER_FNLOCK;
1196 : // case KEY_NAME_INDEX_Hyper:
1197 : case KEY_NAME_INDEX_Meta:
1198 0 : return MODIFIER_META;
1199 : case KEY_NAME_INDEX_NumLock:
1200 0 : return MODIFIER_NUMLOCK;
1201 : case KEY_NAME_INDEX_OS:
1202 0 : return MODIFIER_OS;
1203 : case KEY_NAME_INDEX_ScrollLock:
1204 0 : return MODIFIER_SCROLLLOCK;
1205 : case KEY_NAME_INDEX_Shift:
1206 0 : return MODIFIER_SHIFT;
1207 : // case KEY_NAME_INDEX_Super:
1208 : case KEY_NAME_INDEX_Symbol:
1209 0 : return MODIFIER_SYMBOL;
1210 : case KEY_NAME_INDEX_SymbolLock:
1211 0 : return MODIFIER_SYMBOLLOCK;
1212 : default:
1213 0 : return MODIFIER_NONE;
1214 : }
1215 : }
1216 :
1217 : /* static */ bool
1218 0 : WidgetKeyboardEvent::IsLockableModifier(KeyNameIndex aKeyNameIndex)
1219 : {
1220 0 : switch (aKeyNameIndex) {
1221 : case KEY_NAME_INDEX_CapsLock:
1222 : case KEY_NAME_INDEX_FnLock:
1223 : case KEY_NAME_INDEX_NumLock:
1224 : case KEY_NAME_INDEX_ScrollLock:
1225 : case KEY_NAME_INDEX_SymbolLock:
1226 0 : return true;
1227 : default:
1228 0 : return false;
1229 : }
1230 : }
1231 :
1232 : } // namespace mozilla
|