Bug 1447216 [wpt PR 10104] - Worker: Support ES Modules on DedicatedWorker behind...
[gecko.git] / widget / IMEData.h
blob377d44805376fa443dc8761b4eac86e13c86bbaf
1 /* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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_widget_IMEData_h_
7 #define mozilla_widget_IMEData_h_
9 #include "nsPoint.h"
10 #include "nsRect.h"
11 #include "nsString.h"
12 #include "nsXULAppAPI.h"
13 #include "Units.h"
15 class nsIWidget;
17 namespace mozilla {
19 class WritingMode;
21 namespace widget {
23 /**
24 * Preference for receiving IME updates
26 * If mWantUpdates is not NOTIFY_NOTHING, nsTextStateManager will observe text
27 * change and/or selection change and call nsIWidget::NotifyIME() with
28 * NOTIFY_IME_OF_SELECTION_CHANGE and/or NOTIFY_IME_OF_TEXT_CHANGE.
29 * Please note that the text change observing cost is very expensive especially
30 * on an HTML editor has focus.
31 * If the IME implementation on a particular platform doesn't care about
32 * NOTIFY_IME_OF_SELECTION_CHANGE and/or NOTIFY_IME_OF_TEXT_CHANGE,
33 * they should set mWantUpdates to NOTIFY_NOTHING to avoid the cost.
34 * If the IME implementation needs notifications even while our process is
35 * deactive, it should also set NOTIFY_DURING_DEACTIVE.
37 struct IMENotificationRequests final
39 typedef uint8_t Notifications;
41 enum : Notifications
43 NOTIFY_NOTHING = 0,
44 NOTIFY_TEXT_CHANGE = 1 << 1,
45 NOTIFY_POSITION_CHANGE = 1 << 2,
46 // NOTIFY_MOUSE_BUTTON_EVENT_ON_CHAR is used when mouse button is pressed
47 // or released on a character in the focused editor. The notification is
48 // notified to IME as a mouse event. If it's consumed by IME, NotifyIME()
49 // returns NS_SUCCESS_EVENT_CONSUMED. Otherwise, it returns NS_OK if it's
50 // handled without any error.
51 NOTIFY_MOUSE_BUTTON_EVENT_ON_CHAR = 1 << 3,
52 // NOTE: NOTIFY_DURING_DEACTIVE isn't supported in environments where two
53 // or more compositions are possible. E.g., Mac and Linux (GTK).
54 NOTIFY_DURING_DEACTIVE = 1 << 7,
56 NOTIFY_ALL = NOTIFY_TEXT_CHANGE |
57 NOTIFY_POSITION_CHANGE |
58 NOTIFY_MOUSE_BUTTON_EVENT_ON_CHAR,
61 IMENotificationRequests()
62 : mWantUpdates(NOTIFY_NOTHING)
66 explicit IMENotificationRequests(Notifications aWantUpdates)
67 : mWantUpdates(aWantUpdates)
71 IMENotificationRequests operator|(const IMENotificationRequests& aOther) const
73 return IMENotificationRequests(aOther.mWantUpdates | mWantUpdates);
75 IMENotificationRequests& operator|=(const IMENotificationRequests& aOther)
77 mWantUpdates |= aOther.mWantUpdates;
78 return *this;
80 bool operator==(const IMENotificationRequests& aOther) const
82 return mWantUpdates == aOther.mWantUpdates;
85 bool WantTextChange() const
87 return !!(mWantUpdates & NOTIFY_TEXT_CHANGE);
90 bool WantPositionChanged() const
92 return !!(mWantUpdates & NOTIFY_POSITION_CHANGE);
95 bool WantChanges() const
97 return WantTextChange();
100 bool WantMouseButtonEventOnChar() const
102 return !!(mWantUpdates & NOTIFY_MOUSE_BUTTON_EVENT_ON_CHAR);
105 bool WantDuringDeactive() const
107 return !!(mWantUpdates & NOTIFY_DURING_DEACTIVE);
110 Notifications mWantUpdates;
114 * Contains IMEStatus plus information about the current
115 * input context that the IME can use as hints if desired.
118 struct IMEState final
121 * IME enabled states, the mEnabled value of
122 * SetInputContext()/GetInputContext() should be one value of following
123 * values.
125 * WARNING: If you change these values, you also need to edit:
126 * nsIDOMWindowUtils.idl
127 * nsContentUtils::GetWidgetStatusFromIMEStatus
129 enum Enabled
132 * 'Disabled' means the user cannot use IME. So, the IME open state should
133 * be 'closed' during 'disabled'.
135 DISABLED,
137 * 'Enabled' means the user can use IME.
139 ENABLED,
141 * 'Password' state is a special case for the password editors.
142 * E.g., on mac, the password editors should disable the non-Roman
143 * keyboard layouts at getting focus. Thus, the password editor may have
144 * special rules on some platforms.
146 PASSWORD,
148 * This state is used when a plugin is focused.
149 * When a plug-in is focused content, we should send native events
150 * directly. Because we don't process some native events, but they may
151 * be needed by the plug-in.
153 PLUGIN,
155 * 'Unknown' is useful when you cache this enum. So, this shouldn't be
156 * used with nsIWidget::SetInputContext().
158 UNKNOWN
160 Enabled mEnabled;
163 * IME open states the mOpen value of SetInputContext() should be one value of
164 * OPEN, CLOSE or DONT_CHANGE_OPEN_STATE. GetInputContext() should return
165 * OPEN, CLOSE or OPEN_STATE_NOT_SUPPORTED.
167 enum Open
170 * 'Unsupported' means the platform cannot return actual IME open state.
171 * This value is used only by GetInputContext().
173 OPEN_STATE_NOT_SUPPORTED,
175 * 'Don't change' means the widget shouldn't change IME open state when
176 * SetInputContext() is called.
178 DONT_CHANGE_OPEN_STATE = OPEN_STATE_NOT_SUPPORTED,
180 * 'Open' means that IME should compose in its primary language (or latest
181 * input mode except direct ASCII character input mode). Even if IME is
182 * opened by this value, users should be able to close IME by theirselves.
183 * Web contents can specify this value by |ime-mode: active;|.
185 OPEN,
187 * 'Closed' means that IME shouldn't handle key events (or should handle
188 * as ASCII character inputs on mobile device). Even if IME is closed by
189 * this value, users should be able to open IME by theirselves.
190 * Web contents can specify this value by |ime-mode: inactive;|.
192 CLOSED
194 Open mOpen;
196 IMEState()
197 : mEnabled(ENABLED)
198 , mOpen(DONT_CHANGE_OPEN_STATE)
202 explicit IMEState(Enabled aEnabled, Open aOpen = DONT_CHANGE_OPEN_STATE)
203 : mEnabled(aEnabled)
204 , mOpen(aOpen)
208 // Returns true if the user can input characters.
209 // This means that a plain text editor, an HTML editor, a password editor or
210 // a plain text editor whose ime-mode is "disabled".
211 bool IsEditable() const
213 return mEnabled == ENABLED || mEnabled == PASSWORD;
215 // Returns true if the user might be able to input characters.
216 // This means that a plain text editor, an HTML editor, a password editor,
217 // a plain text editor whose ime-mode is "disabled" or a windowless plugin
218 // has focus.
219 bool MaybeEditable() const
221 return IsEditable() || mEnabled == PLUGIN;
225 // NS_ONLY_ONE_NATIVE_IME_CONTEXT is a special value of native IME context.
226 // If there can be only one IME composition in a process, this can be used.
227 #define NS_ONLY_ONE_NATIVE_IME_CONTEXT \
228 (reinterpret_cast<void*>(static_cast<intptr_t>(-1)))
230 struct NativeIMEContext final
232 // Pointer to native IME context. Typically this is the result of
233 // nsIWidget::GetNativeData(NS_RAW_NATIVE_IME_CONTEXT) in the parent process.
234 // See also NS_ONLY_ONE_NATIVE_IME_CONTEXT.
235 uintptr_t mRawNativeIMEContext;
236 // Process ID of the origin of mNativeIMEContext.
237 uint64_t mOriginProcessID;
239 NativeIMEContext()
241 Init(nullptr);
244 explicit NativeIMEContext(nsIWidget* aWidget)
246 Init(aWidget);
249 bool IsValid() const
251 return mRawNativeIMEContext &&
252 mOriginProcessID != static_cast<uintptr_t>(-1);
255 void Init(nsIWidget* aWidget);
256 void InitWithRawNativeIMEContext(const void* aRawNativeIMEContext)
258 InitWithRawNativeIMEContext(const_cast<void*>(aRawNativeIMEContext));
260 void InitWithRawNativeIMEContext(void* aRawNativeIMEContext);
262 bool operator==(const NativeIMEContext& aOther) const
264 return mRawNativeIMEContext == aOther.mRawNativeIMEContext &&
265 mOriginProcessID == aOther.mOriginProcessID;
267 bool operator!=(const NativeIMEContext& aOther) const
269 return !(*this == aOther);
273 struct InputContext final
275 InputContext()
276 : mOrigin(XRE_IsParentProcess() ? ORIGIN_MAIN : ORIGIN_CONTENT)
277 , mMayBeIMEUnaware(false)
278 , mHasHandledUserInput(false)
279 , mInPrivateBrowsing(false)
283 // If InputContext instance is a static variable, any heap allocated stuff
284 // of its members need to be deleted at XPCOM shutdown. Otherwise, it's
285 // detected as memory leak.
286 void ShutDown()
288 // The buffer for nsString will be released with a call of SetCapacity(0).
289 // Truncate() isn't enough because it just sets length to 0.
290 mHTMLInputType.SetCapacity(0);
291 mHTMLInputInputmode.SetCapacity(0);
292 mActionHint.SetCapacity(0);
295 bool IsPasswordEditor() const
297 return mHTMLInputType.LowerCaseEqualsLiteral("password");
300 IMEState mIMEState;
302 /* The type of the input if the input is a html input field */
303 nsString mHTMLInputType;
305 /* The type of the inputmode */
306 nsString mHTMLInputInputmode;
308 /* A hint for the action that is performed when the input is submitted */
309 nsString mActionHint;
312 * mOrigin indicates whether this focus event refers to main or remote
313 * content.
315 enum Origin
317 // Adjusting focus of content on the main process
318 ORIGIN_MAIN,
319 // Adjusting focus of content in a remote process
320 ORIGIN_CONTENT
322 Origin mOrigin;
324 /* True if the webapp may be unaware of IME events such as input event or
325 * composiion events. This enables a key-events-only mode on Android for
326 * compatibility with webapps relying on key listeners. */
327 bool mMayBeIMEUnaware;
330 * True if the document has ever received user input
332 bool mHasHandledUserInput;
334 /* Whether the owning document of the input element has been loaded
335 * in private browsing mode. */
336 bool mInPrivateBrowsing;
338 bool IsOriginMainProcess() const
340 return mOrigin == ORIGIN_MAIN;
343 bool IsOriginContentProcess() const
345 return mOrigin == ORIGIN_CONTENT;
348 bool IsOriginCurrentProcess() const
350 if (XRE_IsParentProcess()) {
351 return IsOriginMainProcess();
353 return IsOriginContentProcess();
357 // FYI: Implemented in nsBaseWidget.cpp
358 const char* ToChar(InputContext::Origin aOrigin);
360 struct InputContextAction final
363 * mCause indicates what action causes calling nsIWidget::SetInputContext().
364 * It must be one of following values.
366 enum Cause
368 // The cause is unknown but originated from content. Focus might have been
369 // changed by content script.
370 CAUSE_UNKNOWN,
371 // The cause is unknown but originated from chrome. Focus might have been
372 // changed by chrome script.
373 CAUSE_UNKNOWN_CHROME,
374 // The cause is user's keyboard operation.
375 CAUSE_KEY,
376 // The cause is user's mouse operation.
377 CAUSE_MOUSE,
378 // The cause is user's touch operation (implies mouse)
379 CAUSE_TOUCH,
380 // The cause is unknown but it occurs during user input except keyboard
381 // input. E.g., an event handler of a user input event moves focus.
382 CAUSE_UNKNOWN_DURING_NON_KEYBOARD_INPUT,
383 // The cause is unknown but it occurs during keyboard input.
384 CAUSE_UNKNOWN_DURING_KEYBOARD_INPUT,
386 Cause mCause;
389 * mFocusChange indicates what happened for focus.
391 enum FocusChange
393 FOCUS_NOT_CHANGED,
394 // A content got focus.
395 GOT_FOCUS,
396 // Focused content lost focus.
397 LOST_FOCUS,
398 // Menu got pseudo focus that means focused content isn't changed but
399 // keyboard events will be handled by menu.
400 MENU_GOT_PSEUDO_FOCUS,
401 // Menu lost pseudo focus that means focused content will handle keyboard
402 // events.
403 MENU_LOST_PSEUDO_FOCUS,
404 // The widget is created. When a widget is crated, it may need to notify
405 // IME module to initialize its native IME context. In such case, this is
406 // used. I.e., this isn't used by IMEStateManager.
407 WIDGET_CREATED
409 FocusChange mFocusChange;
411 bool ContentGotFocusByTrustedCause() const
413 return (mFocusChange == GOT_FOCUS &&
414 mCause != CAUSE_UNKNOWN);
417 bool UserMightRequestOpenVKB() const
419 // If focus is changed, user must not request to open VKB.
420 if (mFocusChange != FOCUS_NOT_CHANGED) {
421 return false;
423 switch (mCause) {
424 // If user clicks or touches focused editor, user must request to open
425 // VKB.
426 case CAUSE_MOUSE:
427 case CAUSE_TOUCH:
428 // If script does something during a user input and that causes changing
429 // input context, user might request to open VKB. E.g., user clicks
430 // dummy editor and JS moves focus to an actual editable node. However,
431 // this should return false if the user input is a keyboard event since
432 // physical keyboard operation shouldn't cause opening VKB.
433 case CAUSE_UNKNOWN_DURING_NON_KEYBOARD_INPUT:
434 return true;
435 default:
436 return false;
441 * IsHandlingUserInput() returns true if it's caused by a user action directly
442 * or it's caused by script or something but it occurred while we're handling
443 * a user action. E.g., when it's caused by Element.focus() in an event
444 * handler of a user input, this returns true.
446 static bool IsHandlingUserInput(Cause aCause)
448 switch (aCause) {
449 case CAUSE_KEY:
450 case CAUSE_MOUSE:
451 case CAUSE_TOUCH:
452 case CAUSE_UNKNOWN_DURING_NON_KEYBOARD_INPUT:
453 case CAUSE_UNKNOWN_DURING_KEYBOARD_INPUT:
454 return true;
455 default:
456 return false;
460 bool IsHandlingUserInput() const {
461 return IsHandlingUserInput(mCause);
464 InputContextAction()
465 : mCause(CAUSE_UNKNOWN)
466 , mFocusChange(FOCUS_NOT_CHANGED)
470 explicit InputContextAction(Cause aCause,
471 FocusChange aFocusChange = FOCUS_NOT_CHANGED)
472 : mCause(aCause)
473 , mFocusChange(aFocusChange)
478 // IMEMessage is shared by IMEStateManager and TextComposition.
479 // Update values in GeckoEditable.java if you make changes here.
480 // XXX Negative values are used in Android...
481 typedef int8_t IMEMessageType;
482 enum IMEMessage : IMEMessageType
484 // This is used by IMENotification internally. This means that the instance
485 // hasn't been initialized yet.
486 NOTIFY_IME_OF_NOTHING,
487 // An editable content is getting focus
488 NOTIFY_IME_OF_FOCUS,
489 // An editable content is losing focus
490 NOTIFY_IME_OF_BLUR,
491 // Selection in the focused editable content is changed
492 NOTIFY_IME_OF_SELECTION_CHANGE,
493 // Text in the focused editable content is changed
494 NOTIFY_IME_OF_TEXT_CHANGE,
495 // Notified when a dispatched composition event is handled by the
496 // contents. This must be notified after the other notifications.
497 // Note that if a remote process has focus, this is notified only once when
498 // all dispatched events are handled completely. So, the receiver shouldn't
499 // count number of received this notification for comparing with the number
500 // of dispatched events.
501 // NOTE: If a composition event causes moving focus from the focused editor,
502 // this notification may not be notified as usual. Even in such case,
503 // NOTIFY_IME_OF_BLUR is always sent. So, notification listeners
504 // should tread the blur notification as including this if there is
505 // pending composition events.
506 NOTIFY_IME_OF_COMPOSITION_EVENT_HANDLED,
507 // Position or size of focused element may be changed.
508 NOTIFY_IME_OF_POSITION_CHANGE,
509 // Mouse button event is fired on a character in focused editor
510 NOTIFY_IME_OF_MOUSE_BUTTON_EVENT,
511 // Request to commit current composition to IME
512 // (some platforms may not support)
513 REQUEST_TO_COMMIT_COMPOSITION,
514 // Request to cancel current composition to IME
515 // (some platforms may not support)
516 REQUEST_TO_CANCEL_COMPOSITION
519 // FYI: Implemented in nsBaseWidget.cpp
520 const char* ToChar(IMEMessage aIMEMessage);
522 struct IMENotification final
524 IMENotification()
525 : mMessage(NOTIFY_IME_OF_NOTHING)
529 IMENotification(const IMENotification& aOther)
530 : mMessage(NOTIFY_IME_OF_NOTHING)
532 Assign(aOther);
535 ~IMENotification()
537 Clear();
540 MOZ_IMPLICIT IMENotification(IMEMessage aMessage)
541 : mMessage(aMessage)
543 switch (aMessage) {
544 case NOTIFY_IME_OF_SELECTION_CHANGE:
545 mSelectionChangeData.mString = new nsString();
546 mSelectionChangeData.Clear();
547 break;
548 case NOTIFY_IME_OF_TEXT_CHANGE:
549 mTextChangeData.Clear();
550 break;
551 case NOTIFY_IME_OF_MOUSE_BUTTON_EVENT:
552 mMouseButtonEventData.mEventMessage = eVoidEvent;
553 mMouseButtonEventData.mOffset = UINT32_MAX;
554 mMouseButtonEventData.mCursorPos.Set(nsIntPoint(0, 0));
555 mMouseButtonEventData.mCharRect.Set(nsIntRect(0, 0, 0, 0));
556 mMouseButtonEventData.mButton = -1;
557 mMouseButtonEventData.mButtons = 0;
558 mMouseButtonEventData.mModifiers = 0;
559 break;
560 default:
561 break;
565 void Assign(const IMENotification& aOther)
567 bool changingMessage = mMessage != aOther.mMessage;
568 if (changingMessage) {
569 Clear();
570 mMessage = aOther.mMessage;
572 switch (mMessage) {
573 case NOTIFY_IME_OF_SELECTION_CHANGE:
574 if (changingMessage) {
575 mSelectionChangeData.mString = new nsString();
577 mSelectionChangeData.Assign(aOther.mSelectionChangeData);
578 break;
579 case NOTIFY_IME_OF_TEXT_CHANGE:
580 mTextChangeData = aOther.mTextChangeData;
581 break;
582 case NOTIFY_IME_OF_MOUSE_BUTTON_EVENT:
583 mMouseButtonEventData = aOther.mMouseButtonEventData;
584 break;
585 default:
586 break;
590 IMENotification& operator=(const IMENotification& aOther)
592 Assign(aOther);
593 return *this;
596 void Clear()
598 if (mMessage == NOTIFY_IME_OF_SELECTION_CHANGE) {
599 MOZ_ASSERT(mSelectionChangeData.mString);
600 delete mSelectionChangeData.mString;
601 mSelectionChangeData.mString = nullptr;
603 mMessage = NOTIFY_IME_OF_NOTHING;
606 bool HasNotification() const
608 return mMessage != NOTIFY_IME_OF_NOTHING;
611 void MergeWith(const IMENotification& aNotification)
613 switch (mMessage) {
614 case NOTIFY_IME_OF_NOTHING:
615 MOZ_ASSERT(aNotification.mMessage != NOTIFY_IME_OF_NOTHING);
616 Assign(aNotification);
617 break;
618 case NOTIFY_IME_OF_SELECTION_CHANGE:
619 MOZ_ASSERT(aNotification.mMessage == NOTIFY_IME_OF_SELECTION_CHANGE);
620 mSelectionChangeData.Assign(aNotification.mSelectionChangeData);
621 break;
622 case NOTIFY_IME_OF_TEXT_CHANGE:
623 MOZ_ASSERT(aNotification.mMessage == NOTIFY_IME_OF_TEXT_CHANGE);
624 mTextChangeData += aNotification.mTextChangeData;
625 break;
626 case NOTIFY_IME_OF_POSITION_CHANGE:
627 case NOTIFY_IME_OF_COMPOSITION_EVENT_HANDLED:
628 MOZ_ASSERT(aNotification.mMessage == mMessage);
629 break;
630 default:
631 MOZ_CRASH("Merging notification isn't supported");
632 break;
636 IMEMessage mMessage;
638 struct Point
640 int32_t mX;
641 int32_t mY;
643 void Set(const nsIntPoint& aPoint)
645 mX = aPoint.x;
646 mY = aPoint.y;
648 nsIntPoint AsIntPoint() const
650 return nsIntPoint(mX, mY);
654 struct Rect
656 int32_t mX;
657 int32_t mY;
658 int32_t mWidth;
659 int32_t mHeight;
661 void Set(const nsIntRect& aRect)
663 aRect.GetRect(&mX, &mY, &mWidth, &mHeight);
665 nsIntRect AsIntRect() const
667 return nsIntRect(mX, mY, mWidth, mHeight);
671 // NOTIFY_IME_OF_SELECTION_CHANGE specific data
672 struct SelectionChangeDataBase
674 // Selection range.
675 uint32_t mOffset;
677 // Selected string
678 nsString* mString;
680 // Writing mode at the selection.
681 uint8_t mWritingMode;
683 bool mReversed;
684 bool mCausedByComposition;
685 bool mCausedBySelectionEvent;
686 bool mOccurredDuringComposition;
688 void SetWritingMode(const WritingMode& aWritingMode);
689 WritingMode GetWritingMode() const;
691 uint32_t StartOffset() const
693 return mOffset + (mReversed ? Length() : 0);
695 uint32_t EndOffset() const
697 return mOffset + (mReversed ? 0 : Length());
699 const nsString& String() const
701 return *mString;
703 uint32_t Length() const
705 return mString->Length();
707 bool IsInInt32Range() const
709 return mOffset + Length() <= INT32_MAX;
711 bool IsCollapsed() const
713 return mString->IsEmpty();
715 void ClearSelectionData()
717 mOffset = UINT32_MAX;
718 mString->Truncate();
719 mWritingMode = 0;
720 mReversed = false;
722 void Clear()
724 ClearSelectionData();
725 mCausedByComposition = false;
726 mCausedBySelectionEvent = false;
727 mOccurredDuringComposition = false;
729 bool IsValid() const
731 return mOffset != UINT32_MAX;
733 void Assign(const SelectionChangeDataBase& aOther)
735 mOffset = aOther.mOffset;
736 *mString = aOther.String();
737 mWritingMode = aOther.mWritingMode;
738 mReversed = aOther.mReversed;
739 AssignReason(aOther.mCausedByComposition,
740 aOther.mCausedBySelectionEvent,
741 aOther.mOccurredDuringComposition);
743 void AssignReason(bool aCausedByComposition,
744 bool aCausedBySelectionEvent,
745 bool aOccurredDuringComposition)
747 mCausedByComposition = aCausedByComposition;
748 mCausedBySelectionEvent = aCausedBySelectionEvent;
749 mOccurredDuringComposition = aOccurredDuringComposition;
753 // SelectionChangeDataBase cannot have constructors because it's used in
754 // the union. Therefore, SelectionChangeData should only implement
755 // constructors. In other words, add other members to
756 // SelectionChangeDataBase.
757 struct SelectionChangeData final : public SelectionChangeDataBase
759 SelectionChangeData()
761 mString = &mStringInstance;
762 Clear();
764 explicit SelectionChangeData(const SelectionChangeDataBase& aOther)
766 mString = &mStringInstance;
767 Assign(aOther);
769 SelectionChangeData(const SelectionChangeData& aOther)
771 mString = &mStringInstance;
772 Assign(aOther);
774 SelectionChangeData& operator=(const SelectionChangeDataBase& aOther)
776 mString = &mStringInstance;
777 Assign(aOther);
778 return *this;
780 SelectionChangeData& operator=(const SelectionChangeData& aOther)
782 mString = &mStringInstance;
783 Assign(aOther);
784 return *this;
787 private:
788 // When SelectionChangeData is used outside of union, it shouldn't create
789 // nsString instance in the heap as far as possible.
790 nsString mStringInstance;
793 struct TextChangeDataBase
795 // mStartOffset is the start offset of modified or removed text in
796 // original content and inserted text in new content.
797 uint32_t mStartOffset;
798 // mRemovalEndOffset is the end offset of modified or removed text in
799 // original content. If the value is same as mStartOffset, no text hasn't
800 // been removed yet.
801 uint32_t mRemovedEndOffset;
802 // mAddedEndOffset is the end offset of inserted text or same as
803 // mStartOffset if just removed. The vlaue is offset in the new content.
804 uint32_t mAddedEndOffset;
806 // Note that TextChangeDataBase may be the result of merging two or more
807 // changes especially in e10s mode.
809 // mCausedOnlyByComposition is true only when *all* merged changes are
810 // caused by composition.
811 bool mCausedOnlyByComposition;
812 // mIncludingChangesDuringComposition is true if at least one change which
813 // is not caused by composition occurred during the last composition.
814 // Note that if after the last composition is finished and there are some
815 // changes not caused by composition, this is set to false.
816 bool mIncludingChangesDuringComposition;
817 // mIncludingChangesWithoutComposition is true if there is at least one
818 // change which did occur when there wasn't a composition ongoing.
819 bool mIncludingChangesWithoutComposition;
821 uint32_t OldLength() const
823 MOZ_ASSERT(IsValid());
824 return mRemovedEndOffset - mStartOffset;
826 uint32_t NewLength() const
828 MOZ_ASSERT(IsValid());
829 return mAddedEndOffset - mStartOffset;
832 // Positive if text is added. Negative if text is removed.
833 int64_t Difference() const
835 return mAddedEndOffset - mRemovedEndOffset;
838 bool IsInInt32Range() const
840 MOZ_ASSERT(IsValid());
841 return mStartOffset <= INT32_MAX &&
842 mRemovedEndOffset <= INT32_MAX &&
843 mAddedEndOffset <= INT32_MAX;
846 bool IsValid() const
848 return !(mStartOffset == UINT32_MAX &&
849 !mRemovedEndOffset && !mAddedEndOffset);
852 void Clear()
854 mStartOffset = UINT32_MAX;
855 mRemovedEndOffset = mAddedEndOffset = 0;
858 void MergeWith(const TextChangeDataBase& aOther);
859 TextChangeDataBase& operator+=(const TextChangeDataBase& aOther)
861 MergeWith(aOther);
862 return *this;
865 #ifdef DEBUG
866 void Test();
867 #endif // #ifdef DEBUG
870 // TextChangeDataBase cannot have constructors because they are used in union.
871 // Therefore, TextChangeData should only implement constructor. In other
872 // words, add other members to TextChangeDataBase.
873 struct TextChangeData : public TextChangeDataBase
875 TextChangeData() { Clear(); }
877 TextChangeData(uint32_t aStartOffset,
878 uint32_t aRemovedEndOffset,
879 uint32_t aAddedEndOffset,
880 bool aCausedByComposition,
881 bool aOccurredDuringComposition)
883 MOZ_ASSERT(aRemovedEndOffset >= aStartOffset,
884 "removed end offset must not be smaller than start offset");
885 MOZ_ASSERT(aAddedEndOffset >= aStartOffset,
886 "added end offset must not be smaller than start offset");
887 mStartOffset = aStartOffset;
888 mRemovedEndOffset = aRemovedEndOffset;
889 mAddedEndOffset = aAddedEndOffset;
890 mCausedOnlyByComposition = aCausedByComposition;
891 mIncludingChangesDuringComposition =
892 !aCausedByComposition && aOccurredDuringComposition;
893 mIncludingChangesWithoutComposition =
894 !aCausedByComposition && !aOccurredDuringComposition;
898 struct MouseButtonEventData
900 // The value of WidgetEvent::mMessage
901 EventMessage mEventMessage;
902 // Character offset from the start of the focused editor under the cursor
903 uint32_t mOffset;
904 // Cursor position in pixels relative to the widget
905 Point mCursorPos;
906 // Character rect in pixels under the cursor relative to the widget
907 Rect mCharRect;
908 // The value of WidgetMouseEventBase::button and buttons
909 int16_t mButton;
910 int16_t mButtons;
911 // The value of WidgetInputEvent::modifiers
912 Modifiers mModifiers;
915 union
917 // NOTIFY_IME_OF_SELECTION_CHANGE specific data
918 SelectionChangeDataBase mSelectionChangeData;
920 // NOTIFY_IME_OF_TEXT_CHANGE specific data
921 TextChangeDataBase mTextChangeData;
923 // NOTIFY_IME_OF_MOUSE_BUTTON_EVENT specific data
924 MouseButtonEventData mMouseButtonEventData;
927 void SetData(const SelectionChangeDataBase& aSelectionChangeData)
929 MOZ_RELEASE_ASSERT(mMessage == NOTIFY_IME_OF_SELECTION_CHANGE);
930 mSelectionChangeData.Assign(aSelectionChangeData);
933 void SetData(const TextChangeDataBase& aTextChangeData)
935 MOZ_RELEASE_ASSERT(mMessage == NOTIFY_IME_OF_TEXT_CHANGE);
936 mTextChangeData = aTextChangeData;
940 struct CandidateWindowPosition
942 // Upper left corner of the candidate window if mExcludeRect is false.
943 // Otherwise, the position currently interested. E.g., caret position.
944 LayoutDeviceIntPoint mPoint;
945 // Rect which shouldn't be overlapped with the candidate window.
946 // This is valid only when mExcludeRect is true.
947 LayoutDeviceIntRect mRect;
948 // See explanation of mPoint and mRect.
949 bool mExcludeRect;
952 } // namespace widget
953 } // namespace mozilla
955 #endif // #ifndef mozilla_widget_IMEData_h_