/src/mozilla-central/dom/events/IMEContentObserver.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 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/. */ |
6 | | |
7 | | #ifndef mozilla_IMEContentObserver_h |
8 | | #define mozilla_IMEContentObserver_h |
9 | | |
10 | | #include "mozilla/Attributes.h" |
11 | | #include "mozilla/EditorBase.h" |
12 | | #include "mozilla/dom/Selection.h" |
13 | | #include "nsCOMPtr.h" |
14 | | #include "nsCycleCollectionParticipant.h" |
15 | | #include "nsIDocShell.h" // XXX Why does only this need to be included here? |
16 | | #include "nsIReflowObserver.h" |
17 | | #include "nsIScrollObserver.h" |
18 | | #include "nsIWidget.h" |
19 | | #include "nsStubDocumentObserver.h" |
20 | | #include "nsStubMutationObserver.h" |
21 | | #include "nsThreadUtils.h" |
22 | | #include "nsWeakReference.h" |
23 | | |
24 | | class nsIContent; |
25 | | class nsINode; |
26 | | class nsPresContext; |
27 | | |
28 | | namespace mozilla { |
29 | | |
30 | | class EventStateManager; |
31 | | class TextComposition; |
32 | | |
33 | | namespace dom { |
34 | | class Selection; |
35 | | } // namespace dom |
36 | | |
37 | | // IMEContentObserver notifies widget of any text and selection changes |
38 | | // in the currently focused editor |
39 | | class IMEContentObserver final : public nsStubMutationObserver |
40 | | , public nsIReflowObserver |
41 | | , public nsIScrollObserver |
42 | | , public nsSupportsWeakReference |
43 | | { |
44 | | public: |
45 | | typedef widget::IMENotification::SelectionChangeData SelectionChangeData; |
46 | | typedef widget::IMENotification::TextChangeData TextChangeData; |
47 | | typedef widget::IMENotification::TextChangeDataBase TextChangeDataBase; |
48 | | typedef widget::IMENotificationRequests IMENotificationRequests; |
49 | | typedef widget::IMEMessage IMEMessage; |
50 | | |
51 | | IMEContentObserver(); |
52 | | |
53 | | NS_DECL_CYCLE_COLLECTING_ISUPPORTS |
54 | | NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(IMEContentObserver, |
55 | | nsIReflowObserver) |
56 | | NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATAWILLCHANGE |
57 | | NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED |
58 | | NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED |
59 | | NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED |
60 | | NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED |
61 | | NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTEWILLCHANGE |
62 | | NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED |
63 | | NS_DECL_NSIREFLOWOBSERVER |
64 | | |
65 | | // nsIScrollObserver |
66 | | virtual void ScrollPositionChanged() override; |
67 | | |
68 | | /** |
69 | | * OnSelectionChange() is called when selection is changed in the editor. |
70 | | */ |
71 | | void OnSelectionChange(dom::Selection& aSelection); |
72 | | |
73 | | bool OnMouseButtonEvent(nsPresContext* aPresContext, |
74 | | WidgetMouseEvent* aMouseEvent); |
75 | | |
76 | | nsresult HandleQueryContentEvent(WidgetQueryContentEvent* aEvent); |
77 | | |
78 | | /** |
79 | | * Init() initializes the instance, i.e., retrieving necessary objects and |
80 | | * starts to observe something. |
81 | | * Be aware, callers of this method need to guarantee that the instance |
82 | | * won't be released during calling this. |
83 | | * |
84 | | * @param aWidget The widget which can access native IME. |
85 | | * @param aPresContext The PresContext which has aContent. |
86 | | * @param aContent An editable element or a plugin host element which |
87 | | * user may use IME in. |
88 | | * Or nullptr if this will observe design mode |
89 | | * document. |
90 | | * @param aEditorBase When aContent is an editable element or nullptr, |
91 | | * non-nullptr referring an editor instance which |
92 | | * manages aContent. |
93 | | * Otherwise, i.e., this will observe a plugin content, |
94 | | * should be nullptr. |
95 | | */ |
96 | | void Init(nsIWidget* aWidget, nsPresContext* aPresContext, |
97 | | nsIContent* aContent, EditorBase* aEditorBase); |
98 | | |
99 | | /** |
100 | | * Destroy() finalizes the instance, i.e., stops observing contents and |
101 | | * clearing the members. |
102 | | * Be aware, callers of this method need to guarantee that the instance |
103 | | * won't be released during calling this. |
104 | | */ |
105 | | void Destroy(); |
106 | | |
107 | | /** |
108 | | * Returns false if the instance refers some objects and observing them. |
109 | | * Otherwise, true. |
110 | | */ |
111 | | bool Destroyed() const; |
112 | | |
113 | | /** |
114 | | * IMEContentObserver is stored by EventStateManager during observing. |
115 | | * DisconnectFromEventStateManager() is called when EventStateManager stops |
116 | | * storing the instance. |
117 | | */ |
118 | | void DisconnectFromEventStateManager(); |
119 | | |
120 | | /** |
121 | | * MaybeReinitialize() tries to restart to observe the editor's root node. |
122 | | * This is useful when the editor is reframed and all children are replaced |
123 | | * with new node instances. |
124 | | * Be aware, callers of this method need to guarantee that the instance |
125 | | * won't be released during calling this. |
126 | | * |
127 | | * @return Returns true if the instance is managing the content. |
128 | | * Otherwise, false. |
129 | | */ |
130 | | bool MaybeReinitialize(nsIWidget* aWidget, |
131 | | nsPresContext* aPresContext, |
132 | | nsIContent* aContent, |
133 | | EditorBase* aEditorBase); |
134 | | |
135 | | bool IsManaging(nsPresContext* aPresContext, nsIContent* aContent) const; |
136 | | bool IsManaging(const TextComposition* aTextComposition) const; |
137 | | bool WasInitializedWithPlugin() const; |
138 | | bool WasInitializedWith(const EditorBase& aEditorBase) const |
139 | 0 | { |
140 | 0 | return mEditorBase == &aEditorBase; |
141 | 0 | } |
142 | | bool IsEditorHandlingEventForComposition() const; |
143 | | bool KeepAliveDuringDeactive() const |
144 | 0 | { |
145 | 0 | return mIMENotificationRequests && |
146 | 0 | mIMENotificationRequests->WantDuringDeactive(); |
147 | 0 | } |
148 | 0 | nsIWidget* GetWidget() const { return mWidget; } |
149 | | void SuppressNotifyingIME(); |
150 | | void UnsuppressNotifyingIME(); |
151 | | nsPresContext* GetPresContext() const; |
152 | | nsresult GetSelectionAndRoot(dom::Selection** aSelection, |
153 | | nsIContent** aRoot) const; |
154 | | |
155 | | /** |
156 | | * TryToFlushPendingNotifications() should be called when pending events |
157 | | * should be flushed. This tries to run the queued IMENotificationSender. |
158 | | * Doesn't do anything in child processes where flushing happens |
159 | | * asynchronously unless aAllowAsync is false. |
160 | | */ |
161 | | void TryToFlushPendingNotifications(bool aAllowAsync); |
162 | | |
163 | | /** |
164 | | * MaybeNotifyCompositionEventHandled() posts composition event handled |
165 | | * notification into the pseudo queue. |
166 | | */ |
167 | | void MaybeNotifyCompositionEventHandled(); |
168 | | |
169 | | /** |
170 | | * Following methods are called when the editor: |
171 | | * - an edit action handled. |
172 | | * - before handling an edit action. |
173 | | * - canceled handling an edit action after calling BeforeEditAction(). |
174 | | */ |
175 | | void OnEditActionHandled(); |
176 | | void BeforeEditAction(); |
177 | | void CancelEditAction(); |
178 | | |
179 | | private: |
180 | 0 | ~IMEContentObserver() {} |
181 | | |
182 | | enum State { |
183 | | eState_NotObserving, |
184 | | eState_Initializing, |
185 | | eState_StoppedObserving, |
186 | | eState_Observing |
187 | | }; |
188 | | State GetState() const; |
189 | | bool InitWithEditor(nsPresContext* aPresContext, nsIContent* aContent, |
190 | | EditorBase* aEditorBase); |
191 | | bool InitWithPlugin(nsPresContext* aPresContext, nsIContent* aContent); |
192 | 0 | bool IsInitializedWithPlugin() const { return !mEditorBase; } |
193 | | void OnIMEReceivedFocus(); |
194 | | void Clear(); |
195 | | bool IsObservingContent(nsPresContext* aPresContext, |
196 | | nsIContent* aContent) const; |
197 | | bool IsReflowLocked() const; |
198 | | bool IsSafeToNotifyIME() const; |
199 | | bool IsEditorComposing() const; |
200 | | |
201 | | // Following methods are called by DocumentObserver when |
202 | | // beginning to update the contents and ending updating the contents. |
203 | | void BeginDocumentUpdate(); |
204 | | void EndDocumentUpdate(); |
205 | | |
206 | | // Following methods manages added nodes during a document change. |
207 | | |
208 | | /** |
209 | | * MaybeNotifyIMEOfAddedTextDuringDocumentChange() may send text change |
210 | | * notification caused by the nodes added between mFirstAddedContent in |
211 | | * mFirstAddedContainer and mLastAddedContent in |
212 | | * mLastAddedContainer and forgets the range. |
213 | | */ |
214 | | void MaybeNotifyIMEOfAddedTextDuringDocumentChange(); |
215 | | |
216 | | /** |
217 | | * IsInDocumentChange() returns true while the DOM tree is being modified |
218 | | * with mozAutoDocUpdate. E.g., it's being modified by setting innerHTML or |
219 | | * insertAdjacentHTML(). This returns false when user types something in |
220 | | * the focused editor editor. |
221 | | */ |
222 | | bool IsInDocumentChange() const |
223 | 0 | { |
224 | 0 | return mDocumentObserver && mDocumentObserver->IsUpdating(); |
225 | 0 | } |
226 | | |
227 | | /** |
228 | | * Forget the range of added nodes during a document change. |
229 | | */ |
230 | | void ClearAddedNodesDuringDocumentChange(); |
231 | | |
232 | | /** |
233 | | * HasAddedNodesDuringDocumentChange() returns true when this stores range |
234 | | * of nodes which were added into the DOM tree during a document change but |
235 | | * have not been sent to IME. Note that this should always return false when |
236 | | * IsInDocumentChange() returns false. |
237 | | */ |
238 | | bool HasAddedNodesDuringDocumentChange() const |
239 | 0 | { |
240 | 0 | return mFirstAddedContainer && mLastAddedContainer; |
241 | 0 | } |
242 | | |
243 | | /** |
244 | | * Returns true if the passed-in node in aParent is the next node of |
245 | | * mLastAddedContent in pre-order tree traversal of the DOM. |
246 | | */ |
247 | | bool IsNextNodeOfLastAddedNode(nsINode* aParent, nsIContent* aChild) const; |
248 | | |
249 | | void PostFocusSetNotification(); |
250 | | void MaybeNotifyIMEOfFocusSet(); |
251 | | void PostTextChangeNotification(); |
252 | | void MaybeNotifyIMEOfTextChange(const TextChangeDataBase& aTextChangeData); |
253 | | void CancelNotifyingIMEOfTextChange(); |
254 | | void PostSelectionChangeNotification(); |
255 | | void MaybeNotifyIMEOfSelectionChange(bool aCausedByComposition, |
256 | | bool aCausedBySelectionEvent, |
257 | | bool aOccurredDuringComposition); |
258 | | void PostPositionChangeNotification(); |
259 | | void MaybeNotifyIMEOfPositionChange(); |
260 | | void CancelNotifyingIMEOfPositionChange(); |
261 | | void PostCompositionEventHandledNotification(); |
262 | | |
263 | | void NotifyContentAdded(nsINode* aContainer, |
264 | | nsIContent* aFirstContent, |
265 | | nsIContent* aLastContent); |
266 | | void ObserveEditableNode(); |
267 | | /** |
268 | | * NotifyIMEOfBlur() notifies IME of blur. |
269 | | */ |
270 | | void NotifyIMEOfBlur(); |
271 | | /** |
272 | | * UnregisterObservers() unregisters all listeners and observers. |
273 | | */ |
274 | | void UnregisterObservers(); |
275 | | void FlushMergeableNotifications(); |
276 | | bool NeedsTextChangeNotification() const |
277 | 0 | { |
278 | 0 | return mIMENotificationRequests && |
279 | 0 | mIMENotificationRequests->WantTextChange(); |
280 | 0 | } |
281 | | bool NeedsPositionChangeNotification() const |
282 | 0 | { |
283 | 0 | return mIMENotificationRequests && |
284 | 0 | mIMENotificationRequests->WantPositionChanged(); |
285 | 0 | } |
286 | | void ClearPendingNotifications() |
287 | 0 | { |
288 | 0 | mNeedsToNotifyIMEOfFocusSet = false; |
289 | 0 | mNeedsToNotifyIMEOfTextChange = false; |
290 | 0 | mNeedsToNotifyIMEOfSelectionChange = false; |
291 | 0 | mNeedsToNotifyIMEOfPositionChange = false; |
292 | 0 | mNeedsToNotifyIMEOfCompositionEventHandled = false; |
293 | 0 | mTextChangeData.Clear(); |
294 | 0 | } |
295 | | bool NeedsToNotifyIMEOfSomething() const |
296 | 0 | { |
297 | 0 | return mNeedsToNotifyIMEOfFocusSet || |
298 | 0 | mNeedsToNotifyIMEOfTextChange || |
299 | 0 | mNeedsToNotifyIMEOfSelectionChange || |
300 | 0 | mNeedsToNotifyIMEOfPositionChange || |
301 | 0 | mNeedsToNotifyIMEOfCompositionEventHandled; |
302 | 0 | } |
303 | | |
304 | | /** |
305 | | * UpdateSelectionCache() updates mSelectionData with the latest selection. |
306 | | * This should be called only when IsSafeToNotifyIME() returns true. |
307 | | * |
308 | | * Note that this does nothing if WasInitializedWithPlugin() returns true. |
309 | | */ |
310 | | bool UpdateSelectionCache(); |
311 | | |
312 | | nsCOMPtr<nsIWidget> mWidget; |
313 | | // mFocusedWidget has the editor observed by the instance. E.g., if the |
314 | | // focused editor is in XUL panel, this should be the widget of the panel. |
315 | | // On the other hand, mWidget is its parent which handles IME. |
316 | | nsCOMPtr<nsIWidget> mFocusedWidget; |
317 | | RefPtr<dom::Selection> mSelection; |
318 | | nsCOMPtr<nsIContent> mRootContent; |
319 | | nsCOMPtr<nsINode> mEditableNode; |
320 | | nsCOMPtr<nsIDocShell> mDocShell; |
321 | | RefPtr<EditorBase> mEditorBase; |
322 | | |
323 | | /** |
324 | | * Helper classes to notify IME. |
325 | | */ |
326 | | |
327 | | class AChangeEvent: public Runnable |
328 | | { |
329 | | protected: |
330 | | enum ChangeEventType |
331 | | { |
332 | | eChangeEventType_Focus, |
333 | | eChangeEventType_Selection, |
334 | | eChangeEventType_Text, |
335 | | eChangeEventType_Position, |
336 | | eChangeEventType_CompositionEventHandled |
337 | | }; |
338 | | |
339 | | explicit AChangeEvent(const char* aName, |
340 | | IMEContentObserver* aIMEContentObserver) |
341 | | : Runnable(aName) |
342 | | , mIMEContentObserver( |
343 | | do_GetWeakReference( |
344 | | static_cast<nsIReflowObserver*>(aIMEContentObserver))) |
345 | 0 | { |
346 | 0 | MOZ_ASSERT(aIMEContentObserver); |
347 | 0 | } |
348 | | |
349 | | already_AddRefed<IMEContentObserver> GetObserver() const |
350 | 0 | { |
351 | 0 | nsCOMPtr<nsIReflowObserver> observer = |
352 | 0 | do_QueryReferent(mIMEContentObserver); |
353 | 0 | return observer.forget().downcast<IMEContentObserver>(); |
354 | 0 | } |
355 | | |
356 | | nsWeakPtr mIMEContentObserver; |
357 | | |
358 | | /** |
359 | | * CanNotifyIME() checks if mIMEContentObserver can and should notify IME. |
360 | | */ |
361 | | bool CanNotifyIME(ChangeEventType aChangeEventType) const; |
362 | | |
363 | | /** |
364 | | * IsSafeToNotifyIME() checks if it's safe to noitify IME. |
365 | | */ |
366 | | bool IsSafeToNotifyIME(ChangeEventType aChangeEventType) const; |
367 | | }; |
368 | | |
369 | | class IMENotificationSender: public AChangeEvent |
370 | | { |
371 | | public: |
372 | | explicit IMENotificationSender(IMEContentObserver* aIMEContentObserver) |
373 | | : AChangeEvent("IMENotificationSender", aIMEContentObserver) |
374 | | , mIsRunning(false) |
375 | 0 | { |
376 | 0 | } |
377 | | NS_IMETHOD Run() override; |
378 | | |
379 | | void Dispatch(nsIDocShell* aDocShell); |
380 | | private: |
381 | | void SendFocusSet(); |
382 | | void SendSelectionChange(); |
383 | | void SendTextChange(); |
384 | | void SendPositionChange(); |
385 | | void SendCompositionEventHandled(); |
386 | | |
387 | | bool mIsRunning; |
388 | | }; |
389 | | |
390 | | // mQueuedSender is, it was put into the event queue but not run yet. |
391 | | RefPtr<IMENotificationSender> mQueuedSender; |
392 | | |
393 | | /** |
394 | | * IMEContentObserver is a mutation observer of mRootContent. However, |
395 | | * it needs to know the beginning of content changes and end of it too for |
396 | | * reducing redundant computation of text offset with ContentEventHandler. |
397 | | * Therefore, it needs helper class to listen only them since if |
398 | | * both mutations were observed by IMEContentObserver directly, each |
399 | | * methods need to check if the changing node is in mRootContent but it's |
400 | | * too expensive. |
401 | | */ |
402 | | class DocumentObserver final : public nsStubDocumentObserver |
403 | | { |
404 | | public: |
405 | | explicit DocumentObserver(IMEContentObserver& aIMEContentObserver) |
406 | | : mIMEContentObserver(&aIMEContentObserver) |
407 | | , mDocumentUpdating(0) |
408 | 0 | { |
409 | 0 | } |
410 | | |
411 | | NS_DECL_CYCLE_COLLECTION_CLASS(DocumentObserver) |
412 | | NS_DECL_CYCLE_COLLECTING_ISUPPORTS |
413 | | NS_DECL_NSIDOCUMENTOBSERVER_BEGINUPDATE |
414 | | NS_DECL_NSIDOCUMENTOBSERVER_ENDUPDATE |
415 | | |
416 | | void Observe(nsIDocument* aDocument); |
417 | | void StopObserving(); |
418 | | void Destroy(); |
419 | | |
420 | 0 | bool Destroyed() const { return !mIMEContentObserver; } |
421 | 0 | bool IsObserving() const { return mDocument != nullptr; } |
422 | 0 | bool IsUpdating() const { return mDocumentUpdating != 0; } |
423 | | |
424 | | private: |
425 | | DocumentObserver() = delete; |
426 | 0 | virtual ~DocumentObserver() { Destroy(); } |
427 | | |
428 | | RefPtr<IMEContentObserver> mIMEContentObserver; |
429 | | nsCOMPtr<nsIDocument> mDocument; |
430 | | uint32_t mDocumentUpdating; |
431 | | }; |
432 | | RefPtr<DocumentObserver> mDocumentObserver; |
433 | | |
434 | | /** |
435 | | * FlatTextCache stores flat text length from start of the content to |
436 | | * mNodeOffset of mContainerNode. |
437 | | */ |
438 | | struct FlatTextCache |
439 | | { |
440 | | // mContainerNode and mNode represent a point in DOM tree. E.g., |
441 | | // if mContainerNode is a div element, mNode is a child. |
442 | | nsCOMPtr<nsINode> mContainerNode; |
443 | | // mNode points to the last child which participates in the current |
444 | | // mFlatTextLength. If mNode is null, then that means that the end point for |
445 | | // mFlatTextLength is immediately before the first child of mContainerNode. |
446 | | nsCOMPtr<nsINode> mNode; |
447 | | // Length of flat text generated from contents between the start of content |
448 | | // and a child node whose index is mNodeOffset of mContainerNode. |
449 | | uint32_t mFlatTextLength; |
450 | | |
451 | | FlatTextCache() |
452 | | : mFlatTextLength(0) |
453 | 0 | { |
454 | 0 | } |
455 | | |
456 | | void Clear() |
457 | 0 | { |
458 | 0 | mContainerNode = nullptr; |
459 | 0 | mNode = nullptr; |
460 | 0 | mFlatTextLength = 0; |
461 | 0 | } |
462 | | |
463 | | void Cache(nsINode* aContainer, nsINode* aNode, |
464 | | uint32_t aFlatTextLength) |
465 | 0 | { |
466 | 0 | MOZ_ASSERT(aContainer, "aContainer must not be null"); |
467 | 0 | MOZ_ASSERT(!aNode || aNode->GetParentNode() == aContainer, |
468 | 0 | "aNode must be either null or a child of aContainer"); |
469 | 0 | mContainerNode = aContainer; |
470 | 0 | mNode = aNode; |
471 | 0 | mFlatTextLength = aFlatTextLength; |
472 | 0 | } |
473 | | |
474 | | bool Match(nsINode* aContainer, nsINode* aNode) const |
475 | 0 | { |
476 | 0 | return aContainer == mContainerNode && aNode == mNode; |
477 | 0 | } |
478 | | }; |
479 | | // mEndOfAddedTextCache caches text length from the start of content to |
480 | | // the end of the last added content only while an edit action is being |
481 | | // handled by the editor and no other mutation (e.g., removing node) |
482 | | // occur. |
483 | | FlatTextCache mEndOfAddedTextCache; |
484 | | // mStartOfRemovingTextRangeCache caches text length from the start of content |
485 | | // to the start of the last removed content only while an edit action is being |
486 | | // handled by the editor and no other mutation (e.g., adding node) occur. |
487 | | FlatTextCache mStartOfRemovingTextRangeCache; |
488 | | |
489 | | // mFirstAddedContainer is parent node of first added node in current |
490 | | // document change. So, this is not nullptr only when a node was added |
491 | | // during a document change and the change has not been included into |
492 | | // mTextChangeData yet. |
493 | | // Note that this shouldn't be in cycle collection since this is not nullptr |
494 | | // only during a document change. |
495 | | nsCOMPtr<nsINode> mFirstAddedContainer; |
496 | | // mLastAddedContainer is parent node of last added node in current |
497 | | // document change. So, this is not nullptr only when a node was added |
498 | | // during a document change and the change has not been included into |
499 | | // mTextChangeData yet. |
500 | | // Note that this shouldn't be in cycle collection since this is not nullptr |
501 | | // only during a document change. |
502 | | nsCOMPtr<nsINode> mLastAddedContainer; |
503 | | |
504 | | // mFirstAddedContent is the first node added in mFirstAddedContainer. |
505 | | nsCOMPtr<nsIContent> mFirstAddedContent; |
506 | | // mLastAddedContent is the last node added in mLastAddedContainer; |
507 | | nsCOMPtr<nsIContent> mLastAddedContent; |
508 | | |
509 | | TextChangeData mTextChangeData; |
510 | | |
511 | | // mSelectionData is the last selection data which was notified. The |
512 | | // selection information is modified by UpdateSelectionCache(). The reason |
513 | | // of the selection change is modified by MaybeNotifyIMEOfSelectionChange(). |
514 | | SelectionChangeData mSelectionData; |
515 | | |
516 | | EventStateManager* mESM; |
517 | | |
518 | | const IMENotificationRequests* mIMENotificationRequests; |
519 | | uint32_t mPreAttrChangeLength; |
520 | | uint32_t mSuppressNotifications; |
521 | | int64_t mPreCharacterDataChangeLength; |
522 | | |
523 | | // mSendingNotification is a notification which is now sending from |
524 | | // IMENotificationSender. When the value is NOTIFY_IME_OF_NOTHING, it's |
525 | | // not sending any notification. |
526 | | IMEMessage mSendingNotification; |
527 | | |
528 | | bool mIsObserving; |
529 | | bool mIMEHasFocus; |
530 | | bool mNeedsToNotifyIMEOfFocusSet; |
531 | | bool mNeedsToNotifyIMEOfTextChange; |
532 | | bool mNeedsToNotifyIMEOfSelectionChange; |
533 | | bool mNeedsToNotifyIMEOfPositionChange; |
534 | | bool mNeedsToNotifyIMEOfCompositionEventHandled; |
535 | | // mIsHandlingQueryContentEvent is true when IMEContentObserver is handling |
536 | | // WidgetQueryContentEvent with ContentEventHandler. |
537 | | bool mIsHandlingQueryContentEvent; |
538 | | }; |
539 | | |
540 | | } // namespace mozilla |
541 | | |
542 | | #endif // mozilla_IMEContentObserver_h |