Merge mozilla-beta to b2g34. a=merge
[gecko.git] / widget / TextEvents.h
blob3bf14367e873060b5a82dc38ffb0a5bf13088cf3
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"
22 /******************************************************************************
23 * virtual keycode values
24 ******************************************************************************/
26 #define NS_DEFINE_VK(aDOMKeyName, aDOMKeyCode) NS_##aDOMKeyName = aDOMKeyCode
28 enum
30 #include "mozilla/VirtualKeyCodeList.h"
33 #undef NS_DEFINE_VK
35 #define kLatestSeqno UINT32_MAX
37 namespace mozilla {
39 namespace dom {
40 class PBrowserParent;
41 class PBrowserChild;
42 } // namespace dom
43 namespace plugins {
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
74 private:
75 friend class dom::PBrowserParent;
76 friend class dom::PBrowserChild;
78 WidgetKeyboardEvent()
82 public:
83 virtual WidgetKeyboardEvent* AsKeyboardEvent() MOZ_OVERRIDE { return this; }
85 WidgetKeyboardEvent(bool aIsTrusted, uint32_t aMessage, nsIWidget* aWidget)
86 : WidgetInputEvent(aIsTrusted, aMessage, aWidget, eKeyboardEventClass)
87 , keyCode(0)
88 , charCode(0)
89 , location(nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD)
90 , isChar(false)
91 , mIsRepeat(false)
92 , mIsComposing(false)
93 , mKeyNameIndex(mozilla::KEY_NAME_INDEX_Unidentified)
94 , mCodeNameIndex(CODE_NAME_INDEX_UNKNOWN)
95 , mNativeKeyEvent(nullptr)
96 , mUniqueId(0)
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;
109 return result;
112 // A DOM keyCode value or 0. If a keypress event whose charCode is 0, this
113 // should be 0.
114 uint32_t keyCode;
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.
119 uint32_t charCode;
120 // One of nsIDOMKeyEvent::DOM_KEY_LOCATION_*
121 uint32_t 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
126 bool isChar;
127 // Indicates whether the event is generated by auto repeat or not.
128 // if this is keyup event, always false.
129 bool mIsRepeat;
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.
133 bool mIsComposing;
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.
139 nsString mKeyValue;
140 // DOM KeyboardEvent.code only when mCodeNameIndex is
141 // CODE_NAME_INDEX_USE_STRING.
142 nsString mCodeValue;
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.
149 uint32_t mUniqueId;
151 void GetDOMKeyName(nsAString& aKeyName)
153 if (mKeyNameIndex == KEY_NAME_INDEX_USE_STRING) {
154 aKeyName = mKeyValue;
155 return;
157 GetDOMKeyName(mKeyNameIndex, aKeyName);
159 void GetDOMCodeName(nsAString& aCodeName)
161 if (mCodeNameIndex == CODE_NAME_INDEX_USE_STRING) {
162 aCodeName = mCodeValue;
163 return;
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
191 // is destroyed.
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
209 private:
210 friend class dom::PBrowserParent;
211 friend class dom::PBrowserChild;
212 friend class plugins::PPluginInstanceChild;
214 WidgetTextEvent()
215 : mSeqno(kLatestSeqno)
216 , isChar(false)
220 public:
221 uint32_t mSeqno;
223 public:
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)
229 , isChar(false)
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;
241 return result;
244 // The composition string or the commit string.
245 nsString theText;
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.
249 bool isChar;
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
285 private:
286 friend class mozilla::dom::PBrowserParent;
287 friend class mozilla::dom::PBrowserChild;
289 WidgetCompositionEvent()
290 : mSeqno(kLatestSeqno)
294 public:
295 uint32_t mSeqno;
297 public:
298 virtual WidgetCompositionEvent* AsCompositionEvent() MOZ_OVERRIDE
300 return this;
303 WidgetCompositionEvent(bool aIsTrusted, uint32_t aMessage,
304 nsIWidget* aWidget)
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;
323 return result;
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.
329 nsString data;
331 void AssignCompositionEventData(const WidgetCompositionEvent& aEvent,
332 bool aCopyTargets)
334 AssignGUIEventData(aEvent, aCopyTargets);
336 data = aEvent.data;
340 /******************************************************************************
341 * mozilla::WidgetQueryContentEvent
342 ******************************************************************************/
344 class WidgetQueryContentEvent : public WidgetGUIEvent
346 private:
347 friend class dom::PBrowserParent;
348 friend class dom::PBrowserChild;
350 WidgetQueryContentEvent()
352 MOZ_CRASH("WidgetQueryContentEvent is created without proper arguments");
355 public:
356 virtual WidgetQueryContentEvent* AsQueryContentEvent() MOZ_OVERRIDE
358 return this;
361 WidgetQueryContentEvent(bool aIsTrusted, uint32_t aMessage,
362 nsIWidget* aWidget)
363 : WidgetGUIEvent(aIsTrusted, aMessage, aWidget, eQueryContentEventClass)
364 , mSucceeded(false)
365 , mWasAsync(false)
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()");
376 return nullptr;
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");
412 refPoint = aPoint;
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());
429 bool mSucceeded;
430 bool mWasAsync;
431 bool mUseNativeLineBreak;
432 struct
434 uint32_t mOffset;
435 uint32_t mLength;
436 } mInput;
437 struct
439 void* mContentsRoot;
440 uint32_t mOffset;
441 nsString mString;
442 // Finally, the coordinates is system coordinates.
443 nsIntRect mRect;
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)
447 bool mReversed;
448 // true if the selection exists
449 bool mHasSelection;
450 // true if DOM element under mouse belongs to widget
451 bool mWidgetIsHit;
452 // used by NS_QUERY_SELECTION_AS_TRANSFERABLE
453 nsCOMPtr<nsITransferable> mTransferable;
454 } mReply;
456 enum
458 NOT_FOUND = UINT32_MAX
461 // values of mComputedScrollAction
462 enum
464 SCROLL_ACTION_NONE,
465 SCROLL_ACTION_LINE,
466 SCROLL_ACTION_PAGE
470 /******************************************************************************
471 * mozilla::WidgetSelectionEvent
472 ******************************************************************************/
474 class WidgetSelectionEvent : public WidgetGUIEvent
476 private:
477 friend class mozilla::dom::PBrowserParent;
478 friend class mozilla::dom::PBrowserChild;
480 WidgetSelectionEvent()
481 : mSeqno(kLatestSeqno)
482 , mOffset(0)
483 , mLength(0)
484 , mReversed(false)
485 , mExpandToClusterBoundary(true)
486 , mSucceeded(false)
490 public:
491 uint32_t mSeqno;
493 public:
494 virtual WidgetSelectionEvent* AsSelectionEvent() MOZ_OVERRIDE
496 return this;
499 WidgetSelectionEvent(bool aIsTrusted, uint32_t aMessage, nsIWidget* aWidget)
500 : WidgetGUIEvent(aIsTrusted, aMessage, aWidget, eSelectionEventClass)
501 , mSeqno(kLatestSeqno)
502 , mOffset(0)
503 , mLength(0)
504 , mReversed(false)
505 , mExpandToClusterBoundary(true)
506 , mSucceeded(false)
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()");
517 return nullptr;
520 // Start offset of selection
521 uint32_t mOffset;
522 // Length of selection
523 uint32_t mLength;
524 // Selection "anchor" should be in front
525 bool mReversed;
526 // Cluster-based or character-based
527 bool mExpandToClusterBoundary;
528 // true if setting selection succeeded.
529 bool mSucceeded;
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
540 private:
541 InternalEditorInputEvent()
542 : mIsComposing(false)
546 public:
547 virtual InternalEditorInputEvent* AsEditorInputEvent() MOZ_OVERRIDE
549 return this;
552 InternalEditorInputEvent(bool aIsTrusted, uint32_t aMessage,
553 nsIWidget* aWidget)
554 : InternalUIEvent(aIsTrusted, aMessage, aWidget, eEditorInputEventClass)
555 , mIsComposing(false)
557 if (!aIsTrusted) {
558 mFlags.mBubbles = false;
559 mFlags.mCancelable = false;
560 return;
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;
576 return result;
579 bool mIsComposing;
581 void AssignEditorInputEventData(const InternalEditorInputEvent& aEvent,
582 bool aCopyTargets)
584 AssignUIEventData(aEvent, aCopyTargets);
586 mIsComposing = aEvent.mIsComposing;
590 } // namespace mozilla
592 #endif // mozilla_TextEvents_h__