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 #ifndef mozilla_TextEvents_h__
7 #define mozilla_TextEvents_h__
11 #include "mozilla/Assertions.h"
12 #include "mozilla/BasicEvents.h"
13 #include "mozilla/CheckedInt.h"
14 #include "mozilla/EventForwards.h" // for KeyNameIndex, temporarily
15 #include "mozilla/FontRange.h"
16 #include "mozilla/TextRange.h"
17 #include "mozilla/WritingModes.h"
18 #include "mozilla/dom/KeyboardEventBinding.h"
20 #include "nsISelectionController.h"
21 #include "nsISelectionListener.h"
22 #include "nsITransferable.h"
27 class nsStringHashKey
;
28 template<class, class> class nsDataHashtable
;
30 /******************************************************************************
31 * virtual keycode values
32 ******************************************************************************/
36 #define NS_DEFINE_VK(aDOMKeyName, aDOMKeyCode) NS_##aDOMKeyName = aDOMKeyCode,
37 #include "mozilla/VirtualKeyCodeList.h"
46 eKeyLocationStandard
= dom::KeyboardEventBinding::DOM_KEY_LOCATION_STANDARD
,
47 eKeyLocationLeft
= dom::KeyboardEventBinding::DOM_KEY_LOCATION_LEFT
,
48 eKeyLocationRight
= dom::KeyboardEventBinding::DOM_KEY_LOCATION_RIGHT
,
49 eKeyLocationNumpad
= dom::KeyboardEventBinding::DOM_KEY_LOCATION_NUMPAD
52 const nsCString
GetDOMKeyCodeName(uint32_t aKeyCode
);
59 class PPluginInstanceChild
;
60 } // namespace plugins
62 enum class AccessKeyType
64 // Handle access key for chrome.
66 // Handle access key for content.
68 // Don't handle access key.
72 /******************************************************************************
73 * mozilla::AlternativeCharCode
75 * This stores alternative charCode values of a key event with some modifiers.
76 * The stored values proper for testing shortcut key or access key.
77 ******************************************************************************/
79 struct AlternativeCharCode
81 AlternativeCharCode() :
82 mUnshiftedCharCode(0), mShiftedCharCode(0)
85 AlternativeCharCode(uint32_t aUnshiftedCharCode
, uint32_t aShiftedCharCode
) :
86 mUnshiftedCharCode(aUnshiftedCharCode
), mShiftedCharCode(aShiftedCharCode
)
89 uint32_t mUnshiftedCharCode
;
90 uint32_t mShiftedCharCode
;
93 /******************************************************************************
94 * mozilla::ShortcutKeyCandidate
96 * This stores a candidate of shortcut key combination.
97 ******************************************************************************/
99 struct ShortcutKeyCandidate
101 ShortcutKeyCandidate()
106 ShortcutKeyCandidate(uint32_t aCharCode
, bool aIgnoreShift
)
107 : mCharCode(aCharCode
)
108 , mIgnoreShift(aIgnoreShift
)
111 // The mCharCode value which must match keyboard shortcut definition.
113 // true if Shift state can be ignored. Otherwise, Shift key state must
114 // match keyboard shortcut definition.
118 /******************************************************************************
119 * mozilla::IgnoreModifierState
121 * This stores flags for modifiers that should be ignored when matching
123 ******************************************************************************/
125 struct IgnoreModifierState
127 // When mShift is true, Shift key state will be ignored.
129 // When mOS is true, OS key state will be ignored.
132 IgnoreModifierState()
139 /******************************************************************************
140 * mozilla::WidgetKeyboardEvent
141 ******************************************************************************/
143 class WidgetKeyboardEvent
: public WidgetInputEvent
146 friend class dom::PBrowserParent
;
147 friend class dom::PBrowserChild
;
148 friend struct IPC::ParamTraits
<WidgetKeyboardEvent
>;
151 WidgetKeyboardEvent()
152 : mNativeKeyEvent(nullptr)
156 , mLocation(eKeyLocationStandard
)
159 , mNativeModifierFlags(0)
161 #endif // #ifdef XP_MACOSX
162 , mKeyNameIndex(KEY_NAME_INDEX_Unidentified
)
163 , mCodeNameIndex(CODE_NAME_INDEX_UNKNOWN
)
165 , mIsComposing(false)
166 , mIsSynthesizedByTIP(false)
167 , mEditCommandsForSingleLineEditorInitialized(false)
168 , mEditCommandsForMultiLineEditorInitialized(false)
169 , mEditCommandsForRichTextEditorInitialized(false)
174 virtual WidgetKeyboardEvent
* AsKeyboardEvent() override
{ return this; }
176 WidgetKeyboardEvent(bool aIsTrusted
, EventMessage aMessage
,
178 EventClassID aEventClassID
= eKeyboardEventClass
)
179 : WidgetInputEvent(aIsTrusted
, aMessage
, aWidget
, aEventClassID
)
180 , mNativeKeyEvent(nullptr)
184 , mLocation(eKeyLocationStandard
)
187 , mNativeModifierFlags(0)
189 #endif // #ifdef XP_MACOSX
190 , mKeyNameIndex(KEY_NAME_INDEX_Unidentified
)
191 , mCodeNameIndex(CODE_NAME_INDEX_UNKNOWN
)
193 , mIsComposing(false)
194 , mIsSynthesizedByTIP(false)
195 , mEditCommandsForSingleLineEditorInitialized(false)
196 , mEditCommandsForMultiLineEditorInitialized(false)
197 , mEditCommandsForRichTextEditorInitialized(false)
199 // If this is a keyboard event on a plugin, it shouldn't fired on content.
200 if (IsKeyEventOnPlugin()) {
201 mFlags
.mOnlySystemGroupDispatchInContent
= true;
202 StopCrossProcessForwarding();
206 static bool IsKeyDownOrKeyDownOnPlugin(EventMessage aMessage
)
208 return aMessage
== eKeyDown
|| aMessage
== eKeyDownOnPlugin
;
210 bool IsKeyDownOrKeyDownOnPlugin() const
212 return IsKeyDownOrKeyDownOnPlugin(mMessage
);
214 static bool IsKeyUpOrKeyUpOnPlugin(EventMessage aMessage
)
216 return aMessage
== eKeyUp
|| aMessage
== eKeyUpOnPlugin
;
218 bool IsKeyUpOrKeyUpOnPlugin() const
220 return IsKeyUpOrKeyUpOnPlugin(mMessage
);
222 static bool IsKeyEventOnPlugin(EventMessage aMessage
)
224 return aMessage
== eKeyDownOnPlugin
|| aMessage
== eKeyUpOnPlugin
;
226 bool IsKeyEventOnPlugin() const
228 return IsKeyEventOnPlugin(mMessage
);
231 bool IsInputtingText() const
233 // NOTE: On some keyboard layout, some characters are inputted with Control
234 // key or Alt key, but at that time, widget unset the modifier flag
235 // from eKeyPress event.
236 return mMessage
== eKeyPress
&&
238 !(mModifiers
& (MODIFIER_ALT
|
244 bool IsInputtingLineBreak() const
246 return mMessage
== eKeyPress
&&
247 mKeyNameIndex
== KEY_NAME_INDEX_Enter
&&
248 !(mModifiers
& (MODIFIER_ALT
|
255 * ShouldKeyPressEventBeFiredOnContent() should be called only when the
256 * instance is eKeyPress event. This returns true when the eKeyPress
257 * event should be fired even on content in the default event group.
259 bool ShouldKeyPressEventBeFiredOnContent() const
261 MOZ_DIAGNOSTIC_ASSERT(mMessage
== eKeyPress
);
262 if (IsInputtingText() || IsInputtingLineBreak()) {
265 // Ctrl + Enter won't cause actual input in our editor.
266 // However, the other browsers fire keypress event in any platforms.
267 // So, for compatibility with them, we should fire keypress event for
269 return mMessage
== eKeyPress
&&
270 mKeyNameIndex
== KEY_NAME_INDEX_Enter
&&
271 !(mModifiers
& (MODIFIER_ALT
|
277 virtual WidgetEvent
* Duplicate() const override
279 MOZ_ASSERT(mClass
== eKeyboardEventClass
,
280 "Duplicate() must be overridden by sub class");
281 // Not copying widget, it is a weak reference.
282 WidgetKeyboardEvent
* result
=
283 new WidgetKeyboardEvent(false, mMessage
, nullptr);
284 result
->AssignKeyEventData(*this, true);
285 result
->mEditCommandsForSingleLineEditor
= mEditCommandsForSingleLineEditor
;
286 result
->mEditCommandsForMultiLineEditor
= mEditCommandsForMultiLineEditor
;
287 result
->mEditCommandsForRichTextEditor
= mEditCommandsForRichTextEditor
;
288 result
->mFlags
= mFlags
;
292 // OS translated Unicode chars which are used for accesskey and accelkey
293 // handling. The handlers will try from first character to last character.
294 nsTArray
<AlternativeCharCode
> mAlternativeCharCodes
;
295 // DOM KeyboardEvent.key only when mKeyNameIndex is KEY_NAME_INDEX_USE_STRING.
297 // DOM KeyboardEvent.code only when mCodeNameIndex is
298 // CODE_NAME_INDEX_USE_STRING.
302 // Values given by a native NSEvent, for use with Cocoa NPAPI plugins.
303 nsString mNativeCharacters
;
304 nsString mNativeCharactersIgnoringModifiers
;
305 // If this is non-empty, create a text event for plugins instead of a
307 nsString mPluginTextEventString
;
308 #endif // #ifdef XP_MACOSX
310 // OS-specific native event can optionally be preserved
311 void* mNativeKeyEvent
;
312 // A DOM keyCode value or 0. If a keypress event whose mCharCode is 0, this
315 // If the instance is a keypress event of a printable key, this is a UTF-16
316 // value of the key. Otherwise, 0. This value must not be a control
317 // character when some modifiers are active. Then, this value should be an
318 // unmodified value except Shift and AltGr.
320 // mPseudoCharCode is valid only when mMessage is an eKeyDown event.
321 // This stores mCharCode value of keypress event which is fired with same
322 // key value and same modifier state.
323 uint32_t mPseudoCharCode
;
324 // One of eKeyLocation*
326 // Unique id associated with a keydown / keypress event. It's ok if this wraps
327 // over long periods.
331 // Values given by a native NSEvent, for use with Cocoa NPAPI plugins.
332 uint32_t mNativeModifierFlags
;
333 uint16_t mNativeKeyCode
;
334 #endif // #ifdef XP_MACOSX
336 // DOM KeyboardEvent.key
337 KeyNameIndex mKeyNameIndex
;
338 // DOM KeyboardEvent.code
339 CodeNameIndex mCodeNameIndex
;
341 // Indicates whether the event is generated by auto repeat or not.
342 // if this is keyup event, always false.
344 // Indicates whether the event is generated during IME (or deadkey)
345 // composition. This is initialized by EventStateManager. So, key event
346 // dispatchers don't need to initialize this.
348 // Indicates whether the event is synthesized from Text Input Processor
349 // or an actual event from nsAppShell.
350 bool mIsSynthesizedByTIP
;
353 * Retrieves all edit commands from mWidget. This shouldn't be called when
354 * the instance is an untrusted event, doesn't have widget or in non-chrome
357 void InitAllEditCommands();
360 * Retrieves edit commands from mWidget only for aType. This shouldn't be
361 * called when the instance is an untrusted event or doesn't have widget.
363 void InitEditCommandsFor(nsIWidget::NativeKeyBindingsType aType
);
366 * PreventNativeKeyBindings() makes the instance to not cause any edit
367 * actions even if it matches with a native key binding.
369 void PreventNativeKeyBindings()
371 mEditCommandsForSingleLineEditor
.Clear();
372 mEditCommandsForMultiLineEditor
.Clear();
373 mEditCommandsForRichTextEditor
.Clear();
374 mEditCommandsForSingleLineEditorInitialized
= true;
375 mEditCommandsForMultiLineEditorInitialized
= true;
376 mEditCommandsForRichTextEditorInitialized
= true;
380 * EditCommandsConstRef() returns reference to edit commands for aType.
382 const nsTArray
<CommandInt
>&
383 EditCommandsConstRef(nsIWidget::NativeKeyBindingsType aType
) const
385 return const_cast<WidgetKeyboardEvent
*>(this)->EditCommandsRef(aType
);
389 * IsEditCommandsInitialized() returns true if edit commands for aType
390 * was already initialized. Otherwise, false.
392 bool IsEditCommandsInitialized(
393 nsIWidget::NativeKeyBindingsType aType
) const
395 return const_cast<WidgetKeyboardEvent
*>(this)->
396 IsEditCommandsInitializedRef(aType
);
401 * AreAllEditCommandsInitialized() returns true if edit commands for all
402 * types were already initialized. Otherwise, false.
404 bool AreAllEditCommandsInitialized() const
406 return mEditCommandsForSingleLineEditorInitialized
&&
407 mEditCommandsForMultiLineEditorInitialized
&&
408 mEditCommandsForRichTextEditorInitialized
;
410 #endif // #ifdef DEBUG
413 * Execute edit commands for aType.
415 * @return true if the caller should do nothing anymore.
418 typedef void (*DoCommandCallback
)(Command
, void*);
419 bool ExecuteEditCommands(nsIWidget::NativeKeyBindingsType aType
,
420 DoCommandCallback aCallback
,
421 void* aCallbackData
);
423 // If the key should cause keypress events, this returns true.
425 bool ShouldCauseKeypressEvents() const;
427 // mCharCode value of non-eKeyPress events is always 0. However, if
428 // non-eKeyPress event has one or more alternative char code values,
429 // its first item should be the mCharCode value of following eKeyPress event.
430 // PseudoCharCode() returns mCharCode value for eKeyPress event,
431 // the first alternative char code value of non-eKeyPress event or 0.
432 uint32_t PseudoCharCode() const
434 return mMessage
== eKeyPress
? mCharCode
: mPseudoCharCode
;
436 void SetCharCode(uint32_t aCharCode
)
438 if (mMessage
== eKeyPress
) {
439 mCharCode
= aCharCode
;
441 mPseudoCharCode
= aCharCode
;
445 void GetDOMKeyName(nsAString
& aKeyName
)
447 if (mKeyNameIndex
== KEY_NAME_INDEX_USE_STRING
) {
448 aKeyName
= mKeyValue
;
451 GetDOMKeyName(mKeyNameIndex
, aKeyName
);
453 void GetDOMCodeName(nsAString
& aCodeName
)
455 if (mCodeNameIndex
== CODE_NAME_INDEX_USE_STRING
) {
456 aCodeName
= mCodeValue
;
459 GetDOMCodeName(mCodeNameIndex
, aCodeName
);
463 * GetFallbackKeyCodeOfPunctuationKey() returns a DOM keyCode value for
464 * aCodeNameIndex. This is keyCode value of the key when active keyboard
465 * layout is ANSI (US), JIS or ABNT keyboard layout (the latter 2 layouts
466 * are used only when ANSI doesn't have the key). The result is useful
467 * if the key doesn't produce ASCII character with active keyboard layout
468 * nor with alternative ASCII capable keyboard layout.
471 GetFallbackKeyCodeOfPunctuationKey(CodeNameIndex aCodeNameIndex
);
473 bool IsModifierKeyEvent() const
475 return GetModifierForKeyName(mKeyNameIndex
) != MODIFIER_NONE
;
479 * Get the candidates for shortcut key.
481 * @param aCandidates [out] the candidate shortcut key combination list.
482 * the first item is most preferred.
484 void GetShortcutKeyCandidates(ShortcutKeyCandidateArray
& aCandidates
) const;
487 * Get the candidates for access key.
489 * @param aCandidates [out] the candidate access key list.
490 * the first item is most preferred.
492 void GetAccessKeyCandidates(nsTArray
<uint32_t>& aCandidates
) const;
495 * Check whether the modifiers match with chrome access key or
496 * content access key.
498 bool ModifiersMatchWithAccessKey(AccessKeyType aType
) const;
501 * Return active modifiers which may match with access key.
502 * For example, even if Alt is access key modifier, then, when Control,
503 * CapseLock and NumLock are active, this returns only MODIFIER_CONTROL.
505 Modifiers
ModifiersForAccessKeyMatching() const;
508 * Return access key modifiers.
510 static Modifiers
AccessKeyModifiers(AccessKeyType aType
);
512 static void Shutdown();
515 * ComputeLocationFromCodeValue() returns one of .mLocation value
516 * (eKeyLocation*) which is the most preferred value for the specified code
519 static uint32_t ComputeLocationFromCodeValue(CodeNameIndex aCodeNameIndex
);
522 * ComputeKeyCodeFromKeyNameIndex() return a .mKeyCode value which can be
523 * mapped from the specified key value. Note that this returns 0 if the
524 * key name index is KEY_NAME_INDEX_Unidentified or KEY_NAME_INDEX_USE_STRING.
525 * This means that this method is useful only for non-printable keys.
527 static uint32_t ComputeKeyCodeFromKeyNameIndex(KeyNameIndex aKeyNameIndex
);
530 * GetModifierForKeyName() returns a value of Modifier which is activated
531 * by the aKeyNameIndex.
533 static Modifier
GetModifierForKeyName(KeyNameIndex aKeyNameIndex
);
536 * IsLockableModifier() returns true if aKeyNameIndex is a lockable modifier
537 * key such as CapsLock and NumLock.
539 static bool IsLockableModifier(KeyNameIndex aKeyNameIndex
);
541 static void GetDOMKeyName(KeyNameIndex aKeyNameIndex
,
542 nsAString
& aKeyName
);
543 static void GetDOMCodeName(CodeNameIndex aCodeNameIndex
,
544 nsAString
& aCodeName
);
546 static KeyNameIndex
GetKeyNameIndex(const nsAString
& aKeyValue
);
547 static CodeNameIndex
GetCodeNameIndex(const nsAString
& aCodeValue
);
549 static const char* GetCommandStr(Command aCommand
);
551 void AssignKeyEventData(const WidgetKeyboardEvent
& aEvent
, bool aCopyTargets
)
553 AssignInputEventData(aEvent
, aCopyTargets
);
555 mKeyCode
= aEvent
.mKeyCode
;
556 mCharCode
= aEvent
.mCharCode
;
557 mPseudoCharCode
= aEvent
.mPseudoCharCode
;
558 mLocation
= aEvent
.mLocation
;
559 mAlternativeCharCodes
= aEvent
.mAlternativeCharCodes
;
560 mIsRepeat
= aEvent
.mIsRepeat
;
561 mIsComposing
= aEvent
.mIsComposing
;
562 mKeyNameIndex
= aEvent
.mKeyNameIndex
;
563 mCodeNameIndex
= aEvent
.mCodeNameIndex
;
564 mKeyValue
= aEvent
.mKeyValue
;
565 mCodeValue
= aEvent
.mCodeValue
;
566 // Don't copy mNativeKeyEvent because it may be referred after its instance
568 mNativeKeyEvent
= nullptr;
569 mUniqueId
= aEvent
.mUniqueId
;
571 mNativeKeyCode
= aEvent
.mNativeKeyCode
;
572 mNativeModifierFlags
= aEvent
.mNativeModifierFlags
;
573 mNativeCharacters
.Assign(aEvent
.mNativeCharacters
);
574 mNativeCharactersIgnoringModifiers
.
575 Assign(aEvent
.mNativeCharactersIgnoringModifiers
);
576 mPluginTextEventString
.Assign(aEvent
.mPluginTextEventString
);
578 mIsSynthesizedByTIP
= aEvent
.mIsSynthesizedByTIP
;
580 // Don't copy mEditCommandsFor*Editor because it may require a lot of
581 // memory space. For example, if the event is dispatched but grabbed by
582 // a JS variable, they are not necessary anymore.
584 mEditCommandsForSingleLineEditorInitialized
=
585 aEvent
.mEditCommandsForSingleLineEditorInitialized
;
586 mEditCommandsForMultiLineEditorInitialized
=
587 aEvent
.mEditCommandsForMultiLineEditorInitialized
;
588 mEditCommandsForRichTextEditorInitialized
=
589 aEvent
.mEditCommandsForRichTextEditorInitialized
;
593 static const char16_t
* const kKeyNames
[];
594 static const char16_t
* const kCodeNames
[];
595 typedef nsDataHashtable
<nsStringHashKey
,
596 KeyNameIndex
> KeyNameIndexHashtable
;
597 typedef nsDataHashtable
<nsStringHashKey
,
598 CodeNameIndex
> CodeNameIndexHashtable
;
599 static KeyNameIndexHashtable
* sKeyNameIndexHashtable
;
600 static CodeNameIndexHashtable
* sCodeNameIndexHashtable
;
602 // mEditCommandsFor*Editor store edit commands. This should be initialized
603 // with InitEditCommandsFor().
604 // XXX Ideally, this should be array of Command rather than CommandInt.
605 // However, ParamTraits isn't aware of enum array.
606 nsTArray
<CommandInt
> mEditCommandsForSingleLineEditor
;
607 nsTArray
<CommandInt
> mEditCommandsForMultiLineEditor
;
608 nsTArray
<CommandInt
> mEditCommandsForRichTextEditor
;
610 nsTArray
<CommandInt
>& EditCommandsRef(nsIWidget::NativeKeyBindingsType aType
)
613 case nsIWidget::NativeKeyBindingsForSingleLineEditor
:
614 return mEditCommandsForSingleLineEditor
;
615 case nsIWidget::NativeKeyBindingsForMultiLineEditor
:
616 return mEditCommandsForMultiLineEditor
;
617 case nsIWidget::NativeKeyBindingsForRichTextEditor
:
618 return mEditCommandsForRichTextEditor
;
620 MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE(
621 "Invalid native key binding type");
625 // mEditCommandsFor*EditorInitialized are set to true when
626 // InitEditCommandsFor() initializes edit commands for the type.
627 bool mEditCommandsForSingleLineEditorInitialized
;
628 bool mEditCommandsForMultiLineEditorInitialized
;
629 bool mEditCommandsForRichTextEditorInitialized
;
631 bool& IsEditCommandsInitializedRef(nsIWidget::NativeKeyBindingsType aType
)
634 case nsIWidget::NativeKeyBindingsForSingleLineEditor
:
635 return mEditCommandsForSingleLineEditorInitialized
;
636 case nsIWidget::NativeKeyBindingsForMultiLineEditor
:
637 return mEditCommandsForMultiLineEditorInitialized
;
638 case nsIWidget::NativeKeyBindingsForRichTextEditor
:
639 return mEditCommandsForRichTextEditorInitialized
;
641 MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE(
642 "Invalid native key binding type");
646 static int32_t GenericAccessModifierKeyPref();
647 static int32_t ChromeAccessModifierMaskPref();
648 static int32_t ContentAccessModifierMaskPref();
651 /******************************************************************************
652 * mozilla::WidgetCompositionEvent
653 ******************************************************************************/
655 class WidgetCompositionEvent
: public WidgetGUIEvent
658 friend class mozilla::dom::PBrowserParent
;
659 friend class mozilla::dom::PBrowserChild
;
661 WidgetCompositionEvent()
666 virtual WidgetCompositionEvent
* AsCompositionEvent() override
671 WidgetCompositionEvent(bool aIsTrusted
, EventMessage aMessage
,
673 : WidgetGUIEvent(aIsTrusted
, aMessage
, aWidget
, eCompositionEventClass
)
674 , mNativeIMEContext(aWidget
)
675 , mOriginalMessage(eVoidEvent
)
679 virtual WidgetEvent
* Duplicate() const override
681 MOZ_ASSERT(mClass
== eCompositionEventClass
,
682 "Duplicate() must be overridden by sub class");
683 // Not copying widget, it is a weak reference.
684 WidgetCompositionEvent
* result
=
685 new WidgetCompositionEvent(false, mMessage
, nullptr);
686 result
->AssignCompositionEventData(*this, true);
687 result
->mFlags
= mFlags
;
691 // The composition string or the commit string. If the instance is a
692 // compositionstart event, this is initialized with selected text by
693 // TextComposition automatically.
696 RefPtr
<TextRangeArray
> mRanges
;
698 // mNativeIMEContext stores the native IME context which causes the
699 // composition event.
700 widget::NativeIMEContext mNativeIMEContext
;
702 // If the instance is a clone of another event, mOriginalMessage stores
703 // the another event's mMessage.
704 EventMessage mOriginalMessage
;
706 void AssignCompositionEventData(const WidgetCompositionEvent
& aEvent
,
709 AssignGUIEventData(aEvent
, aCopyTargets
);
711 mData
= aEvent
.mData
;
712 mOriginalMessage
= aEvent
.mOriginalMessage
;
713 mRanges
= aEvent
.mRanges
;
715 // Currently, we don't need to copy the other members because they are
716 // for internal use only (not available from JS).
719 bool IsComposing() const
721 return mRanges
&& mRanges
->IsComposing();
724 uint32_t TargetClauseOffset() const
726 return mRanges
? mRanges
->TargetClauseOffset() : 0;
729 uint32_t TargetClauseLength() const
731 uint32_t length
= UINT32_MAX
;
733 length
= mRanges
->TargetClauseLength();
735 return length
== UINT32_MAX
? mData
.Length() : length
;
738 uint32_t RangeCount() const
740 return mRanges
? mRanges
->Length() : 0;
743 bool CausesDOMTextEvent() const
745 return mMessage
== eCompositionChange
||
746 mMessage
== eCompositionCommit
||
747 mMessage
== eCompositionCommitAsIs
;
750 bool CausesDOMCompositionEndEvent() const
752 return mMessage
== eCompositionEnd
||
753 mMessage
== eCompositionCommit
||
754 mMessage
== eCompositionCommitAsIs
;
757 bool IsFollowedByCompositionEnd() const
759 return IsFollowedByCompositionEnd(mOriginalMessage
);
762 static bool IsFollowedByCompositionEnd(EventMessage aEventMessage
)
764 return aEventMessage
== eCompositionCommit
||
765 aEventMessage
== eCompositionCommitAsIs
;
769 /******************************************************************************
770 * mozilla::WidgetQueryContentEvent
771 ******************************************************************************/
773 class WidgetQueryContentEvent
: public WidgetGUIEvent
776 friend class dom::PBrowserParent
;
777 friend class dom::PBrowserChild
;
779 WidgetQueryContentEvent()
781 , mUseNativeLineBreak(true)
782 , mWithFontRanges(false)
784 MOZ_CRASH("WidgetQueryContentEvent is created without proper arguments");
788 virtual WidgetQueryContentEvent
* AsQueryContentEvent() override
793 WidgetQueryContentEvent(bool aIsTrusted
, EventMessage aMessage
,
795 : WidgetGUIEvent(aIsTrusted
, aMessage
, aWidget
, eQueryContentEventClass
)
797 , mUseNativeLineBreak(true)
798 , mWithFontRanges(false)
802 WidgetQueryContentEvent(EventMessage aMessage
,
803 const WidgetQueryContentEvent
& aOtherEvent
)
804 : WidgetGUIEvent(aOtherEvent
.IsTrusted(), aMessage
,
805 const_cast<nsIWidget
*>(aOtherEvent
.mWidget
.get()),
806 eQueryContentEventClass
)
808 , mUseNativeLineBreak(aOtherEvent
.mUseNativeLineBreak
)
809 , mWithFontRanges(false)
813 virtual WidgetEvent
* Duplicate() const override
815 // This event isn't an internal event of any DOM event.
816 NS_ASSERTION(!IsAllowedToDispatchDOMEvent(),
817 "WidgetQueryContentEvent needs to support Duplicate()");
818 MOZ_CRASH("WidgetQueryContentEvent doesn't support Duplicate()");
823 bool mUseNativeLineBreak
;
824 bool mRelativeToInsertionPoint
;
827 : mUseNativeLineBreak(true)
828 , mRelativeToInsertionPoint(false)
832 explicit Options(const WidgetQueryContentEvent
& aEvent
)
833 : mUseNativeLineBreak(aEvent
.mUseNativeLineBreak
)
834 , mRelativeToInsertionPoint(aEvent
.mInput
.mRelativeToInsertionPoint
)
839 void Init(const Options
& aOptions
)
841 mUseNativeLineBreak
= aOptions
.mUseNativeLineBreak
;
842 mInput
.mRelativeToInsertionPoint
= aOptions
.mRelativeToInsertionPoint
;
843 MOZ_ASSERT(mInput
.IsValidEventMessage(mMessage
));
846 void InitForQueryTextContent(int64_t aOffset
, uint32_t aLength
,
847 const Options
& aOptions
= Options())
849 NS_ASSERTION(mMessage
== eQueryTextContent
,
850 "wrong initializer is called");
851 mInput
.mOffset
= aOffset
;
852 mInput
.mLength
= aLength
;
854 MOZ_ASSERT(mInput
.IsValidOffset());
857 void InitForQueryCaretRect(int64_t aOffset
,
858 const Options
& aOptions
= Options())
860 NS_ASSERTION(mMessage
== eQueryCaretRect
,
861 "wrong initializer is called");
862 mInput
.mOffset
= aOffset
;
864 MOZ_ASSERT(mInput
.IsValidOffset());
867 void InitForQueryTextRect(int64_t aOffset
, uint32_t aLength
,
868 const Options
& aOptions
= Options())
870 NS_ASSERTION(mMessage
== eQueryTextRect
,
871 "wrong initializer is called");
872 mInput
.mOffset
= aOffset
;
873 mInput
.mLength
= aLength
;
875 MOZ_ASSERT(mInput
.IsValidOffset());
878 void InitForQuerySelectedText(SelectionType aSelectionType
,
879 const Options
& aOptions
= Options())
881 MOZ_ASSERT(mMessage
== eQuerySelectedText
);
882 MOZ_ASSERT(aSelectionType
!= SelectionType::eNone
);
883 mInput
.mSelectionType
= aSelectionType
;
887 void InitForQueryDOMWidgetHittest(const mozilla::LayoutDeviceIntPoint
& aPoint
)
889 NS_ASSERTION(mMessage
== eQueryDOMWidgetHittest
,
890 "wrong initializer is called");
894 void InitForQueryTextRectArray(uint32_t aOffset
, uint32_t aLength
,
895 const Options
& aOptions
= Options())
897 NS_ASSERTION(mMessage
== eQueryTextRectArray
,
898 "wrong initializer is called");
899 mInput
.mOffset
= aOffset
;
900 mInput
.mLength
= aLength
;
904 void RequestFontRanges()
906 NS_ASSERTION(mMessage
== eQueryTextContent
,
907 "not querying text content");
908 mWithFontRanges
= true;
911 uint32_t GetSelectionStart(void) const
913 NS_ASSERTION(mMessage
== eQuerySelectedText
,
914 "not querying selection");
915 return mReply
.mOffset
+ (mReply
.mReversed
? mReply
.mString
.Length() : 0);
918 uint32_t GetSelectionEnd(void) const
920 NS_ASSERTION(mMessage
== eQuerySelectedText
,
921 "not querying selection");
922 return mReply
.mOffset
+ (mReply
.mReversed
? 0 : mReply
.mString
.Length());
925 mozilla::WritingMode
GetWritingMode(void) const
927 NS_ASSERTION(mMessage
== eQuerySelectedText
||
928 mMessage
== eQueryCaretRect
||
929 mMessage
== eQueryTextRect
,
930 "not querying selection or text rect");
931 return mReply
.mWritingMode
;
935 bool mUseNativeLineBreak
;
936 bool mWithFontRanges
;
939 uint32_t EndOffset() const
941 CheckedInt
<uint32_t> endOffset
=
942 CheckedInt
<uint32_t>(mOffset
) + mLength
;
943 return NS_WARN_IF(!endOffset
.isValid()) ? UINT32_MAX
: endOffset
.value();
948 SelectionType mSelectionType
;
949 // If mOffset is true, mOffset is relative to the start offset of
950 // composition if there is, otherwise, the start of the first selection
952 bool mRelativeToInsertionPoint
;
957 , mSelectionType(SelectionType::eNormal
)
958 , mRelativeToInsertionPoint(false)
962 bool IsValidOffset() const
964 return mRelativeToInsertionPoint
|| mOffset
>= 0;
966 bool IsValidEventMessage(EventMessage aEventMessage
) const
968 if (!mRelativeToInsertionPoint
) {
971 switch (aEventMessage
) {
972 case eQueryTextContent
:
973 case eQueryCaretRect
:
980 bool MakeOffsetAbsolute(uint32_t aInsertionPointOffset
)
982 if (NS_WARN_IF(!mRelativeToInsertionPoint
)) {
985 mRelativeToInsertionPoint
= false;
986 // If mOffset + aInsertionPointOffset becomes negative value,
987 // we should assume the absolute offset is 0.
988 if (mOffset
< 0 && -mOffset
> aInsertionPointOffset
) {
992 // Otherwise, we don't allow too large offset.
993 CheckedInt
<uint32_t> absOffset
= mOffset
+ aInsertionPointOffset
;
994 if (NS_WARN_IF(!absOffset
.isValid())) {
995 mOffset
= UINT32_MAX
;
998 mOffset
= absOffset
.value();
1005 void* mContentsRoot
;
1007 // mTentativeCaretOffset is used by only eQueryCharacterAtPoint.
1008 // This is the offset where caret would be if user clicked at the mRefPoint.
1009 uint32_t mTentativeCaretOffset
;
1011 // mRect is used by eQueryTextRect, eQueryCaretRect, eQueryCharacterAtPoint
1012 // and eQueryEditorRect. The coordinates is system coordinates relative to
1013 // the top level widget of mFocusedWidget. E.g., if a <xul:panel> which
1014 // is owned by a window has focused editor, the offset of mRect is relative
1015 // to the owner window, not the <xul:panel>.
1016 mozilla::LayoutDeviceIntRect mRect
;
1017 // The return widget has the caret. This is set at all query events.
1018 nsIWidget
* mFocusedWidget
;
1019 // mozilla::WritingMode value at the end (focus) of the selection
1020 mozilla::WritingMode mWritingMode
;
1021 // Used by eQuerySelectionAsTransferable
1022 nsCOMPtr
<nsITransferable
> mTransferable
;
1023 // Used by eQueryTextContent with font ranges requested
1024 AutoTArray
<mozilla::FontRange
, 1> mFontRanges
;
1025 // Used by eQueryTextRectArray
1026 nsTArray
<mozilla::LayoutDeviceIntRect
> mRectArray
;
1027 // true if selection is reversed (end < start)
1029 // true if the selection exists
1031 // true if DOM element under mouse belongs to widget
1035 : mContentsRoot(nullptr)
1036 , mOffset(NOT_FOUND
)
1037 , mTentativeCaretOffset(NOT_FOUND
)
1038 , mFocusedWidget(nullptr)
1040 , mHasSelection(false)
1041 , mWidgetIsHit(false)
1048 NOT_FOUND
= UINT32_MAX
1051 // values of mComputedScrollAction
1060 /******************************************************************************
1061 * mozilla::WidgetSelectionEvent
1062 ******************************************************************************/
1064 class WidgetSelectionEvent
: public WidgetGUIEvent
1067 friend class mozilla::dom::PBrowserParent
;
1068 friend class mozilla::dom::PBrowserChild
;
1070 WidgetSelectionEvent()
1074 , mExpandToClusterBoundary(true)
1076 , mUseNativeLineBreak(true)
1081 virtual WidgetSelectionEvent
* AsSelectionEvent() override
1086 WidgetSelectionEvent(bool aIsTrusted
, EventMessage aMessage
,
1088 : WidgetGUIEvent(aIsTrusted
, aMessage
, aWidget
, eSelectionEventClass
)
1092 , mExpandToClusterBoundary(true)
1094 , mUseNativeLineBreak(true)
1095 , mReason(nsISelectionListener::NO_REASON
)
1099 virtual WidgetEvent
* Duplicate() const override
1101 // This event isn't an internal event of any DOM event.
1102 NS_ASSERTION(!IsAllowedToDispatchDOMEvent(),
1103 "WidgetSelectionEvent needs to support Duplicate()");
1104 MOZ_CRASH("WidgetSelectionEvent doesn't support Duplicate()");
1108 // Start offset of selection
1110 // Length of selection
1112 // Selection "anchor" should be in front
1114 // Cluster-based or character-based
1115 bool mExpandToClusterBoundary
;
1116 // true if setting selection succeeded.
1118 // true if native line breaks are used for mOffset and mLength
1119 bool mUseNativeLineBreak
;
1120 // Fennec provides eSetSelection reason codes for downstream
1121 // use in AccessibleCaret visibility logic.
1125 /******************************************************************************
1126 * mozilla::InternalEditorInputEvent
1127 ******************************************************************************/
1129 class InternalEditorInputEvent
: public InternalUIEvent
1132 InternalEditorInputEvent()
1133 : mIsComposing(false)
1138 virtual InternalEditorInputEvent
* AsEditorInputEvent() override
1143 InternalEditorInputEvent(bool aIsTrusted
, EventMessage aMessage
,
1144 nsIWidget
* aWidget
= nullptr)
1145 : InternalUIEvent(aIsTrusted
, aMessage
, aWidget
, eEditorInputEventClass
)
1146 , mIsComposing(false)
1150 virtual WidgetEvent
* Duplicate() const override
1152 MOZ_ASSERT(mClass
== eEditorInputEventClass
,
1153 "Duplicate() must be overridden by sub class");
1154 // Not copying widget, it is a weak reference.
1155 InternalEditorInputEvent
* result
=
1156 new InternalEditorInputEvent(false, mMessage
, nullptr);
1157 result
->AssignEditorInputEventData(*this, true);
1158 result
->mFlags
= mFlags
;
1164 void AssignEditorInputEventData(const InternalEditorInputEvent
& aEvent
,
1167 AssignUIEventData(aEvent
, aCopyTargets
);
1169 mIsComposing
= aEvent
.mIsComposing
;
1173 } // namespace mozilla
1175 #endif // mozilla_TextEvents_h__