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"
22 /******************************************************************************
23 * virtual keycode values
24 ******************************************************************************/
26 #define NS_DEFINE_VK(aDOMKeyName, aDOMKeyCode) NS_##aDOMKeyName = aDOMKeyCode
30 #include "mozilla/VirtualKeyCodeList.h"
35 #define kLatestSeqno UINT32_MAX
44 class PPluginInstanceChild
;
45 } // namespace plugins
47 /******************************************************************************
48 * mozilla::AlternativeCharCode
50 * This stores alternative charCode values of a key event with some modifiers.
51 * The stored values proper for testing shortcut key or access key.
52 ******************************************************************************/
54 struct AlternativeCharCode
56 AlternativeCharCode() :
57 mUnshiftedCharCode(0), mShiftedCharCode(0)
60 AlternativeCharCode(uint32_t aUnshiftedCharCode
, uint32_t aShiftedCharCode
) :
61 mUnshiftedCharCode(aUnshiftedCharCode
), mShiftedCharCode(aShiftedCharCode
)
64 uint32_t mUnshiftedCharCode
;
65 uint32_t mShiftedCharCode
;
68 /******************************************************************************
69 * mozilla::WidgetKeyboardEvent
70 ******************************************************************************/
72 class WidgetKeyboardEvent
: public WidgetInputEvent
75 friend class dom::PBrowserParent
;
76 friend class dom::PBrowserChild
;
83 virtual WidgetKeyboardEvent
* AsKeyboardEvent() MOZ_OVERRIDE
{ return this; }
85 WidgetKeyboardEvent(bool aIsTrusted
, uint32_t aMessage
, nsIWidget
* aWidget
)
86 : WidgetInputEvent(aIsTrusted
, aMessage
, aWidget
, eKeyboardEventClass
)
89 , location(nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD
)
93 , mKeyNameIndex(mozilla::KEY_NAME_INDEX_Unidentified
)
94 , mCodeNameIndex(CODE_NAME_INDEX_UNKNOWN
)
95 , mNativeKeyEvent(nullptr)
100 virtual WidgetEvent
* Duplicate() const MOZ_OVERRIDE
102 MOZ_ASSERT(mClass
== eKeyboardEventClass
,
103 "Duplicate() must be overridden by sub class");
104 // Not copying widget, it is a weak reference.
105 WidgetKeyboardEvent
* result
=
106 new WidgetKeyboardEvent(false, message
, nullptr);
107 result
->AssignKeyEventData(*this, true);
108 result
->mFlags
= mFlags
;
112 // A DOM keyCode value or 0. If a keypress event whose charCode is 0, this
115 // If the instance is a keypress event of a printable key, this is a UTF-16
116 // value of the key. Otherwise, 0. This value must not be a control
117 // character when some modifiers are active. Then, this value should be an
118 // unmodified value except Shift and AltGr.
120 // One of nsIDOMKeyEvent::DOM_KEY_LOCATION_*
122 // OS translated Unicode chars which are used for accesskey and accelkey
123 // handling. The handlers will try from first character to last character.
124 nsTArray
<AlternativeCharCode
> alternativeCharCodes
;
125 // Indicates whether the event signifies a printable character
127 // Indicates whether the event is generated by auto repeat or not.
128 // if this is keyup event, always false.
130 // Indicates whether the event is generated during IME (or deadkey)
131 // composition. This is initialized by EventStateManager. So, key event
132 // dispatchers don't need to initialize this.
134 // DOM KeyboardEvent.key
135 KeyNameIndex mKeyNameIndex
;
136 // DOM KeyboardEvent.code
137 CodeNameIndex mCodeNameIndex
;
138 // DOM KeyboardEvent.key only when mKeyNameIndex is KEY_NAME_INDEX_USE_STRING.
140 // DOM KeyboardEvent.code only when mCodeNameIndex is
141 // CODE_NAME_INDEX_USE_STRING.
143 // OS-specific native event can optionally be preserved
144 void* mNativeKeyEvent
;
145 // Unique id associated with a keydown / keypress event. Used in identifing
146 // keypress events for removal from async event dispatch queue in metrofx
147 // after preventDefault is called on keydown events. It's ok if this wraps
148 // over long periods.
151 void GetDOMKeyName(nsAString
& aKeyName
)
153 if (mKeyNameIndex
== KEY_NAME_INDEX_USE_STRING
) {
154 aKeyName
= mKeyValue
;
157 GetDOMKeyName(mKeyNameIndex
, aKeyName
);
159 void GetDOMCodeName(nsAString
& aCodeName
)
161 if (mCodeNameIndex
== CODE_NAME_INDEX_USE_STRING
) {
162 aCodeName
= mCodeValue
;
165 GetDOMCodeName(mCodeNameIndex
, aCodeName
);
168 static void GetDOMKeyName(KeyNameIndex aKeyNameIndex
,
169 nsAString
& aKeyName
);
170 static void GetDOMCodeName(CodeNameIndex aCodeNameIndex
,
171 nsAString
& aCodeName
);
173 static const char* GetCommandStr(Command aCommand
);
175 void AssignKeyEventData(const WidgetKeyboardEvent
& aEvent
, bool aCopyTargets
)
177 AssignInputEventData(aEvent
, aCopyTargets
);
179 keyCode
= aEvent
.keyCode
;
180 charCode
= aEvent
.charCode
;
181 location
= aEvent
.location
;
182 alternativeCharCodes
= aEvent
.alternativeCharCodes
;
183 isChar
= aEvent
.isChar
;
184 mIsRepeat
= aEvent
.mIsRepeat
;
185 mIsComposing
= aEvent
.mIsComposing
;
186 mKeyNameIndex
= aEvent
.mKeyNameIndex
;
187 mCodeNameIndex
= aEvent
.mCodeNameIndex
;
188 mKeyValue
= aEvent
.mKeyValue
;
189 mCodeValue
= aEvent
.mCodeValue
;
190 // Don't copy mNativeKeyEvent because it may be referred after its instance
192 mNativeKeyEvent
= nullptr;
193 mUniqueId
= aEvent
.mUniqueId
;
197 /******************************************************************************
198 * mozilla::WidgetTextEvent
200 * XXX WidgetTextEvent is fired with compositionupdate event almost every time.
201 * This wastes performance and the cost of mantaining each platform's
202 * implementation. Therefore, we should merge WidgetTextEvent and
203 * WidgetCompositionEvent. Then, DOM compositionupdate should be fired
204 * from TextComposition automatically.
205 ******************************************************************************/
207 class WidgetTextEvent
: public WidgetGUIEvent
210 friend class dom::PBrowserParent
;
211 friend class dom::PBrowserChild
;
212 friend class plugins::PPluginInstanceChild
;
215 : mSeqno(kLatestSeqno
)
224 virtual WidgetTextEvent
* AsTextEvent() MOZ_OVERRIDE
{ return this; }
226 WidgetTextEvent(bool aIsTrusted
, uint32_t aMessage
, nsIWidget
* aWidget
)
227 : WidgetGUIEvent(aIsTrusted
, aMessage
, aWidget
, eTextEventClass
)
228 , mSeqno(kLatestSeqno
)
233 virtual WidgetEvent
* Duplicate() const MOZ_OVERRIDE
235 MOZ_ASSERT(mClass
== eTextEventClass
,
236 "Duplicate() must be overridden by sub class");
237 // Not copying widget, it is a weak reference.
238 WidgetTextEvent
* result
= new WidgetTextEvent(false, message
, nullptr);
239 result
->AssignTextEventData(*this, true);
240 result
->mFlags
= mFlags
;
244 // The composition string or the commit string.
246 // Indicates whether the event signifies printable text.
247 // XXX This is not a standard, and most platforms don't set this properly.
248 // So, perhaps, we can get rid of this.
251 nsRefPtr
<TextRangeArray
> mRanges
;
253 void AssignTextEventData(const WidgetTextEvent
& aEvent
, bool aCopyTargets
)
255 AssignGUIEventData(aEvent
, aCopyTargets
);
257 isChar
= aEvent
.isChar
;
259 // Currently, we don't need to copy the other members because they are
260 // for internal use only (not available from JS).
263 bool IsComposing() const
265 return mRanges
&& mRanges
->IsComposing();
268 uint32_t TargetClauseOffset() const
270 return mRanges
? mRanges
->TargetClauseOffset() : 0;
273 uint32_t RangeCount() const
275 return mRanges
? mRanges
->Length() : 0;
279 /******************************************************************************
280 * mozilla::WidgetCompositionEvent
281 ******************************************************************************/
283 class WidgetCompositionEvent
: public WidgetGUIEvent
286 friend class mozilla::dom::PBrowserParent
;
287 friend class mozilla::dom::PBrowserChild
;
289 WidgetCompositionEvent()
290 : mSeqno(kLatestSeqno
)
298 virtual WidgetCompositionEvent
* AsCompositionEvent() MOZ_OVERRIDE
303 WidgetCompositionEvent(bool aIsTrusted
, uint32_t aMessage
,
305 : WidgetGUIEvent(aIsTrusted
, aMessage
, aWidget
, eCompositionEventClass
)
306 , mSeqno(kLatestSeqno
)
308 // XXX compositionstart is cancelable in draft of DOM3 Events.
309 // However, it doesn't make sense for us, we cannot cancel composition
310 // when we send compositionstart event.
311 mFlags
.mCancelable
= false;
314 virtual WidgetEvent
* Duplicate() const MOZ_OVERRIDE
316 MOZ_ASSERT(mClass
== eCompositionEventClass
,
317 "Duplicate() must be overridden by sub class");
318 // Not copying widget, it is a weak reference.
319 WidgetCompositionEvent
* result
=
320 new WidgetCompositionEvent(false, message
, nullptr);
321 result
->AssignCompositionEventData(*this, true);
322 result
->mFlags
= mFlags
;
326 // The composition string or the commit string. If the instance is a
327 // compositionstart event, this is initialized with selected text by
328 // TextComposition automatically.
331 void AssignCompositionEventData(const WidgetCompositionEvent
& aEvent
,
334 AssignGUIEventData(aEvent
, aCopyTargets
);
340 /******************************************************************************
341 * mozilla::WidgetQueryContentEvent
342 ******************************************************************************/
344 class WidgetQueryContentEvent
: public WidgetGUIEvent
347 friend class dom::PBrowserParent
;
348 friend class dom::PBrowserChild
;
350 WidgetQueryContentEvent()
352 MOZ_CRASH("WidgetQueryContentEvent is created without proper arguments");
356 virtual WidgetQueryContentEvent
* AsQueryContentEvent() MOZ_OVERRIDE
361 WidgetQueryContentEvent(bool aIsTrusted
, uint32_t aMessage
,
363 : WidgetGUIEvent(aIsTrusted
, aMessage
, aWidget
, eQueryContentEventClass
)
366 , mUseNativeLineBreak(true)
370 virtual WidgetEvent
* Duplicate() const MOZ_OVERRIDE
372 // This event isn't an internal event of any DOM event.
373 NS_ASSERTION(!IsAllowedToDispatchDOMEvent(),
374 "WidgetQueryContentEvent needs to support Duplicate()");
375 MOZ_CRASH("WidgetQueryContentEvent doesn't support Duplicate()");
379 void InitForQueryTextContent(uint32_t aOffset
, uint32_t aLength
,
380 bool aUseNativeLineBreak
= true)
382 NS_ASSERTION(message
== NS_QUERY_TEXT_CONTENT
,
383 "wrong initializer is called");
384 mInput
.mOffset
= aOffset
;
385 mInput
.mLength
= aLength
;
386 mUseNativeLineBreak
= aUseNativeLineBreak
;
389 void InitForQueryCaretRect(uint32_t aOffset
,
390 bool aUseNativeLineBreak
= true)
392 NS_ASSERTION(message
== NS_QUERY_CARET_RECT
,
393 "wrong initializer is called");
394 mInput
.mOffset
= aOffset
;
395 mUseNativeLineBreak
= aUseNativeLineBreak
;
398 void InitForQueryTextRect(uint32_t aOffset
, uint32_t aLength
,
399 bool aUseNativeLineBreak
= true)
401 NS_ASSERTION(message
== NS_QUERY_TEXT_RECT
,
402 "wrong initializer is called");
403 mInput
.mOffset
= aOffset
;
404 mInput
.mLength
= aLength
;
405 mUseNativeLineBreak
= aUseNativeLineBreak
;
408 void InitForQueryDOMWidgetHittest(const mozilla::LayoutDeviceIntPoint
& aPoint
)
410 NS_ASSERTION(message
== NS_QUERY_DOM_WIDGET_HITTEST
,
411 "wrong initializer is called");
415 uint32_t GetSelectionStart(void) const
417 NS_ASSERTION(message
== NS_QUERY_SELECTED_TEXT
,
418 "not querying selection");
419 return mReply
.mOffset
+ (mReply
.mReversed
? mReply
.mString
.Length() : 0);
422 uint32_t GetSelectionEnd(void) const
424 NS_ASSERTION(message
== NS_QUERY_SELECTED_TEXT
,
425 "not querying selection");
426 return mReply
.mOffset
+ (mReply
.mReversed
? 0 : mReply
.mString
.Length());
431 bool mUseNativeLineBreak
;
442 // Finally, the coordinates is system coordinates.
444 // The return widget has the caret. This is set at all query events.
445 nsIWidget
* mFocusedWidget
;
446 // true if selection is reversed (end < start)
448 // true if the selection exists
450 // true if DOM element under mouse belongs to widget
452 // used by NS_QUERY_SELECTION_AS_TRANSFERABLE
453 nsCOMPtr
<nsITransferable
> mTransferable
;
458 NOT_FOUND
= UINT32_MAX
461 // values of mComputedScrollAction
470 /******************************************************************************
471 * mozilla::WidgetSelectionEvent
472 ******************************************************************************/
474 class WidgetSelectionEvent
: public WidgetGUIEvent
477 friend class mozilla::dom::PBrowserParent
;
478 friend class mozilla::dom::PBrowserChild
;
480 WidgetSelectionEvent()
481 : mSeqno(kLatestSeqno
)
485 , mExpandToClusterBoundary(true)
494 virtual WidgetSelectionEvent
* AsSelectionEvent() MOZ_OVERRIDE
499 WidgetSelectionEvent(bool aIsTrusted
, uint32_t aMessage
, nsIWidget
* aWidget
)
500 : WidgetGUIEvent(aIsTrusted
, aMessage
, aWidget
, eSelectionEventClass
)
501 , mSeqno(kLatestSeqno
)
505 , mExpandToClusterBoundary(true)
507 , mUseNativeLineBreak(true)
511 virtual WidgetEvent
* Duplicate() const MOZ_OVERRIDE
513 // This event isn't an internal event of any DOM event.
514 NS_ASSERTION(!IsAllowedToDispatchDOMEvent(),
515 "WidgetSelectionEvent needs to support Duplicate()");
516 MOZ_CRASH("WidgetSelectionEvent doesn't support Duplicate()");
520 // Start offset of selection
522 // Length of selection
524 // Selection "anchor" should be in front
526 // Cluster-based or character-based
527 bool mExpandToClusterBoundary
;
528 // true if setting selection succeeded.
530 // true if native line breaks are used for mOffset and mLength
531 bool mUseNativeLineBreak
;
534 /******************************************************************************
535 * mozilla::InternalEditorInputEvent
536 ******************************************************************************/
538 class InternalEditorInputEvent
: public InternalUIEvent
541 InternalEditorInputEvent()
542 : mIsComposing(false)
547 virtual InternalEditorInputEvent
* AsEditorInputEvent() MOZ_OVERRIDE
552 InternalEditorInputEvent(bool aIsTrusted
, uint32_t aMessage
,
554 : InternalUIEvent(aIsTrusted
, aMessage
, aWidget
, eEditorInputEventClass
)
555 , mIsComposing(false)
558 mFlags
.mBubbles
= false;
559 mFlags
.mCancelable
= false;
563 mFlags
.mBubbles
= true;
564 mFlags
.mCancelable
= false;
567 virtual WidgetEvent
* Duplicate() const MOZ_OVERRIDE
569 MOZ_ASSERT(mClass
== eEditorInputEventClass
,
570 "Duplicate() must be overridden by sub class");
571 // Not copying widget, it is a weak reference.
572 InternalEditorInputEvent
* result
=
573 new InternalEditorInputEvent(false, message
, nullptr);
574 result
->AssignEditorInputEventData(*this, true);
575 result
->mFlags
= mFlags
;
581 void AssignEditorInputEventData(const InternalEditorInputEvent
& aEvent
,
584 AssignUIEventData(aEvent
, aCopyTargets
);
586 mIsComposing
= aEvent
.mIsComposing
;
590 } // namespace mozilla
592 #endif // mozilla_TextEvents_h__