TextComposition.h (24885B)
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_TextComposition_h 8 #define mozilla_TextComposition_h 9 10 #include "mozilla/AlreadyAddRefed.h" 11 #include "mozilla/Attributes.h" 12 #include "mozilla/EventForwards.h" 13 #include "mozilla/RangeBoundary.h" 14 #include "mozilla/TextRange.h" 15 #include "mozilla/dom/BrowserParent.h" 16 #include "mozilla/dom/Text.h" 17 #include "nsCOMPtr.h" 18 #include "nsINode.h" 19 #include "nsIWidget.h" 20 #include "nsPresContext.h" 21 #include "nsTArray.h" 22 #include "nsThreadUtils.h" 23 24 class nsRange; 25 26 struct CharacterDataChangeInfo; 27 28 namespace mozilla { 29 30 class EditorBase; 31 class EventDispatchingCallback; 32 class IMEStateManager; 33 34 /** 35 * TextComposition represents a text composition. This class stores the 36 * composition event target and its presContext. At dispatching the event via 37 * this class, the instances use the stored event target. 38 */ 39 40 class TextComposition final { 41 friend class IMEStateManager; 42 43 NS_INLINE_DECL_REFCOUNTING(TextComposition) 44 45 public: 46 typedef dom::BrowserParent BrowserParent; 47 typedef dom::Text Text; 48 49 static bool IsHandlingSelectionEvent() { return sHandlingSelectionEvent; } 50 51 TextComposition(nsPresContext* aPresContext, nsINode* aNode, 52 BrowserParent* aBrowserParent, 53 WidgetCompositionEvent* aCompositionEvent); 54 TextComposition() = delete; 55 TextComposition(const TextComposition& aOther) = delete; 56 57 bool Destroyed() const { return !mPresContext; } 58 nsPresContext* GetPresContext() const { return mPresContext; } 59 nsINode* GetEventTargetNode() const { return mNode; } 60 // The text node which includes composition string. 61 Text* GetContainerTextNode() const { return mContainerTextNode; } 62 // The latest CompositionEvent.data value except compositionstart event. 63 // This value is modified at dispatching compositionupdate. 64 const nsString& LastData() const { return mLastData; } 65 // Returns commit string if it'll be commited as-is. 66 nsString CommitStringIfCommittedAsIs() const; 67 // The composition string which is already handled by the focused editor. 68 // I.e., this value must be same as the composition string on the focused 69 // editor. This value is modified at a call of 70 // EditorDidHandleCompositionChangeEvent(). 71 // Note that mString and mLastData are different between dispatcing 72 // compositionupdate and compositionchange event handled by focused editor. 73 const nsString& String() const { return mString; } 74 // The latest clauses range of the composition string. 75 // During compositionupdate event, GetRanges() returns old ranges. 76 // So if getting on compositionupdate, Use GetLastRange instead of GetRange(). 77 TextRangeArray* GetLastRanges() const { return mLastRanges; } 78 // Returns the clauses and/or caret range of the composition string. 79 // This is modified at a call of EditorWillHandleCompositionChangeEvent(). 80 // This may return null if there is no clauses and caret. 81 // XXX We should return |const TextRangeArray*| here, but it causes compile 82 // error due to inaccessible Release() method. 83 TextRangeArray* GetRanges() const { return mRanges; } 84 // Returns the widget which is proper to call NotifyIME(). 85 already_AddRefed<nsIWidget> GetWidget() const { 86 if (!mPresContext) { 87 return nullptr; 88 } 89 return do_AddRef(mPresContext->GetRootWidget()); 90 } 91 /** 92 * GetEditorBase() returns EditorBase pointer of mEditorBaseWeak. 93 */ 94 already_AddRefed<EditorBase> GetEditorBase() const; 95 // Returns the tab parent which has this composition in its remote process. 96 BrowserParent* GetBrowserParent() const { return mBrowserParent; } 97 // Returns true if the composition is started with synthesized event which 98 // came from nsDOMWindowUtils. 99 bool IsSynthesizedForTests() const { return mIsSynthesizedForTests; } 100 101 // Returns the composition ID. It must be 0 if the composition is synthesized 102 // in a content process. Otherwise, returns 1 or larger value. 103 uint32_t Id() const { return mCompositionId; } 104 105 const widget::NativeIMEContext& GetNativeIMEContext() const { 106 return mNativeContext; 107 } 108 109 /** 110 * This is called when IMEStateManager stops managing the instance. 111 */ 112 void Destroy(); 113 114 /** 115 * Request to commit (or cancel) the composition to IME. This method should 116 * be called only by IMEStateManager::NotifyIME(). 117 */ 118 nsresult RequestToCommit(nsIWidget* aWidget, bool aDiscard); 119 120 /** 121 * IsRequestingCommitOrCancelComposition() returns true if the instance is 122 * requesting widget to commit or cancel composition. 123 */ 124 bool IsRequestingCommitOrCancelComposition() const { 125 return mIsRequestingCancel || mIsRequestingCommit; 126 } 127 128 /** 129 * Send a notification to IME. It depends on the IME or platform spec what 130 * will occur (or not occur). 131 */ 132 nsresult NotifyIME(widget::IMEMessage aMessage); 133 134 /** 135 * the offset of first composition string 136 */ 137 uint32_t NativeOffsetOfStartComposition() const { 138 return mCompositionStartOffset; 139 } 140 141 /** 142 * the offset of first selected clause or start of composition 143 */ 144 uint32_t NativeOffsetOfTargetClause() const { 145 return mCompositionStartOffset + mTargetClauseOffsetInComposition; 146 } 147 148 /** 149 * Return current composition start and end point in the DOM tree. 150 * Note that one of or both of those result container may be different 151 * from GetContainerTextNode() if the DOM tree was modified by the web 152 * app. If there is no composition string the DOM tree, these return 153 * unset range boundaries. 154 */ 155 RawRangeBoundary FirstIMESelectionStartRef() const; 156 RawRangeBoundary LastIMESelectionEndRef() const; 157 158 /** 159 * The offset of composition string in the text node. If composition string 160 * hasn't been inserted in any text node yet, this returns UINT32_MAX. 161 */ 162 uint32_t XPOffsetInTextNode() const { 163 return mCompositionStartOffsetInTextNode; 164 } 165 166 /** 167 * The length of composition string in the text node. If composition string 168 * hasn't been inserted in any text node yet, this returns 0. 169 */ 170 uint32_t XPLengthInTextNode() const { 171 return mCompositionLengthInTextNode == UINT32_MAX 172 ? 0 173 : mCompositionLengthInTextNode; 174 } 175 176 /** 177 * The end offset of composition string in the text node. If composition 178 * string hasn't been inserted in any text node yet, this returns UINT32_MAX. 179 */ 180 uint32_t XPEndOffsetInTextNode() const { 181 if (mCompositionStartOffsetInTextNode == UINT32_MAX || 182 mCompositionLengthInTextNode == UINT32_MAX) { 183 return UINT32_MAX; 184 } 185 return mCompositionStartOffsetInTextNode + mCompositionLengthInTextNode; 186 } 187 188 /** 189 * Returns true if there is non-empty composition string and it's not fixed. 190 * Otherwise, false. 191 */ 192 bool IsComposing() const { return mIsComposing; } 193 194 /** 195 * If we're requesting IME to commit or cancel composition, or we've already 196 * requested it, or we've already known this composition has been ended in 197 * IME, we don't need to request commit nor cancel composition anymore and 198 * shouldn't do so if we're in content process for not committing/canceling 199 * "current" composition in native IME. So, when this returns true, 200 * RequestIMEToCommit() does nothing. 201 */ 202 [[nodiscard]] bool CanRequsetIMEToCommitOrCancelComposition() const { 203 return !mIsRequestingCommit && !mIsRequestingCancel && 204 !mRequestedToCommitOrCancel && !mHasReceivedCommitEvent; 205 } 206 207 /** 208 * Returns true if editor has started or already ended handling an event which 209 * is modifying the composition string and/or IME selections. 210 */ 211 [[nodiscard]] bool EditorHasHandledLatestChange() const { 212 return EditorIsHandlingLatestChange() || 213 (mLastRanges == mRanges && mLastData == mString); 214 } 215 216 /** 217 * Returns true while editor is handling an event which is modifying the 218 * composition string and/or IME selections. 219 */ 220 [[nodiscard]] bool EditorIsHandlingLatestChange() const { 221 return mEditorIsHandlingEvent; 222 } 223 224 /** 225 * IsMovingToNewTextNode() returns true if editor detects the text node 226 * has been removed and still not insert the composition string into 227 * new text node. 228 */ 229 bool IsMovingToNewTextNode() const { 230 return !mContainerTextNode && mCompositionLengthInTextNode && 231 mCompositionLengthInTextNode != UINT32_MAX; 232 } 233 234 /** 235 * StartHandlingComposition() and EndHandlingComposition() are called by 236 * editor when it holds a TextComposition instance and release it. 237 */ 238 void StartHandlingComposition(EditorBase* aEditorBase); 239 void EndHandlingComposition(EditorBase* aEditorBase); 240 241 /** 242 * OnEditorDestroyed() is called when the editor is destroyed but there is 243 * active composition. 244 */ 245 void OnEditorDestroyed(); 246 247 /** 248 * CompositionChangeEventHandlingMarker class should be created at starting 249 * to handle text event in focused editor. This calls 250 * EditorWillHandleCompositionChangeEvent() and 251 * EditorDidHandleCompositionChangeEvent() automatically. 252 */ 253 class MOZ_STACK_CLASS CompositionChangeEventHandlingMarker { 254 public: 255 CompositionChangeEventHandlingMarker( 256 TextComposition* aComposition, 257 const WidgetCompositionEvent* aCompositionChangeEvent) 258 : mComposition(aComposition) { 259 mComposition->EditorWillHandleCompositionChangeEvent( 260 aCompositionChangeEvent); 261 } 262 263 ~CompositionChangeEventHandlingMarker() { 264 mComposition->EditorDidHandleCompositionChangeEvent(); 265 } 266 267 private: 268 RefPtr<TextComposition> mComposition; 269 CompositionChangeEventHandlingMarker(); 270 CompositionChangeEventHandlingMarker( 271 const CompositionChangeEventHandlingMarker& aOther); 272 }; 273 274 /** 275 * OnUpdateCompositionInEditor() is called when editor updates composition 276 * string in the DOM tree. 277 * 278 * @param aStringToInsert The string to insert the text node actually. 279 * This may be different from the data of 280 * dispatching composition event because it may 281 * be replaced with different character for 282 * passwords, or truncated due to maxlength. 283 * @param aTextNode The text node which includes composition string. 284 * @param aOffset The offset of composition string in aTextNode. 285 */ 286 void OnUpdateCompositionInEditor(const nsAString& aStringToInsert, 287 Text& aTextNode, uint32_t aOffset) { 288 mContainerTextNode = &aTextNode; 289 mCompositionStartOffsetInTextNode = aOffset; 290 NS_WARNING_ASSERTION(mCompositionStartOffsetInTextNode != UINT32_MAX, 291 "The text node is really too long."); 292 mCompositionLengthInTextNode = aStringToInsert.Length(); 293 NS_WARNING_ASSERTION(mCompositionLengthInTextNode != UINT32_MAX, 294 "The string to insert is really too long."); 295 } 296 297 /** 298 * OnTextNodeRemoved() is called when focused editor is reframed and 299 * mContainerTextNode may be (or have been) replaced with different text 300 * node, or just removes the text node due to empty. 301 */ 302 void OnTextNodeRemoved() { 303 mContainerTextNode = nullptr; 304 // Don't reset mCompositionStartOffsetInTextNode nor 305 // mCompositionLengthInTextNode because editor needs them to restore 306 // composition in new text node. 307 } 308 309 /** 310 * OnCharacterDataChanged() is called when IMEContentObserver receives 311 * character data change notifications. 312 */ 313 void OnCharacterDataChanged(Text& aText, 314 const CharacterDataChangeInfo& aInfo); 315 316 private: 317 // Private destructor, to discourage deletion outside of Release(): 318 ~TextComposition() { 319 // WARNING: mPresContext may be destroying, so, be careful if you touch it. 320 } 321 322 // sHandlingSelectionEvent is true while TextComposition sends a selection 323 // event to ContentEventHandler. 324 static bool sHandlingSelectionEvent; 325 326 // This class holds nsPresContext weak. This instance shouldn't block 327 // destroying it. When the presContext is being destroyed, it's notified to 328 // IMEStateManager::OnDestroyPresContext(), and then, it destroy 329 // this instance. 330 nsPresContext* mPresContext; 331 RefPtr<nsINode> mNode; 332 RefPtr<BrowserParent> mBrowserParent; 333 334 // The text node which includes the composition string. 335 RefPtr<Text> mContainerTextNode; 336 337 // This is the clause and caret range information which is managed by 338 // the focused editor. This may be null if there is no clauses or caret. 339 RefPtr<TextRangeArray> mRanges; 340 // Same as mRange, but mRange will have old ranges before editor starts 341 // handling the latest eCompositionChange. Therefore, this stores the latest 342 // ranges which is introduced by the latest eCompositionChange. So this may 343 // be useful during dispatching eCompositionUpdate or eCompositionChange. 344 RefPtr<TextRangeArray> mLastRanges; 345 346 // mNativeContext stores a opaque pointer. This works as the "ID" for this 347 // composition. Don't access the instance, it may not be available. 348 widget::NativeIMEContext mNativeContext; 349 350 // mEditorBaseWeak is a weak reference to the focused editor handling 351 // composition. 352 nsWeakPtr mEditorBaseWeak; 353 354 // mLastData stores the data attribute of the latest composition event (except 355 // the compositionstart event). 356 nsString mLastData; 357 358 // mString stores the composition text which has been handled by the focused 359 // editor. 360 nsString mString; 361 362 // Composition ID of this composition. If this is in a parent process, 363 // this is 1 or larger. If the composition is created for managing a 364 // composition synthesized in a content process, this is 0. 365 const uint32_t mCompositionId = 0; 366 367 // Offset of the composition string from start of the editor 368 uint32_t mCompositionStartOffset; 369 // Offset of the selected clause of the composition string from 370 // mCompositionStartOffset 371 uint32_t mTargetClauseOffsetInComposition; 372 // Offset of the composition string in mContainerTextNode. 373 // NOTE: This is NOT valid in the main process if focused editor is in a 374 // remote process. 375 uint32_t mCompositionStartOffsetInTextNode; 376 // Length of the composition string in mContainerTextNode. If this instance 377 // has already dispatched eCompositionCommit(AsIs) and 378 // EditorDidHandleCompositionChangeEvent() has already been called, 379 // this may be different from length of mString because committed string 380 // may be truncated by maxlength attribute of <input> or <textarea>. 381 // NOTE: This is NOT valid in the main process if focused editor is in a 382 // remote process. 383 uint32_t mCompositionLengthInTextNode; 384 385 // See the comment for IsSynthesizedForTests(). 386 bool mIsSynthesizedForTests; 387 388 // See the comment for IsComposing(). 389 bool mIsComposing; 390 391 // mEditorIsHandlingEvent is true while editor is modifying the composition 392 // string. 393 bool mEditorIsHandlingEvent = false; 394 395 // mIsRequestingCommit or mIsRequestingCancel is true *only* while we're 396 // requesting commit or canceling the composition. In other words, while 397 // one of these values is true, we're handling the request. 398 bool mIsRequestingCommit; 399 bool mIsRequestingCancel; 400 401 // mRequestedToCommitOrCancel is true *after* we requested IME to commit or 402 // cancel the composition. In other words, we already requested of IME that 403 // it commits or cancels current composition. 404 // NOTE: Before this is set to true, both mIsRequestingCommit and 405 // mIsRequestingCancel are set to false. 406 bool mRequestedToCommitOrCancel; 407 408 // Set to true if the instance dispatches an eCompositionChange event. 409 bool mHasDispatchedDOMTextEvent; 410 411 // Before this dispatches commit event into the tree, this is set to true. 412 // So, this means if native IME already commits the composition. 413 bool mHasReceivedCommitEvent; 414 415 // mWasNativeCompositionEndEventDiscarded is true if this composition was 416 // requested commit or cancel itself but native compositionend event is 417 // discarded by PresShell due to not safe to dispatch events. 418 bool mWasNativeCompositionEndEventDiscarded; 419 420 // Allow control characters appear in composition string. 421 // When this is false, control characters except 422 // CHARACTER TABULATION (horizontal tab) are removed from 423 // both composition string and data attribute of compositionupdate 424 // and compositionend events. 425 bool mAllowControlCharacters; 426 427 // mWasCompositionStringEmpty is true if the composition string was empty 428 // when DispatchCompositionEvent() is called. 429 bool mWasCompositionStringEmpty; 430 431 /** 432 * HasEditor() returns true if mEditorBaseWeak holds EditorBase instance 433 * which is alive. Otherwise, false. 434 */ 435 bool HasEditor() const; 436 437 /** 438 * EditorWillHandleCompositionChangeEvent() must be called before the focused 439 * editor handles the compositionchange event. 440 */ 441 void EditorWillHandleCompositionChangeEvent( 442 const WidgetCompositionEvent* aCompositionChangeEvent); 443 444 /** 445 * EditorDidHandleCompositionChangeEvent() must be called after the focused 446 * editor handles a compositionchange event. 447 */ 448 void EditorDidHandleCompositionChangeEvent(); 449 450 /** 451 * IsValidStateForComposition() returns true if it's safe to dispatch an event 452 * to the DOM tree. Otherwise, false. 453 * WARNING: This doesn't check script blocker state. It should be checked 454 * before dispatching the first event. 455 */ 456 bool IsValidStateForComposition(nsIWidget* aWidget) const; 457 458 /** 459 * DispatchCompositionEvent() dispatches the aCompositionEvent to the mContent 460 * synchronously. The caller must ensure that it's safe to dispatch the event. 461 */ 462 MOZ_CAN_RUN_SCRIPT void DispatchCompositionEvent( 463 WidgetCompositionEvent* aCompositionEvent, nsEventStatus* aStatus, 464 EventDispatchingCallback* aCallBack, bool aIsSynthesized); 465 466 /** 467 * Simply calling EventDispatcher::Dispatch() with plugin event. 468 * If dispatching event has no orginal clone, aOriginalEvent can be null. 469 */ 470 MOZ_CAN_RUN_SCRIPT void DispatchEvent( 471 WidgetCompositionEvent* aDispatchEvent, nsEventStatus* aStatus, 472 EventDispatchingCallback* aCallback, 473 const WidgetCompositionEvent* aOriginalEvent = nullptr); 474 475 /** 476 * HandleSelectionEvent() sends the selection event to ContentEventHandler 477 * or dispatches it to the focused child process. 478 */ 479 MOZ_CAN_RUN_SCRIPT 480 void HandleSelectionEvent(WidgetSelectionEvent* aSelectionEvent) { 481 RefPtr<nsPresContext> presContext(mPresContext); 482 RefPtr<BrowserParent> browserParent(mBrowserParent); 483 HandleSelectionEvent(presContext, browserParent, aSelectionEvent); 484 } 485 MOZ_CAN_RUN_SCRIPT 486 static void HandleSelectionEvent(nsPresContext* aPresContext, 487 BrowserParent* aBrowserParent, 488 WidgetSelectionEvent* aSelectionEvent); 489 490 /** 491 * MaybeDispatchCompositionUpdate() may dispatch a compositionupdate event 492 * if aCompositionEvent changes composition string. 493 * @return Returns false if dispatching the compositionupdate event caused 494 * destroying this composition. 495 */ 496 MOZ_CAN_RUN_SCRIPT bool MaybeDispatchCompositionUpdate( 497 const WidgetCompositionEvent* aCompositionEvent); 498 499 /** 500 * CloneAndDispatchAs() dispatches a composition event which is 501 * duplicateed from aCompositionEvent and set the aMessage. 502 * 503 * @return Returns BaseEventFlags which is the result of dispatched event. 504 */ 505 MOZ_CAN_RUN_SCRIPT BaseEventFlags 506 CloneAndDispatchAs(const WidgetCompositionEvent* aCompositionEvent, 507 EventMessage aMessage, nsEventStatus* aStatus = nullptr, 508 EventDispatchingCallback* aCallBack = nullptr); 509 510 /** 511 * If IME has already dispatched compositionend event but it was discarded 512 * by PresShell due to not safe to dispatch, this returns true. 513 */ 514 bool WasNativeCompositionEndEventDiscarded() const { 515 return mWasNativeCompositionEndEventDiscarded; 516 } 517 518 /** 519 * OnCompositionEventDiscarded() is called when PresShell discards 520 * compositionupdate, compositionend or compositionchange event due to not 521 * safe to dispatch event. 522 */ 523 void OnCompositionEventDiscarded(WidgetCompositionEvent* aCompositionEvent); 524 525 /** 526 * OnCompositionEventDispatched() is called after a composition event is 527 * dispatched. 528 */ 529 MOZ_CAN_RUN_SCRIPT void OnCompositionEventDispatched( 530 const WidgetCompositionEvent* aDispatchEvent); 531 532 /** 533 * MaybeNotifyIMEOfCompositionEventHandled() notifies IME of composition 534 * event handled. This should be called after dispatching a composition 535 * event which came from widget. 536 */ 537 void MaybeNotifyIMEOfCompositionEventHandled( 538 const WidgetCompositionEvent* aCompositionEvent); 539 540 /** 541 * GetSelectionStartOffset() returns normal selection start offset in the 542 * editor which has this composition. 543 * If it failed or lost focus, this would return 0. 544 */ 545 MOZ_CAN_RUN_SCRIPT uint32_t GetSelectionStartOffset(); 546 547 /** 548 * OnStartOffsetUpdatedInChild() is called when composition start offset 549 * is updated in the child process. I.e., this is called and never called 550 * if the composition is in this process. 551 * @param aStartOffset New composition start offset with native 552 * linebreaks. 553 */ 554 void OnStartOffsetUpdatedInChild(uint32_t aStartOffset); 555 556 /** 557 * CompositionEventDispatcher dispatches the specified composition (or text) 558 * event. 559 */ 560 class CompositionEventDispatcher : public Runnable { 561 public: 562 CompositionEventDispatcher(TextComposition* aTextComposition, 563 nsINode* aEventTarget, 564 EventMessage aEventMessage, 565 const nsAString& aData, 566 bool aIsSynthesizedEvent = false); 567 MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHOD Run() override; 568 569 private: 570 RefPtr<TextComposition> mTextComposition; 571 nsCOMPtr<nsINode> mEventTarget; 572 nsString mData; 573 EventMessage mEventMessage; 574 bool mIsSynthesizedEvent; 575 576 CompositionEventDispatcher() 577 : Runnable("TextComposition::CompositionEventDispatcher"), 578 mEventMessage(eVoidEvent), 579 mIsSynthesizedEvent(false) {}; 580 }; 581 582 /** 583 * DispatchCompositionEventRunnable() dispatches a composition event to the 584 * content. Be aware, if you use this method, nsPresShellEventCB isn't used. 585 * That means that nsIFrame::HandleEvent() is never called. 586 * WARNING: The instance which is managed by IMEStateManager may be 587 * destroyed by this method call. 588 * 589 * @param aEventMessage Must be one of composition events. 590 * @param aData Used for mData value. 591 * @param aIsSynthesizingCommit true if this is called for synthesizing 592 * commit or cancel composition. Otherwise, 593 * false. 594 */ 595 void DispatchCompositionEventRunnable(EventMessage aEventMessage, 596 const nsAString& aData, 597 bool aIsSynthesizingCommit = false); 598 }; 599 600 /** 601 * TextCompositionArray manages the instances of TextComposition class. 602 * Managing with array is enough because only one composition is typically 603 * there. Even if user switches native IME context, it's very rare that 604 * second or more composition is started. 605 * It's assumed that this is used by IMEStateManager for storing all active 606 * compositions in the process. If the instance is it, each TextComposition 607 * in the array can be destroyed by calling some methods of itself. 608 */ 609 610 class TextCompositionArray final 611 : public AutoTArray<RefPtr<TextComposition>, 2> { 612 public: 613 // Looking for per native IME context. 614 index_type IndexOf(const widget::NativeIMEContext& aNativeIMEContext); 615 index_type IndexOf(nsIWidget* aWidget); 616 617 TextComposition* GetCompositionFor(nsIWidget* aWidget); 618 TextComposition* GetCompositionFor( 619 const WidgetCompositionEvent* aCompositionEvent); 620 621 // Looking for per nsPresContext 622 index_type IndexOf(nsPresContext* aPresContext); 623 index_type IndexOf(nsPresContext* aPresContext, nsINode* aNode); 624 625 TextComposition* GetCompositionFor(nsPresContext* aPresContext); 626 TextComposition* GetCompositionFor(nsPresContext* aPresContext, 627 nsINode* aNode); 628 TextComposition* GetCompositionInContent(nsPresContext* aPresContext, 629 nsIContent* aContent); 630 }; 631 632 } // namespace mozilla 633 634 #endif // #ifndef mozilla_TextComposition_h