Bumping gaia.json for 2 gaia revision(s) a=gaia-bump
[gecko.git] / dom / events / IMEContentObserver.h
blobf8dba04917f9f86f7252cf84aacd94fc2a870b4e
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 sw=2 et tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_IMEContentObserver_h_
8 #define mozilla_IMEContentObserver_h_
10 #include "mozilla/Attributes.h"
11 #include "nsCOMPtr.h"
12 #include "nsCycleCollectionParticipant.h"
13 #include "nsIDocShell.h" // XXX Why does only this need to be included here?
14 #include "nsIEditor.h"
15 #include "nsIEditorObserver.h"
16 #include "nsIReflowObserver.h"
17 #include "nsISelectionListener.h"
18 #include "nsIScrollObserver.h"
19 #include "nsIWidget.h" // for nsIMEUpdatePreference
20 #include "nsStubMutationObserver.h"
21 #include "nsWeakReference.h"
23 class nsIContent;
24 class nsINode;
25 class nsISelection;
26 class nsPresContext;
28 namespace mozilla {
30 class EventStateManager;
32 // IMEContentObserver notifies widget of any text and selection changes
33 // in the currently focused editor
34 class IMEContentObserver MOZ_FINAL : public nsISelectionListener
35 , public nsStubMutationObserver
36 , public nsIReflowObserver
37 , public nsIScrollObserver
38 , public nsSupportsWeakReference
39 , public nsIEditorObserver
41 friend class AsyncMergeableNotificationsFlusher;
43 public:
44 IMEContentObserver();
46 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
47 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(IMEContentObserver,
48 nsISelectionListener)
49 NS_DECL_NSIEDITOROBSERVER
50 NS_DECL_NSISELECTIONLISTENER
51 NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATAWILLCHANGE
52 NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
53 NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
54 NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
55 NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
56 NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTEWILLCHANGE
57 NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
58 NS_DECL_NSIREFLOWOBSERVER
60 // nsIScrollObserver
61 virtual void ScrollPositionChanged() MOZ_OVERRIDE;
63 bool OnMouseButtonEvent(nsPresContext* aPresContext,
64 WidgetMouseEvent* aMouseEvent);
66 void Init(nsIWidget* aWidget, nsPresContext* aPresContext,
67 nsIContent* aContent);
68 void Destroy();
69 /**
70 * IMEContentObserver is stored by EventStateManager during observing.
71 * DisconnectFromEventStateManager() is called when EventStateManager stops
72 * storing the instance.
74 void DisconnectFromEventStateManager();
75 bool IsManaging(nsPresContext* aPresContext, nsIContent* aContent);
76 bool IsEditorHandlingEventForComposition() const;
77 bool KeepAliveDuringDeactive() const
79 return mUpdatePreference.WantDuringDeactive();
81 nsIWidget* GetWidget() const { return mWidget; }
82 nsresult GetSelectionAndRoot(nsISelection** aSelection,
83 nsIContent** aRoot) const;
85 struct TextChangeData
87 // mStartOffset is the start offset of modified or removed text in
88 // original content and inserted text in new content.
89 uint32_t mStartOffset;
90 // mRemovalEndOffset is the end offset of modified or removed text in
91 // original content. If the value is same as mStartOffset, no text hasn't
92 // been removed yet.
93 uint32_t mRemovedEndOffset;
94 // mAddedEndOffset is the end offset of inserted text or same as
95 // mStartOffset if just removed. The vlaue is offset in the new content.
96 uint32_t mAddedEndOffset;
98 bool mCausedOnlyByComposition;
99 bool mStored;
101 TextChangeData()
102 : mStartOffset(0)
103 , mRemovedEndOffset(0)
104 , mAddedEndOffset(0)
105 , mCausedOnlyByComposition(false)
106 , mStored(false)
110 TextChangeData(uint32_t aStartOffset,
111 uint32_t aRemovedEndOffset,
112 uint32_t aAddedEndOffset,
113 bool aCausedByComposition)
114 : mStartOffset(aStartOffset)
115 , mRemovedEndOffset(aRemovedEndOffset)
116 , mAddedEndOffset(aAddedEndOffset)
117 , mCausedOnlyByComposition(aCausedByComposition)
118 , mStored(true)
120 MOZ_ASSERT(aRemovedEndOffset >= aStartOffset,
121 "removed end offset must not be smaller than start offset");
122 MOZ_ASSERT(aAddedEndOffset >= aStartOffset,
123 "added end offset must not be smaller than start offset");
125 // Positive if text is added. Negative if text is removed.
126 int64_t Difference() const
128 return mAddedEndOffset - mRemovedEndOffset;
132 private:
133 ~IMEContentObserver() {}
135 void MaybeNotifyIMEOfTextChange(const TextChangeData& aTextChangeData);
136 void MaybeNotifyIMEOfSelectionChange(bool aCausedByComposition);
137 void MaybeNotifyIMEOfPositionChange();
139 void NotifyContentAdded(nsINode* aContainer, int32_t aStart, int32_t aEnd);
140 void ObserveEditableNode();
142 * UnregisterObservers() unresiters all listeners and observers.
143 * @param aPostEvent When true, DOM event will be posted to the thread.
144 * Otherwise, dispatched when safe.
146 void UnregisterObservers(bool aPostEvent);
147 void StoreTextChangeData(const TextChangeData& aTextChangeData);
148 void FlushMergeableNotifications();
150 #ifdef DEBUG
151 void TestMergingTextChangeData();
152 #endif
154 nsCOMPtr<nsIWidget> mWidget;
155 nsCOMPtr<nsISelection> mSelection;
156 nsCOMPtr<nsIContent> mRootContent;
157 nsCOMPtr<nsINode> mEditableNode;
158 nsCOMPtr<nsIDocShell> mDocShell;
159 nsCOMPtr<nsIEditor> mEditor;
162 * FlatTextCache stores flat text length from start of the content to
163 * mNodeOffset of mContainerNode.
165 struct FlatTextCache
167 // mContainerNode and mNodeOffset represent a point in DOM tree. E.g.,
168 // if mContainerNode is a div element, mNodeOffset is index of its child.
169 nsCOMPtr<nsINode> mContainerNode;
170 int32_t mNodeOffset;
171 // Length of flat text generated from contents between the start of content
172 // and a child node whose index is mNodeOffset of mContainerNode.
173 uint32_t mFlatTextLength;
175 FlatTextCache()
176 : mNodeOffset(0)
177 , mFlatTextLength(0)
181 void Clear()
183 mContainerNode = nullptr;
184 mNodeOffset = 0;
185 mFlatTextLength = 0;
188 void Cache(nsINode* aContainer, int32_t aNodeOffset,
189 uint32_t aFlatTextLength)
191 MOZ_ASSERT(aContainer, "aContainer must not be null");
192 MOZ_ASSERT(
193 aNodeOffset <= static_cast<int32_t>(aContainer->GetChildCount()),
194 "aNodeOffset must be same as or less than the count of children");
195 mContainerNode = aContainer;
196 mNodeOffset = aNodeOffset;
197 mFlatTextLength = aFlatTextLength;
200 bool Match(nsINode* aContainer, int32_t aNodeOffset) const
202 return aContainer == mContainerNode && aNodeOffset == mNodeOffset;
205 // mEndOfAddedTextCache caches text length from the start of content to
206 // the end of the last added content only while an edit action is being
207 // handled by the editor and no other mutation (e.g., removing node)
208 // occur.
209 FlatTextCache mEndOfAddedTextCache;
210 // mStartOfRemovingTextRangeCache caches text length from the start of content
211 // to the start of the last removed content only while an edit action is being
212 // handled by the editor and no other mutation (e.g., adding node) occur.
213 FlatTextCache mStartOfRemovingTextRangeCache;
215 TextChangeData mTextChangeData;
217 EventStateManager* mESM;
219 nsIMEUpdatePreference mUpdatePreference;
220 uint32_t mPreAttrChangeLength;
221 int64_t mPreCharacterDataChangeLength;
223 bool mIsSelectionChangeEventPending;
224 bool mSelectionChangeCausedOnlyByComposition;
225 bool mIsPositionChangeEventPending;
226 bool mIsFlushingPendingNotifications;
229 } // namespace mozilla
231 #endif // mozilla_IMEContentObserver_h_