Bumping manifests a=b2g-bump
[gecko.git] / widget / TextEvents.h
blobbfe0d5d4efe5c856bb5c0684887d74ac61ddba1f
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__
9 #include <stdint.h>
11 #include "mozilla/Assertions.h"
12 #include "mozilla/BasicEvents.h"
13 #include "mozilla/EventForwards.h" // for KeyNameIndex, temporarily
14 #include "mozilla/TextRange.h"
15 #include "nsCOMPtr.h"
16 #include "nsIDOMKeyEvent.h"
17 #include "nsITransferable.h"
18 #include "nsRect.h"
19 #include "nsStringGlue.h"
20 #include "nsTArray.h"
21 #include "WritingModes.h"
23 /******************************************************************************
24 * virtual keycode values
25 ******************************************************************************/
27 #define NS_DEFINE_VK(aDOMKeyName, aDOMKeyCode) NS_##aDOMKeyName = aDOMKeyCode
29 enum
31 #include "mozilla/VirtualKeyCodeList.h"
34 #undef NS_DEFINE_VK
36 #define kLatestSeqno UINT32_MAX
38 namespace mozilla {
40 namespace dom {
41 class PBrowserParent;
42 class PBrowserChild;
43 } // namespace dom
44 namespace plugins {
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
75 private:
76 friend class dom::PBrowserParent;
77 friend class dom::PBrowserChild;
79 protected:
80 WidgetKeyboardEvent()
84 public:
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)
90 , keyCode(0)
91 , charCode(0)
92 , location(nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD)
93 , isChar(false)
94 , mIsRepeat(false)
95 , mIsComposing(false)
96 , mKeyNameIndex(mozilla::KEY_NAME_INDEX_Unidentified)
97 , mCodeNameIndex(CODE_NAME_INDEX_UNKNOWN)
98 , mNativeKeyEvent(nullptr)
99 , mUniqueId(0)
100 #ifdef XP_MACOSX
101 , mNativeKeyCode(0)
102 , mNativeModifierFlags(0)
103 #endif
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;
116 return result;
119 // A DOM keyCode value or 0. If a keypress event whose charCode is 0, this
120 // should be 0.
121 uint32_t keyCode;
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.
126 uint32_t charCode;
127 // One of nsIDOMKeyEvent::DOM_KEY_LOCATION_*
128 uint32_t 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
133 bool isChar;
134 // Indicates whether the event is generated by auto repeat or not.
135 // if this is keyup event, always false.
136 bool mIsRepeat;
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.
140 bool mIsComposing;
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.
146 nsString mKeyValue;
147 // DOM KeyboardEvent.code only when mCodeNameIndex is
148 // CODE_NAME_INDEX_USE_STRING.
149 nsString mCodeValue;
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.
156 uint32_t mUniqueId;
158 #ifdef XP_MACOSX
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
165 // keyboard event.
166 nsString mPluginTextEventString;
167 #endif
169 void GetDOMKeyName(nsAString& aKeyName)
171 if (mKeyNameIndex == KEY_NAME_INDEX_USE_STRING) {
172 aKeyName = mKeyValue;
173 return;
175 GetDOMKeyName(mKeyNameIndex, aKeyName);
177 void GetDOMCodeName(nsAString& aCodeName)
179 if (mCodeNameIndex == CODE_NAME_INDEX_USE_STRING) {
180 aCodeName = mCodeValue;
181 return;
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
209 // is destroyed.
210 mNativeKeyEvent = nullptr;
211 mUniqueId = aEvent.mUniqueId;
212 #ifdef XP_MACOSX
213 mNativeKeyCode = aEvent.mNativeKeyCode;
214 mNativeModifierFlags = aEvent.mNativeModifierFlags;
215 mNativeCharacters.Assign(aEvent.mNativeCharacters);
216 mNativeCharactersIgnoringModifiers.
217 Assign(aEvent.mNativeCharactersIgnoringModifiers);
218 mPluginTextEventString.Assign(aEvent.mPluginTextEventString);
219 #endif
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
231 * NS_KEY_BEFORE_UP
232 * NS_KEY_AFTER_DOWN
233 * NS_KEY_AFTER_UP
234 ******************************************************************************/
235 class InternalBeforeAfterKeyboardEvent : public WidgetKeyboardEvent
237 private:
238 friend class dom::PBrowserParent;
239 friend class dom::PBrowserChild;
241 InternalBeforeAfterKeyboardEvent()
245 public:
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
252 return this;
255 InternalBeforeAfterKeyboardEvent(bool aIsTrusted, uint32_t aMessage,
256 nsIWidget* aWidget)
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;
270 return result;
273 void AssignBeforeAfterKeyEventData(
274 const InternalBeforeAfterKeyboardEvent& aEvent,
275 bool aCopyTargets)
277 AssignKeyEventData(aEvent, aCopyTargets);
278 mEmbeddedCancelled = aEvent.mEmbeddedCancelled;
281 void AssignBeforeAfterKeyEventData(
282 const WidgetKeyboardEvent& aEvent,
283 bool aCopyTargets)
285 AssignKeyEventData(aEvent, aCopyTargets);
289 /******************************************************************************
290 * mozilla::WidgetCompositionEvent
291 ******************************************************************************/
293 class WidgetCompositionEvent : public WidgetGUIEvent
295 private:
296 friend class mozilla::dom::PBrowserParent;
297 friend class mozilla::dom::PBrowserChild;
299 WidgetCompositionEvent()
300 : mSeqno(kLatestSeqno)
304 public:
305 uint32_t mSeqno;
307 public:
308 virtual WidgetCompositionEvent* AsCompositionEvent() MOZ_OVERRIDE
310 return this;
313 WidgetCompositionEvent(bool aIsTrusted, uint32_t aMessage,
314 nsIWidget* aWidget)
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;
333 return result;
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.
339 nsString mData;
341 nsRefPtr<TextRangeArray> mRanges;
343 void AssignCompositionEventData(const WidgetCompositionEvent& aEvent,
344 bool aCopyTargets)
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
390 private:
391 friend class dom::PBrowserParent;
392 friend class dom::PBrowserChild;
394 WidgetQueryContentEvent()
396 MOZ_CRASH("WidgetQueryContentEvent is created without proper arguments");
399 public:
400 virtual WidgetQueryContentEvent* AsQueryContentEvent() MOZ_OVERRIDE
402 return this;
405 WidgetQueryContentEvent(bool aIsTrusted, uint32_t aMessage,
406 nsIWidget* aWidget)
407 : WidgetGUIEvent(aIsTrusted, aMessage, aWidget, eQueryContentEventClass)
408 , mSucceeded(false)
409 , mWasAsync(false)
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()");
420 return nullptr;
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");
456 refPoint = aPoint;
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;
480 bool mSucceeded;
481 bool mWasAsync;
482 bool mUseNativeLineBreak;
483 struct
485 uint32_t mOffset;
486 uint32_t mLength;
487 } mInput;
488 struct
490 void* mContentsRoot;
491 uint32_t mOffset;
492 nsString mString;
493 // Finally, the coordinates is system coordinates.
494 nsIntRect mRect;
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)
498 bool mReversed;
499 // true if the selection exists
500 bool mHasSelection;
501 // true if DOM element under mouse belongs to widget
502 bool mWidgetIsHit;
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;
507 } mReply;
509 enum
511 NOT_FOUND = UINT32_MAX
514 // values of mComputedScrollAction
515 enum
517 SCROLL_ACTION_NONE,
518 SCROLL_ACTION_LINE,
519 SCROLL_ACTION_PAGE
523 /******************************************************************************
524 * mozilla::WidgetSelectionEvent
525 ******************************************************************************/
527 class WidgetSelectionEvent : public WidgetGUIEvent
529 private:
530 friend class mozilla::dom::PBrowserParent;
531 friend class mozilla::dom::PBrowserChild;
533 WidgetSelectionEvent()
534 : mSeqno(kLatestSeqno)
535 , mOffset(0)
536 , mLength(0)
537 , mReversed(false)
538 , mExpandToClusterBoundary(true)
539 , mSucceeded(false)
543 public:
544 uint32_t mSeqno;
546 public:
547 virtual WidgetSelectionEvent* AsSelectionEvent() MOZ_OVERRIDE
549 return this;
552 WidgetSelectionEvent(bool aIsTrusted, uint32_t aMessage, nsIWidget* aWidget)
553 : WidgetGUIEvent(aIsTrusted, aMessage, aWidget, eSelectionEventClass)
554 , mSeqno(kLatestSeqno)
555 , mOffset(0)
556 , mLength(0)
557 , mReversed(false)
558 , mExpandToClusterBoundary(true)
559 , mSucceeded(false)
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()");
570 return nullptr;
573 // Start offset of selection
574 uint32_t mOffset;
575 // Length of selection
576 uint32_t mLength;
577 // Selection "anchor" should be in front
578 bool mReversed;
579 // Cluster-based or character-based
580 bool mExpandToClusterBoundary;
581 // true if setting selection succeeded.
582 bool mSucceeded;
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
593 private:
594 InternalEditorInputEvent()
595 : mIsComposing(false)
599 public:
600 virtual InternalEditorInputEvent* AsEditorInputEvent() MOZ_OVERRIDE
602 return this;
605 InternalEditorInputEvent(bool aIsTrusted, uint32_t aMessage,
606 nsIWidget* aWidget)
607 : InternalUIEvent(aIsTrusted, aMessage, aWidget, eEditorInputEventClass)
608 , mIsComposing(false)
610 if (!aIsTrusted) {
611 mFlags.mBubbles = false;
612 mFlags.mCancelable = false;
613 return;
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;
629 return result;
632 bool mIsComposing;
634 void AssignEditorInputEventData(const InternalEditorInputEvent& aEvent,
635 bool aCopyTargets)
637 AssignUIEventData(aEvent, aCopyTargets);
639 mIsComposing = aEvent.mIsComposing;
643 } // namespace mozilla
645 #endif // mozilla_TextEvents_h__