Bug 1032573 part 4 - Add AnimationTimeline::ToTimelineTime helper method; r=dbaron
[gecko.git] / dom / events / TextComposition.h
blobad859c652de19709bc10e95d248734932b883547
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_TextComposition_h
8 #define mozilla_TextComposition_h
10 #include "nsCOMPtr.h"
11 #include "nsINode.h"
12 #include "nsIWeakReference.h"
13 #include "nsIWidget.h"
14 #include "nsTArray.h"
15 #include "nsThreadUtils.h"
16 #include "nsPresContext.h"
17 #include "mozilla/Attributes.h"
18 #include "mozilla/EventForwards.h"
19 #include "mozilla/TextRange.h"
21 class nsIEditor;
23 namespace mozilla {
25 class EventDispatchingCallback;
26 class IMEStateManager;
28 /**
29 * TextComposition represents a text composition. This class stores the
30 * composition event target and its presContext. At dispatching the event via
31 * this class, the instances use the stored event target.
34 class TextComposition MOZ_FINAL
36 friend class IMEStateManager;
38 NS_INLINE_DECL_REFCOUNTING(TextComposition)
40 public:
41 TextComposition(nsPresContext* aPresContext,
42 nsINode* aNode,
43 WidgetGUIEvent* aEvent);
45 bool Destroyed() const { return !mPresContext; }
46 nsPresContext* GetPresContext() const { return mPresContext; }
47 nsINode* GetEventTargetNode() const { return mNode; }
48 // The latest CompositionEvent.data value except compositionstart event.
49 // This value is modified at dispatching compositionupdate.
50 const nsString& LastData() const { return mLastData; }
51 // The composition string which is already handled by the focused editor.
52 // I.e., this value must be same as the composition string on the focused
53 // editor. This value is modified at a call of EditorDidHandleTextEvent().
54 // Note that mString and mLastData are different between dispatcing
55 // compositionupdate and text event handled by focused editor.
56 const nsString& String() const { return mString; }
57 // Returns the clauses and/or caret range of the composition string.
58 // This is modified at a call of EditorWillHandleTextEvent().
59 // This may return null if there is no clauses and caret.
60 // XXX We should return |const TextRangeArray*| here, but it causes compile
61 // error due to inaccessible Release() method.
62 TextRangeArray* GetRanges() const { return mRanges; }
63 // Returns true if the composition is started with synthesized event which
64 // came from nsDOMWindowUtils.
65 bool IsSynthesizedForTests() const { return mIsSynthesizedForTests; }
67 bool MatchesNativeContext(nsIWidget* aWidget) const;
69 /**
70 * This is called when IMEStateManager stops managing the instance.
72 void Destroy();
74 /**
75 * SynthesizeCommit() dispatches compositionupdate, text and compositionend
76 * events for emulating commit on the content.
78 * @param aDiscard true when committing with empty string. Otherwise, false.
80 void SynthesizeCommit(bool aDiscard);
82 /**
83 * Send a notification to IME. It depends on the IME or platform spec what
84 * will occur (or not occur).
86 nsresult NotifyIME(widget::IMEMessage aMessage);
88 /**
89 * the offset of first selected clause or start of of compositon
91 uint32_t OffsetOfTargetClause() const { return mCompositionTargetOffset; }
93 /**
94 * Returns true if there is non-empty composition string and it's not fixed.
95 * Otherwise, false.
97 bool IsComposing() const { return mIsComposing; }
99 /**
100 * Returns true while editor is handling an event which is modifying the
101 * composition string.
103 bool IsEditorHandlingEvent() const
105 return mIsEditorHandlingEvent;
109 * StartHandlingComposition() and EndHandlingComposition() are called by
110 * editor when it holds a TextComposition instance and release it.
112 void StartHandlingComposition(nsIEditor* aEditor);
113 void EndHandlingComposition(nsIEditor* aEditor);
116 * TextEventHandlingMarker class should be created at starting to handle text
117 * event in focused editor. This calls EditorWillHandleTextEvent() and
118 * EditorDidHandleTextEvent() automatically.
120 class MOZ_STACK_CLASS TextEventHandlingMarker
122 public:
123 TextEventHandlingMarker(TextComposition* aComposition,
124 const WidgetTextEvent* aTextEvent)
125 : mComposition(aComposition)
127 mComposition->EditorWillHandleTextEvent(aTextEvent);
130 ~TextEventHandlingMarker()
132 mComposition->EditorDidHandleTextEvent();
135 private:
136 nsRefPtr<TextComposition> mComposition;
137 TextEventHandlingMarker();
138 TextEventHandlingMarker(const TextEventHandlingMarker& aOther);
141 private:
142 // Private destructor, to discourage deletion outside of Release():
143 ~TextComposition()
145 // WARNING: mPresContext may be destroying, so, be careful if you touch it.
148 // This class holds nsPresContext weak. This instance shouldn't block
149 // destroying it. When the presContext is being destroyed, it's notified to
150 // IMEStateManager::OnDestroyPresContext(), and then, it destroy
151 // this instance.
152 nsPresContext* mPresContext;
153 nsCOMPtr<nsINode> mNode;
155 // This is the clause and caret range information which is managed by
156 // the focused editor. This may be null if there is no clauses or caret.
157 nsRefPtr<TextRangeArray> mRanges;
159 // mNativeContext stores a opaque pointer. This works as the "ID" for this
160 // composition. Don't access the instance, it may not be available.
161 void* mNativeContext;
163 // mEditorWeak is a weak reference to the focused editor handling composition.
164 nsWeakPtr mEditorWeak;
166 // mLastData stores the data attribute of the latest composition event (except
167 // the compositionstart event).
168 nsString mLastData;
170 // mString stores the composition text which has been handled by the focused
171 // editor.
172 nsString mString;
174 // Offset of the composition string from start of the editor
175 uint32_t mCompositionStartOffset;
176 // Offset of the selected clause of the composition string from start of the
177 // editor
178 uint32_t mCompositionTargetOffset;
180 // See the comment for IsSynthesizedForTests().
181 bool mIsSynthesizedForTests;
183 // See the comment for IsComposing().
184 bool mIsComposing;
186 // mIsEditorHandlingEvent is true while editor is modifying the composition
187 // string.
188 bool mIsEditorHandlingEvent;
190 // Hide the default constructor and copy constructor.
191 TextComposition() {}
192 TextComposition(const TextComposition& aOther);
195 * GetEditor() returns nsIEditor pointer of mEditorWeak.
197 already_AddRefed<nsIEditor> GetEditor() const;
200 * HasEditor() returns true if mEditorWeak holds nsIEditor instance which is
201 * alive. Otherwise, false.
203 bool HasEditor() const;
206 * EditorWillHandleTextEvent() must be called before the focused editor
207 * handles the text event.
209 void EditorWillHandleTextEvent(const WidgetTextEvent* aTextEvent);
212 * EditorDidHandleTextEvent() must be called after the focused editor handles
213 * a text event.
215 void EditorDidHandleTextEvent();
218 * DispatchEvent() dispatches the aEvent to the mContent synchronously.
219 * The caller must ensure that it's safe to dispatch the event.
221 void DispatchEvent(WidgetGUIEvent* aEvent,
222 nsEventStatus* aStatus,
223 EventDispatchingCallback* aCallBack);
226 * Calculate composition offset then notify composition update to widget
228 void NotityUpdateComposition(WidgetGUIEvent* aEvent);
231 * CompositionEventDispatcher dispatches the specified composition (or text)
232 * event.
234 class CompositionEventDispatcher : public nsRunnable
236 public:
237 CompositionEventDispatcher(nsPresContext* aPresContext,
238 nsINode* aEventTarget,
239 uint32_t aEventMessage,
240 const nsAString& aData);
241 NS_IMETHOD Run() MOZ_OVERRIDE;
243 private:
244 nsRefPtr<nsPresContext> mPresContext;
245 nsCOMPtr<nsINode> mEventTarget;
246 nsCOMPtr<nsIWidget> mWidget;
247 uint32_t mEventMessage;
248 nsString mData;
250 CompositionEventDispatcher() {};
254 * DispatchCompositionEventRunnable() dispatches a composition or text event
255 * to the content. Be aware, if you use this method, nsPresShellEventCB
256 * isn't used. That means that nsIFrame::HandleEvent() is never called.
257 * WARNING: The instance which is managed by IMEStateManager may be
258 * destroyed by this method call.
260 * @param aEventMessage Must be one of composition event or text event.
261 * @param aData Used for data value if aEventMessage is
262 * NS_COMPOSITION_UPDATE or NS_COMPOSITION_END.
263 * Used for theText value if aEventMessage is
264 * NS_TEXT_TEXT.
266 void DispatchCompositionEventRunnable(uint32_t aEventMessage,
267 const nsAString& aData);
271 * TextCompositionArray manages the instances of TextComposition class.
272 * Managing with array is enough because only one composition is typically
273 * there. Even if user switches native IME context, it's very rare that
274 * second or more composition is started.
275 * It's assumed that this is used by IMEStateManager for storing all active
276 * compositions in the process. If the instance is it, each TextComposition
277 * in the array can be destroyed by calling some methods of itself.
280 class TextCompositionArray MOZ_FINAL :
281 public nsAutoTArray<nsRefPtr<TextComposition>, 2>
283 public:
284 index_type IndexOf(nsIWidget* aWidget);
285 index_type IndexOf(nsPresContext* aPresContext);
286 index_type IndexOf(nsPresContext* aPresContext, nsINode* aNode);
288 TextComposition* GetCompositionFor(nsIWidget* aWidget);
289 TextComposition* GetCompositionFor(nsPresContext* aPresContext,
290 nsINode* aNode);
291 TextComposition* GetCompositionInContent(nsPresContext* aPresContext,
292 nsIContent* aContent);
295 } // namespace mozilla
297 #endif // #ifndef mozilla_TextComposition_h