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/EventForwards.h" // for KeyNameIndex, temporarily
14 #include "mozilla/TextRange.h"
16 #include "nsIDOMKeyEvent.h"
17 #include "nsITransferable.h"
19 #include "nsStringGlue.h"
21 #include "WritingModes.h"
23 /******************************************************************************
24 * virtual keycode values
25 ******************************************************************************/
27 #define NS_DEFINE_VK(aDOMKeyName, aDOMKeyCode) NS_##aDOMKeyName = aDOMKeyCode
31 #include "mozilla/VirtualKeyCodeList.h"
36 #define kLatestSeqno UINT32_MAX
45 class PPluginInstanceChild
;
46 } // namespace plugins
48 /******************************************************************************
49 * mozilla::AlternativeCharCode
51 * This stores alternative charCode values of a key event with some modifiers.
52 * The stored values proper for testing shortcut key or access key.
53 ******************************************************************************/
55 struct AlternativeCharCode
57 AlternativeCharCode() :
58 mUnshiftedCharCode(0), mShiftedCharCode(0)
61 AlternativeCharCode(uint32_t aUnshiftedCharCode
, uint32_t aShiftedCharCode
) :
62 mUnshiftedCharCode(aUnshiftedCharCode
), mShiftedCharCode(aShiftedCharCode
)
65 uint32_t mUnshiftedCharCode
;
66 uint32_t mShiftedCharCode
;
69 /******************************************************************************
70 * mozilla::WidgetKeyboardEvent
71 ******************************************************************************/
73 class WidgetKeyboardEvent
: public WidgetInputEvent
76 friend class dom::PBrowserParent
;
77 friend class dom::PBrowserChild
;
85 virtual WidgetKeyboardEvent
* AsKeyboardEvent() MOZ_OVERRIDE
{ return this; }
87 WidgetKeyboardEvent(bool aIsTrusted
, uint32_t aMessage
, nsIWidget
* aWidget
,
88 EventClassID aEventClassID
= eKeyboardEventClass
)
89 : WidgetInputEvent(aIsTrusted
, aMessage
, aWidget
, aEventClassID
)
92 , location(nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD
)
96 , mKeyNameIndex(mozilla::KEY_NAME_INDEX_Unidentified
)
97 , mCodeNameIndex(CODE_NAME_INDEX_UNKNOWN
)
98 , mNativeKeyEvent(nullptr)
102 , mNativeModifierFlags(0)
107 virtual WidgetEvent
* Duplicate() const MOZ_OVERRIDE
109 MOZ_ASSERT(mClass
== eKeyboardEventClass
,
110 "Duplicate() must be overridden by sub class");
111 // Not copying widget, it is a weak reference.
112 WidgetKeyboardEvent
* result
=
113 new WidgetKeyboardEvent(false, message
, nullptr);
114 result
->AssignKeyEventData(*this, true);
115 result
->mFlags
= mFlags
;
119 // A DOM keyCode value or 0. If a keypress event whose charCode is 0, this
122 // If the instance is a keypress event of a printable key, this is a UTF-16
123 // value of the key. Otherwise, 0. This value must not be a control
124 // character when some modifiers are active. Then, this value should be an
125 // unmodified value except Shift and AltGr.
127 // One of nsIDOMKeyEvent::DOM_KEY_LOCATION_*
129 // OS translated Unicode chars which are used for accesskey and accelkey
130 // handling. The handlers will try from first character to last character.
131 nsTArray
<AlternativeCharCode
> alternativeCharCodes
;
132 // Indicates whether the event signifies a printable character
134 // Indicates whether the event is generated by auto repeat or not.
135 // if this is keyup event, always false.
137 // Indicates whether the event is generated during IME (or deadkey)
138 // composition. This is initialized by EventStateManager. So, key event
139 // dispatchers don't need to initialize this.
141 // DOM KeyboardEvent.key
142 KeyNameIndex mKeyNameIndex
;
143 // DOM KeyboardEvent.code
144 CodeNameIndex mCodeNameIndex
;
145 // DOM KeyboardEvent.key only when mKeyNameIndex is KEY_NAME_INDEX_USE_STRING.
147 // DOM KeyboardEvent.code only when mCodeNameIndex is
148 // CODE_NAME_INDEX_USE_STRING.
150 // OS-specific native event can optionally be preserved
151 void* mNativeKeyEvent
;
152 // Unique id associated with a keydown / keypress event. Used in identifing
153 // keypress events for removal from async event dispatch queue in metrofx
154 // after preventDefault is called on keydown events. It's ok if this wraps
155 // over long periods.
159 // Values given by a native NSEvent, for use with Cocoa NPAPI plugins.
160 uint16_t mNativeKeyCode
;
161 uint32_t mNativeModifierFlags
;
162 nsString mNativeCharacters
;
163 nsString mNativeCharactersIgnoringModifiers
;
164 // If this is non-empty, create a text event for plugins instead of a
166 nsString mPluginTextEventString
;
169 void GetDOMKeyName(nsAString
& aKeyName
)
171 if (mKeyNameIndex
== KEY_NAME_INDEX_USE_STRING
) {
172 aKeyName
= mKeyValue
;
175 GetDOMKeyName(mKeyNameIndex
, aKeyName
);
177 void GetDOMCodeName(nsAString
& aCodeName
)
179 if (mCodeNameIndex
== CODE_NAME_INDEX_USE_STRING
) {
180 aCodeName
= mCodeValue
;
183 GetDOMCodeName(mCodeNameIndex
, aCodeName
);
186 static void GetDOMKeyName(KeyNameIndex aKeyNameIndex
,
187 nsAString
& aKeyName
);
188 static void GetDOMCodeName(CodeNameIndex aCodeNameIndex
,
189 nsAString
& aCodeName
);
191 static const char* GetCommandStr(Command aCommand
);
193 void AssignKeyEventData(const WidgetKeyboardEvent
& aEvent
, bool aCopyTargets
)
195 AssignInputEventData(aEvent
, aCopyTargets
);
197 keyCode
= aEvent
.keyCode
;
198 charCode
= aEvent
.charCode
;
199 location
= aEvent
.location
;
200 alternativeCharCodes
= aEvent
.alternativeCharCodes
;
201 isChar
= aEvent
.isChar
;
202 mIsRepeat
= aEvent
.mIsRepeat
;
203 mIsComposing
= aEvent
.mIsComposing
;
204 mKeyNameIndex
= aEvent
.mKeyNameIndex
;
205 mCodeNameIndex
= aEvent
.mCodeNameIndex
;
206 mKeyValue
= aEvent
.mKeyValue
;
207 mCodeValue
= aEvent
.mCodeValue
;
208 // Don't copy mNativeKeyEvent because it may be referred after its instance
210 mNativeKeyEvent
= nullptr;
211 mUniqueId
= aEvent
.mUniqueId
;
213 mNativeKeyCode
= aEvent
.mNativeKeyCode
;
214 mNativeModifierFlags
= aEvent
.mNativeModifierFlags
;
215 mNativeCharacters
.Assign(aEvent
.mNativeCharacters
);
216 mNativeCharactersIgnoringModifiers
.
217 Assign(aEvent
.mNativeCharactersIgnoringModifiers
);
218 mPluginTextEventString
.Assign(aEvent
.mPluginTextEventString
);
224 /******************************************************************************
225 * mozilla::InternalBeforeAfterKeyboardEvent
227 * This is extended from WidgetKeyboardEvent and is mapped to DOM event
228 * "BeforeAfterKeyboardEvent".
230 * Event message: NS_KEY_BEFORE_DOWN
234 ******************************************************************************/
235 class InternalBeforeAfterKeyboardEvent
: public WidgetKeyboardEvent
238 friend class dom::PBrowserParent
;
239 friend class dom::PBrowserChild
;
241 InternalBeforeAfterKeyboardEvent()
246 // Extra member for InternalBeforeAfterKeyboardEvent. Indicates whether
247 // default actions of keydown/keyup event is prevented.
248 Nullable
<bool> mEmbeddedCancelled
;
250 virtual InternalBeforeAfterKeyboardEvent
* AsBeforeAfterKeyboardEvent() MOZ_OVERRIDE
255 InternalBeforeAfterKeyboardEvent(bool aIsTrusted
, uint32_t aMessage
,
257 : WidgetKeyboardEvent(aIsTrusted
, aMessage
, aWidget
, eBeforeAfterKeyboardEventClass
)
261 virtual WidgetEvent
* Duplicate() const MOZ_OVERRIDE
263 MOZ_ASSERT(mClass
== eBeforeAfterKeyboardEventClass
,
264 "Duplicate() must be overridden by sub class");
265 // Not copying widget, it is a weak reference.
266 InternalBeforeAfterKeyboardEvent
* result
=
267 new InternalBeforeAfterKeyboardEvent(false, message
, nullptr);
268 result
->AssignBeforeAfterKeyEventData(*this, true);
269 result
->mFlags
= mFlags
;
273 void AssignBeforeAfterKeyEventData(
274 const InternalBeforeAfterKeyboardEvent
& aEvent
,
277 AssignKeyEventData(aEvent
, aCopyTargets
);
278 mEmbeddedCancelled
= aEvent
.mEmbeddedCancelled
;
281 void AssignBeforeAfterKeyEventData(
282 const WidgetKeyboardEvent
& aEvent
,
285 AssignKeyEventData(aEvent
, aCopyTargets
);
289 /******************************************************************************
290 * mozilla::WidgetCompositionEvent
291 ******************************************************************************/
293 class WidgetCompositionEvent
: public WidgetGUIEvent
296 friend class mozilla::dom::PBrowserParent
;
297 friend class mozilla::dom::PBrowserChild
;
299 WidgetCompositionEvent()
300 : mSeqno(kLatestSeqno
)
308 virtual WidgetCompositionEvent
* AsCompositionEvent() MOZ_OVERRIDE
313 WidgetCompositionEvent(bool aIsTrusted
, uint32_t aMessage
,
315 : WidgetGUIEvent(aIsTrusted
, aMessage
, aWidget
, eCompositionEventClass
)
316 , mSeqno(kLatestSeqno
)
318 // XXX compositionstart is cancelable in draft of DOM3 Events.
319 // However, it doesn't make sense for us, we cannot cancel composition
320 // when we send compositionstart event.
321 mFlags
.mCancelable
= false;
324 virtual WidgetEvent
* Duplicate() const MOZ_OVERRIDE
326 MOZ_ASSERT(mClass
== eCompositionEventClass
,
327 "Duplicate() must be overridden by sub class");
328 // Not copying widget, it is a weak reference.
329 WidgetCompositionEvent
* result
=
330 new WidgetCompositionEvent(false, message
, nullptr);
331 result
->AssignCompositionEventData(*this, true);
332 result
->mFlags
= mFlags
;
336 // The composition string or the commit string. If the instance is a
337 // compositionstart event, this is initialized with selected text by
338 // TextComposition automatically.
341 nsRefPtr
<TextRangeArray
> mRanges
;
343 void AssignCompositionEventData(const WidgetCompositionEvent
& aEvent
,
346 AssignGUIEventData(aEvent
, aCopyTargets
);
348 mData
= aEvent
.mData
;
350 // Currently, we don't need to copy the other members because they are
351 // for internal use only (not available from JS).
354 bool IsComposing() const
356 return mRanges
&& mRanges
->IsComposing();
359 uint32_t TargetClauseOffset() const
361 return mRanges
? mRanges
->TargetClauseOffset() : 0;
364 uint32_t RangeCount() const
366 return mRanges
? mRanges
->Length() : 0;
369 bool CausesDOMTextEvent() const
371 return message
== NS_COMPOSITION_CHANGE
||
372 message
== NS_COMPOSITION_COMMIT
||
373 message
== NS_COMPOSITION_COMMIT_AS_IS
;
376 bool CausesDOMCompositionEndEvent() const
378 return message
== NS_COMPOSITION_END
||
379 message
== NS_COMPOSITION_COMMIT
||
380 message
== NS_COMPOSITION_COMMIT_AS_IS
;
384 /******************************************************************************
385 * mozilla::WidgetQueryContentEvent
386 ******************************************************************************/
388 class WidgetQueryContentEvent
: public WidgetGUIEvent
391 friend class dom::PBrowserParent
;
392 friend class dom::PBrowserChild
;
394 WidgetQueryContentEvent()
396 MOZ_CRASH("WidgetQueryContentEvent is created without proper arguments");
400 virtual WidgetQueryContentEvent
* AsQueryContentEvent() MOZ_OVERRIDE
405 WidgetQueryContentEvent(bool aIsTrusted
, uint32_t aMessage
,
407 : WidgetGUIEvent(aIsTrusted
, aMessage
, aWidget
, eQueryContentEventClass
)
410 , mUseNativeLineBreak(true)
414 virtual WidgetEvent
* Duplicate() const MOZ_OVERRIDE
416 // This event isn't an internal event of any DOM event.
417 NS_ASSERTION(!IsAllowedToDispatchDOMEvent(),
418 "WidgetQueryContentEvent needs to support Duplicate()");
419 MOZ_CRASH("WidgetQueryContentEvent doesn't support Duplicate()");
423 void InitForQueryTextContent(uint32_t aOffset
, uint32_t aLength
,
424 bool aUseNativeLineBreak
= true)
426 NS_ASSERTION(message
== NS_QUERY_TEXT_CONTENT
,
427 "wrong initializer is called");
428 mInput
.mOffset
= aOffset
;
429 mInput
.mLength
= aLength
;
430 mUseNativeLineBreak
= aUseNativeLineBreak
;
433 void InitForQueryCaretRect(uint32_t aOffset
,
434 bool aUseNativeLineBreak
= true)
436 NS_ASSERTION(message
== NS_QUERY_CARET_RECT
,
437 "wrong initializer is called");
438 mInput
.mOffset
= aOffset
;
439 mUseNativeLineBreak
= aUseNativeLineBreak
;
442 void InitForQueryTextRect(uint32_t aOffset
, uint32_t aLength
,
443 bool aUseNativeLineBreak
= true)
445 NS_ASSERTION(message
== NS_QUERY_TEXT_RECT
,
446 "wrong initializer is called");
447 mInput
.mOffset
= aOffset
;
448 mInput
.mLength
= aLength
;
449 mUseNativeLineBreak
= aUseNativeLineBreak
;
452 void InitForQueryDOMWidgetHittest(const mozilla::LayoutDeviceIntPoint
& aPoint
)
454 NS_ASSERTION(message
== NS_QUERY_DOM_WIDGET_HITTEST
,
455 "wrong initializer is called");
459 uint32_t GetSelectionStart(void) const
461 NS_ASSERTION(message
== NS_QUERY_SELECTED_TEXT
,
462 "not querying selection");
463 return mReply
.mOffset
+ (mReply
.mReversed
? mReply
.mString
.Length() : 0);
466 uint32_t GetSelectionEnd(void) const
468 NS_ASSERTION(message
== NS_QUERY_SELECTED_TEXT
,
469 "not querying selection");
470 return mReply
.mOffset
+ (mReply
.mReversed
? 0 : mReply
.mString
.Length());
473 mozilla::WritingMode
GetWritingMode(void) const
475 NS_ASSERTION(message
== NS_QUERY_SELECTED_TEXT
,
476 "not querying selection");
477 return mReply
.mWritingMode
;
482 bool mUseNativeLineBreak
;
493 // Finally, the coordinates is system coordinates.
495 // The return widget has the caret. This is set at all query events.
496 nsIWidget
* mFocusedWidget
;
497 // true if selection is reversed (end < start)
499 // true if the selection exists
501 // true if DOM element under mouse belongs to widget
503 // mozilla::WritingMode value at the end (focus) of the selection
504 mozilla::WritingMode mWritingMode
;
505 // used by NS_QUERY_SELECTION_AS_TRANSFERABLE
506 nsCOMPtr
<nsITransferable
> mTransferable
;
511 NOT_FOUND
= UINT32_MAX
514 // values of mComputedScrollAction
523 /******************************************************************************
524 * mozilla::WidgetSelectionEvent
525 ******************************************************************************/
527 class WidgetSelectionEvent
: public WidgetGUIEvent
530 friend class mozilla::dom::PBrowserParent
;
531 friend class mozilla::dom::PBrowserChild
;
533 WidgetSelectionEvent()
534 : mSeqno(kLatestSeqno
)
538 , mExpandToClusterBoundary(true)
547 virtual WidgetSelectionEvent
* AsSelectionEvent() MOZ_OVERRIDE
552 WidgetSelectionEvent(bool aIsTrusted
, uint32_t aMessage
, nsIWidget
* aWidget
)
553 : WidgetGUIEvent(aIsTrusted
, aMessage
, aWidget
, eSelectionEventClass
)
554 , mSeqno(kLatestSeqno
)
558 , mExpandToClusterBoundary(true)
560 , mUseNativeLineBreak(true)
564 virtual WidgetEvent
* Duplicate() const MOZ_OVERRIDE
566 // This event isn't an internal event of any DOM event.
567 NS_ASSERTION(!IsAllowedToDispatchDOMEvent(),
568 "WidgetSelectionEvent needs to support Duplicate()");
569 MOZ_CRASH("WidgetSelectionEvent doesn't support Duplicate()");
573 // Start offset of selection
575 // Length of selection
577 // Selection "anchor" should be in front
579 // Cluster-based or character-based
580 bool mExpandToClusterBoundary
;
581 // true if setting selection succeeded.
583 // true if native line breaks are used for mOffset and mLength
584 bool mUseNativeLineBreak
;
587 /******************************************************************************
588 * mozilla::InternalEditorInputEvent
589 ******************************************************************************/
591 class InternalEditorInputEvent
: public InternalUIEvent
594 InternalEditorInputEvent()
595 : mIsComposing(false)
600 virtual InternalEditorInputEvent
* AsEditorInputEvent() MOZ_OVERRIDE
605 InternalEditorInputEvent(bool aIsTrusted
, uint32_t aMessage
,
607 : InternalUIEvent(aIsTrusted
, aMessage
, aWidget
, eEditorInputEventClass
)
608 , mIsComposing(false)
611 mFlags
.mBubbles
= false;
612 mFlags
.mCancelable
= false;
616 mFlags
.mBubbles
= true;
617 mFlags
.mCancelable
= false;
620 virtual WidgetEvent
* Duplicate() const MOZ_OVERRIDE
622 MOZ_ASSERT(mClass
== eEditorInputEventClass
,
623 "Duplicate() must be overridden by sub class");
624 // Not copying widget, it is a weak reference.
625 InternalEditorInputEvent
* result
=
626 new InternalEditorInputEvent(false, message
, nullptr);
627 result
->AssignEditorInputEventData(*this, true);
628 result
->mFlags
= mFlags
;
634 void AssignEditorInputEventData(const InternalEditorInputEvent
& aEvent
,
637 AssignUIEventData(aEvent
, aCopyTargets
);
639 mIsComposing
= aEvent
.mIsComposing
;
643 } // namespace mozilla
645 #endif // mozilla_TextEvents_h__