LCOV - code coverage report
Current view: top level - widget - TextEventDispatcher.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 40 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 18 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       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/. */
       5             : 
       6             : #ifndef mozilla_textcompositionsynthesizer_h_
       7             : #define mozilla_textcompositionsynthesizer_h_
       8             : 
       9             : #include "mozilla/RefPtr.h"
      10             : #include "nsString.h"
      11             : #include "mozilla/Attributes.h"
      12             : #include "mozilla/EventForwards.h"
      13             : #include "mozilla/TextEventDispatcherListener.h"
      14             : #include "mozilla/TextRange.h"
      15             : #include "mozilla/widget/IMEData.h"
      16             : 
      17             : class nsIWidget;
      18             : 
      19             : namespace mozilla {
      20             : namespace widget {
      21             : 
      22             : /**
      23             :  * TextEventDispatcher is a helper class for dispatching widget events defined
      24             :  * in TextEvents.h.  Currently, this is a helper for dispatching
      25             :  * WidgetCompositionEvent and WidgetKeyboardEvent.  This manages the behavior
      26             :  * of them for conforming to DOM Level 3 Events.
      27             :  * An instance of this class is created by nsIWidget instance and owned by it.
      28             :  * This is typically created only by the top level widgets because only they
      29             :  * handle IME.
      30             :  */
      31             : 
      32             : class TextEventDispatcher final
      33             : {
      34           0 :   ~TextEventDispatcher()
      35           0 :   {
      36           0 :   }
      37             : 
      38           0 :   NS_INLINE_DECL_REFCOUNTING(TextEventDispatcher)
      39             : 
      40             : public:
      41             :   explicit TextEventDispatcher(nsIWidget* aWidget);
      42             : 
      43             :   /**
      44             :    * Initializes the instance for IME or automated test.  Either IME or tests
      45             :    * need to call one of them before starting composition.  If they return
      46             :    * NS_ERROR_ALREADY_INITIALIZED, it means that the listener already listens
      47             :    * notifications from TextEventDispatcher for same purpose (for IME or tests).
      48             :    * If this returns another error, the caller shouldn't keep starting
      49             :    * composition.
      50             :    *
      51             :    * @param aListener       Specify the listener to listen notifications and
      52             :    *                        requests.  This must not be null.
      53             :    *                        NOTE: aListener is stored as weak reference in
      54             :    *                              TextEventDispatcher.  See mListener
      55             :    *                              definition below.
      56             :    */
      57             :   nsresult BeginInputTransaction(TextEventDispatcherListener* aListener);
      58             :   nsresult BeginTestInputTransaction(TextEventDispatcherListener* aListener,
      59             :                                      bool aIsAPZAware);
      60             :   nsresult BeginNativeInputTransaction();
      61             : 
      62             :   /**
      63             :    * EndInputTransaction() should be called when the listener stops using
      64             :    * the TextEventDispatcher.
      65             :    *
      66             :    * @param aListener       The listener using the TextEventDispatcher instance.
      67             :    */
      68             :   void EndInputTransaction(TextEventDispatcherListener* aListener);
      69             : 
      70             :   /**
      71             :    * OnDestroyWidget() is called when mWidget is being destroyed.
      72             :    */
      73             :   void OnDestroyWidget();
      74             : 
      75           0 :   nsIWidget* GetWidget() const { return mWidget; }
      76             : 
      77           0 :   const IMENotificationRequests& IMENotificationRequestsRef() const
      78             :   {
      79           0 :     return mIMENotificationRequests;
      80             :   }
      81             : 
      82             :   /**
      83             :    * GetState() returns current state of this class.
      84             :    *
      85             :    * @return        NS_OK: Fine to compose text.
      86             :    *                NS_ERROR_NOT_INITIALIZED: BeginInputTransaction() or
      87             :    *                                          BeginInputTransactionForTests()
      88             :    *                                          should be called.
      89             :    *                NS_ERROR_NOT_AVAILABLE: The widget isn't available for
      90             :    *                                        composition.
      91             :    */
      92             :   nsresult GetState() const;
      93             : 
      94             :   /**
      95             :    * IsComposing() returns true after calling StartComposition() and before
      96             :    * calling CommitComposition().
      97             :    */
      98           0 :   bool IsComposing() const { return mIsComposing; }
      99             : 
     100             :   /**
     101             :    * IsInNativeInputTransaction() returns true if native IME handler began a
     102             :    * transaction and it's not finished yet.
     103             :    */
     104           0 :   bool IsInNativeInputTransaction() const
     105             :   {
     106           0 :     return mInputTransactionType == eNativeInputTransaction;
     107             :   }
     108             : 
     109             :   /**
     110             :    * IsDispatchingEvent() returns true while this instance dispatching an event.
     111             :    */
     112           0 :   bool IsDispatchingEvent() const { return mDispatchingEvent > 0; }
     113             : 
     114             :   /**
     115             :    * GetPseudoIMEContext() returns pseudo native IME context if there is an
     116             :    * input transaction whose type is not for native event handler.
     117             :    * Otherwise, returns nullptr.
     118             :    */
     119           0 :   void* GetPseudoIMEContext() const
     120             :   {
     121           0 :     if (mInputTransactionType == eNoInputTransaction ||
     122           0 :         mInputTransactionType == eNativeInputTransaction) {
     123           0 :       return nullptr;
     124             :     }
     125           0 :     return const_cast<TextEventDispatcher*>(this);
     126             :   }
     127             : 
     128             :   /**
     129             :    * StartComposition() starts composition explicitly.
     130             :    *
     131             :    * @param aEventTime  If this is not nullptr, WidgetCompositionEvent will
     132             :    *                    be initialized with this.  Otherwise, initialized
     133             :    *                    with the time at initializing.
     134             :    */
     135             :   nsresult StartComposition(nsEventStatus& aStatus,
     136             :                             const WidgetEventTime* aEventTime = nullptr);
     137             : 
     138             :   /**
     139             :    * CommitComposition() commits composition.
     140             :    *
     141             :    * @param aCommitString   If this is null, commits with the last composition
     142             :    *                        string.  Otherwise, commits the composition with
     143             :    *                        this value.
     144             :    * @param aEventTime      If this is not nullptr, WidgetCompositionEvent will
     145             :    *                        be initialized with this.  Otherwise, initialized
     146             :    *                        with the time at initializing.
     147             :    */
     148             :    nsresult CommitComposition(nsEventStatus& aStatus,
     149             :                               const nsAString* aCommitString = nullptr,
     150             :                               const WidgetEventTime* aEventTime = nullptr);
     151             : 
     152             :   /**
     153             :    * SetPendingCompositionString() sets new composition string which will be
     154             :    * dispatched with eCompositionChange event by calling Flush().
     155             :    *
     156             :    * @param aString         New composition string.
     157             :    */
     158           0 :   nsresult SetPendingCompositionString(const nsAString& aString)
     159             :   {
     160           0 :     return mPendingComposition.SetString(aString);
     161             :   }
     162             : 
     163             :   /**
     164             :    * AppendClauseToPendingComposition() appends a clause information to
     165             :    * the pending composition string.
     166             :    *
     167             :    * @param aLength         Length of the clause.
     168             :    * @param aTextRangeType  One of TextRangeType::eRawClause,
     169             :    *                        TextRangeType::eSelectedRawClause,
     170             :    *                        TextRangeType::eConvertedClause or
     171             :    *                        TextRangeType::eSelectedClause.
     172             :    */
     173           0 :   nsresult AppendClauseToPendingComposition(uint32_t aLength,
     174             :                                             TextRangeType aTextRangeType)
     175             :   {
     176           0 :     return mPendingComposition.AppendClause(aLength, aTextRangeType);
     177             :   }
     178             : 
     179             :   /**
     180             :    * SetCaretInPendingComposition() sets caret position in the pending
     181             :    * composition string and its length.  This is optional.  If IME doesn't
     182             :    * want to show caret, it shouldn't need to call this.
     183             :    *
     184             :    * @param aOffset         Offset of the caret in the pending composition
     185             :    *                        string.  This should not be larger than the length
     186             :    *                        of the pending composition string.
     187             :    * @param aLength         Caret width.  If this is 0, caret will be collapsed.
     188             :    *                        Note that Gecko doesn't supported wide caret yet,
     189             :    *                        therefore, this is ignored for now.
     190             :    */
     191           0 :   nsresult SetCaretInPendingComposition(uint32_t aOffset,
     192             :                                         uint32_t aLength)
     193             :   {
     194           0 :     return mPendingComposition.SetCaret(aOffset, aLength);
     195             :   }
     196             : 
     197             :   /**
     198             :    * SetPendingComposition() is useful if native IME handler already creates
     199             :    * array of clauses and/or caret information.
     200             :    *
     201             :    * @param aString         Composition string.  This may include native line
     202             :    *                        breakers since they will be replaced with XP line
     203             :    *                        breakers automatically.
     204             :    * @param aRanges         This should include the ranges of clauses and/or
     205             :    *                        a range of caret.  Note that this method allows
     206             :    *                        some ranges overlap each other and the range order
     207             :    *                        is not from start to end.
     208             :    */
     209           0 :   nsresult SetPendingComposition(const nsAString& aString,
     210             :                                  const TextRangeArray* aRanges)
     211             :   {
     212           0 :     return mPendingComposition.Set(aString, aRanges);
     213             :   }
     214             : 
     215             :   /**
     216             :    * FlushPendingComposition() sends the pending composition string
     217             :    * to the widget of the store DOM window.  Before calling this, IME needs to
     218             :    * set pending composition string with SetPendingCompositionString(),
     219             :    * AppendClauseToPendingComposition() and/or
     220             :    * SetCaretInPendingComposition().
     221             :    *
     222             :    * @param aEventTime      If this is not nullptr, WidgetCompositionEvent will
     223             :    *                        be initialized with this.  Otherwise, initialized
     224             :    *                        with the time at initializing.
     225             :    */
     226           0 :   nsresult FlushPendingComposition(nsEventStatus& aStatus,
     227             :                                    const WidgetEventTime* aEventTime = nullptr)
     228             :   {
     229           0 :     return mPendingComposition.Flush(this, aStatus, aEventTime);
     230             :   }
     231             : 
     232             :   /**
     233             :    * ClearPendingComposition() makes this instance forget pending composition.
     234             :    */
     235           0 :   void ClearPendingComposition()
     236             :   {
     237           0 :     mPendingComposition.Clear();
     238           0 :   }
     239             : 
     240             :   /**
     241             :    * GetPendingCompositionClauses() returns text ranges which was appended by
     242             :    * AppendClauseToPendingComposition() or SetPendingComposition().
     243             :    */
     244             :   const TextRangeArray* GetPendingCompositionClauses() const
     245             :   {
     246             :     return mPendingComposition.GetClauses();
     247             :   }
     248             : 
     249             :   /**
     250             :    * @see nsIWidget::NotifyIME()
     251             :    */
     252             :   nsresult NotifyIME(const IMENotification& aIMENotification);
     253             : 
     254             :   /**
     255             :    * DispatchKeyboardEvent() maybe dispatches aKeyboardEvent.
     256             :    *
     257             :    * @param aMessage        Must be eKeyDown or eKeyUp.
     258             :    *                        Use MaybeDispatchKeypressEvents() for dispatching
     259             :    *                        eKeyPress.
     260             :    * @param aKeyboardEvent  A keyboard event.
     261             :    * @param aStatus         If dispatching event should be marked as consumed,
     262             :    *                        set nsEventStatus_eConsumeNoDefault.  Otherwise,
     263             :    *                        set nsEventStatus_eIgnore.  After dispatching
     264             :    *                        a event and it's consumed this returns
     265             :    *                        nsEventStatus_eConsumeNoDefault.
     266             :    * @param aData           Calling this method may cause calling
     267             :    *                        WillDispatchKeyboardEvent() of the listener.
     268             :    *                        aData will be set to its argument.
     269             :    * @return                true if an event is dispatched.  Otherwise, false.
     270             :    */
     271             :   bool DispatchKeyboardEvent(EventMessage aMessage,
     272             :                              const WidgetKeyboardEvent& aKeyboardEvent,
     273             :                              nsEventStatus& aStatus,
     274             :                              void* aData = nullptr);
     275             : 
     276             :   /**
     277             :    * MaybeDispatchKeypressEvents() maybe dispatches a keypress event which is
     278             :    * generated from aKeydownEvent.
     279             :    *
     280             :    * @param aKeyboardEvent  A keyboard event.
     281             :    * @param aStatus         Sets the result when the caller dispatches
     282             :    *                        aKeyboardEvent.  Note that if the value is
     283             :    *                        nsEventStatus_eConsumeNoDefault, this does NOT
     284             :    *                        dispatch keypress events.
     285             :    *                        When this method dispatches one or more keypress
     286             :    *                        events and one of them is consumed, this returns
     287             :    *                        nsEventStatus_eConsumeNoDefault.
     288             :    * @param aData           Calling this method may cause calling
     289             :    *                        WillDispatchKeyboardEvent() of the listener.
     290             :    *                        aData will be set to its argument.
     291             :    * @param aNeedsCallback  Set true when caller needs to initialize each
     292             :    *                        eKeyPress event immediately before dispatch.
     293             :    *                        Then, WillDispatchKeyboardEvent() is always called.
     294             :    * @return                true if one or more events are dispatched.
     295             :    *                        Otherwise, false.
     296             :    */
     297             :   bool MaybeDispatchKeypressEvents(const WidgetKeyboardEvent& aKeyboardEvent,
     298             :                                    nsEventStatus& aStatus,
     299             :                                    void* aData = nullptr,
     300             :                                    bool aNeedsCallback = false);
     301             : 
     302             : private:
     303             :   // mWidget is owner of the instance.  When this is created, this is set.
     304             :   // And when mWidget is released, this is cleared by OnDestroyWidget().
     305             :   // Note that mWidget may be destroyed already (i.e., mWidget->Destroyed() may
     306             :   // return true).
     307             :   nsIWidget* mWidget;
     308             :   // mListener is a weak reference to TextEventDispatcherListener.  That might
     309             :   // be referred by JS.  Therefore, the listener might be difficult to release
     310             :   // itself if this is a strong reference.  Additionally, it's difficult to
     311             :   // check if a method to uninstall the listener is called by valid instance.
     312             :   // So, using weak reference is the best way in this case.
     313             :   nsWeakPtr mListener;
     314             :   // mIMENotificationRequests should store current IME's notification requests.
     315             :   // So, this may be invalid when IME doesn't have focus.
     316             :   IMENotificationRequests mIMENotificationRequests;
     317             : 
     318             :   // mPendingComposition stores new composition string temporarily.
     319             :   // These values will be used for dispatching eCompositionChange event
     320             :   // in Flush().  When Flush() is called, the members will be cleared
     321             :   // automatically.
     322           0 :   class PendingComposition
     323             :   {
     324             :   public:
     325             :     PendingComposition();
     326             :     nsresult SetString(const nsAString& aString);
     327             :     nsresult AppendClause(uint32_t aLength, TextRangeType aTextRangeType);
     328             :     nsresult SetCaret(uint32_t aOffset, uint32_t aLength);
     329             :     nsresult Set(const nsAString& aString, const TextRangeArray* aRanges);
     330             :     nsresult Flush(TextEventDispatcher* aDispatcher,
     331             :                    nsEventStatus& aStatus,
     332             :                    const WidgetEventTime* aEventTime);
     333             :     const TextRangeArray* GetClauses() const { return mClauses; }
     334             :     void Clear();
     335             : 
     336             :   private:
     337             :     nsString mString;
     338             :     RefPtr<TextRangeArray> mClauses;
     339             :     TextRange mCaret;
     340             :     bool mReplacedNativeLineBreakers;
     341             : 
     342             :     void EnsureClauseArray();
     343             : 
     344             :     /**
     345             :      * ReplaceNativeLineBreakers() replaces "\r\n" and "\r" to "\n" and adjust
     346             :      * each clause information and the caret information.
     347             :      */
     348             :     void ReplaceNativeLineBreakers();
     349             : 
     350             :     /**
     351             :      * AdjustRange() adjusts aRange as in the string with XP line breakers.
     352             :      *
     353             :      * @param aRange            The reference to a range in aNativeString.
     354             :      *                          This will be modified.
     355             :      * @param aNativeString     The string with native line breakers.
     356             :      *                          This may include "\r\n" and/or "\r".
     357             :      */
     358             :     static void AdjustRange(TextRange& aRange, const nsAString& aNativeString);
     359             :   };
     360             :   PendingComposition mPendingComposition;
     361             : 
     362             :   // While dispatching an event, this is incremented.
     363             :   uint16_t mDispatchingEvent;
     364             : 
     365             :   enum InputTransactionType : uint8_t
     366             :   {
     367             :     // No input transaction has been started.
     368             :     eNoInputTransaction,
     369             :     // Input transaction for native IME or keyboard event handler.  Note that
     370             :     // keyboard events may be dispatched via parent process if there is.
     371             :     eNativeInputTransaction,
     372             :     // Input transaction for automated tests which are APZ-aware.  Note that
     373             :     // keyboard events may be dispatched via parent process if there is.
     374             :     eAsyncTestInputTransaction,
     375             :     // Input transaction for automated tests which assume events are fired
     376             :     // synchronously.  I.e., keyboard events are always dispatched in the
     377             :     // current process.
     378             :     eSameProcessSyncTestInputTransaction,
     379             :     // Input transaction for Others (must be IME on B2G).  Events are fired
     380             :     // synchronously because TextInputProcessor which is the only user of
     381             :     // this input transaction type supports only keyboard apps on B2G.
     382             :     // Keyboard apps on B2G doesn't want to dispatch keyboard events to
     383             :     // chrome process. Therefore, this should dispatch key events only in
     384             :     // the current process.
     385             :     eSameProcessSyncInputTransaction
     386             :   };
     387             : 
     388             :   InputTransactionType mInputTransactionType;
     389             : 
     390           0 :   bool IsForTests() const
     391             :   {
     392           0 :     return mInputTransactionType == eAsyncTestInputTransaction ||
     393           0 :            mInputTransactionType == eSameProcessSyncTestInputTransaction;
     394             :   }
     395             : 
     396             :   // ShouldSendInputEventToAPZ() returns true when WidgetInputEvent should
     397             :   // be dispatched via its parent process (if there is) for APZ.  Otherwise,
     398             :   // when the input transaction is for IME of B2G or automated tests which
     399             :   // isn't APZ-aware, WidgetInputEvent should be dispatched form current
     400             :   // process directly.
     401           0 :   bool ShouldSendInputEventToAPZ() const
     402             :   {
     403           0 :     switch (mInputTransactionType) {
     404             :       case eNativeInputTransaction:
     405             :       case eAsyncTestInputTransaction:
     406           0 :         return true;
     407             :       case eSameProcessSyncTestInputTransaction:
     408             :       case eSameProcessSyncInputTransaction:
     409           0 :         return false;
     410             :       case eNoInputTransaction:
     411             :         NS_WARNING("Why does the caller need to dispatch an event when "
     412           0 :                    "there is no input transaction?");
     413           0 :         return true;
     414             :       default:
     415           0 :         MOZ_CRASH("Define the behavior of new InputTransactionType");
     416             :     }
     417             :   }
     418             : 
     419             :   // See IsComposing().
     420             :   bool mIsComposing;
     421             : 
     422             :   // true while NOTIFY_IME_OF_FOCUS is received but NOTIFY_IME_OF_BLUR has not
     423             :   // received yet.  Otherwise, false.
     424             :   bool mHasFocus;
     425             : 
     426             :   // If this is true, keydown and keyup events are dispatched even when there
     427             :   // is a composition.
     428             :   static bool sDispatchKeyEventsDuringComposition;
     429             : 
     430             :   nsresult BeginInputTransactionInternal(
     431             :              TextEventDispatcherListener* aListener,
     432             :              InputTransactionType aType);
     433             : 
     434             :   /**
     435             :    * InitEvent() initializes aEvent.  This must be called before dispatching
     436             :    * the event.
     437             :    */
     438             :   void InitEvent(WidgetGUIEvent& aEvent) const;
     439             : 
     440             : 
     441             :   /**
     442             :    * DispatchEvent() dispatches aEvent on aWidget.
     443             :    */
     444             :   nsresult DispatchEvent(nsIWidget* aWidget,
     445             :                          WidgetGUIEvent& aEvent,
     446             :                          nsEventStatus& aStatus);
     447             : 
     448             :   /**
     449             :    * DispatchInputEvent() dispatches aEvent on aWidget.
     450             :    */
     451             :   nsresult DispatchInputEvent(nsIWidget* aWidget,
     452             :                               WidgetInputEvent& aEvent,
     453             :                               nsEventStatus& aStatus);
     454             : 
     455             :   /**
     456             :    * StartCompositionAutomaticallyIfNecessary() starts composition if it hasn't
     457             :    * been started it yet.
     458             :    *
     459             :    * @param aStatus         If it succeeded to start composition normally, this
     460             :    *                        returns nsEventStatus_eIgnore.  Otherwise, e.g.,
     461             :    *                        the composition is canceled during dispatching
     462             :    *                        compositionstart event, this returns
     463             :    *                        nsEventStatus_eConsumeNoDefault.  In this case,
     464             :    *                        the caller shouldn't keep doing its job.
     465             :    * @param aEventTime      If this is not nullptr, WidgetCompositionEvent will
     466             :    *                        be initialized with this.  Otherwise, initialized
     467             :    *                        with the time at initializing.
     468             :    * @return                Only when something unexpected occurs, this returns
     469             :    *                        an error.  Otherwise, returns NS_OK even if aStatus
     470             :    *                        is nsEventStatus_eConsumeNoDefault.
     471             :    */
     472             :   nsresult StartCompositionAutomaticallyIfNecessary(
     473             :              nsEventStatus& aStatus,
     474             :              const WidgetEventTime* aEventTime);
     475             : 
     476             :   /**
     477             :    * DispatchKeyboardEventInternal() maybe dispatches aKeyboardEvent.
     478             :    *
     479             :    * @param aMessage        Must be eKeyDown, eKeyUp or eKeyPress.
     480             :    * @param aKeyboardEvent  A keyboard event.  If aMessage is eKeyPress and
     481             :    *                        the event is for second or later character, its
     482             :    *                        mKeyValue should be empty string.
     483             :    * @param aStatus         If dispatching event should be marked as consumed,
     484             :    *                        set nsEventStatus_eConsumeNoDefault.  Otherwise,
     485             :    *                        set nsEventStatus_eIgnore.  After dispatching
     486             :    *                        a event and it's consumed this returns
     487             :    *                        nsEventStatus_eConsumeNoDefault.
     488             :    * @param aData           Calling this method may cause calling
     489             :    *                        WillDispatchKeyboardEvent() of the listener.
     490             :    *                        aData will be set to its argument.
     491             :    * @param aIndexOfKeypress    This must be 0 if aMessage isn't eKeyPress or
     492             :    *                            aKeyboard.mKeyNameIndex isn't
     493             :    *                            KEY_NAME_INDEX_USE_STRING.  Otherwise, i.e.,
     494             :    *                            when an eKeyPress event causes inputting
     495             :    *                            text, this must be between 0 and
     496             :    *                            mKeyValue.Length() - 1 since keypress events
     497             :    *                            sending only one character per event.
     498             :    * @param aNeedsCallback  Set true when caller needs to initialize each
     499             :    *                        eKeyPress event immediately before dispatch.
     500             :    *                        Then, WillDispatchKeyboardEvent() is always called.
     501             :    * @return                true if an event is dispatched.  Otherwise, false.
     502             :    */
     503             :   bool DispatchKeyboardEventInternal(EventMessage aMessage,
     504             :                                      const WidgetKeyboardEvent& aKeyboardEvent,
     505             :                                      nsEventStatus& aStatus,
     506             :                                      void* aData,
     507             :                                      uint32_t aIndexOfKeypress = 0,
     508             :                                      bool aNeedsCallback = false);
     509             : 
     510             :   /**
     511             :    * ClearNotificationRequests() clears mIMENotificationRequests.
     512             :    */
     513             :   void ClearNotificationRequests();
     514             : 
     515             :   /**
     516             :    * UpdateNotificationRequests() updates mIMENotificationRequests with
     517             :    * current state.  If the instance doesn't have focus, this clears
     518             :    * mIMENotificationRequests.  Otherwise, updates it with both requests of
     519             :    * current listener and native listener.
     520             :    */
     521             :   void UpdateNotificationRequests();
     522             : };
     523             : 
     524             : } // namespace widget
     525             : } // namespace mozilla
     526             : 
     527             : #endif // #ifndef mozilla_widget_textcompositionsynthesizer_h_

Generated by: LCOV version 1.13