Bug 917322 part.4 Create utility methods of TextEventDispatcher r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 28 Jan 2015 15:27:31 +0900
changeset 239575 7b196aeab6de7296dee5896f6557cb85cde0a962
parent 239574 a3c0661108138058c16363814ac44855b5fb7d14
child 239576 c7fac3ab77af8edfcd9a7175f6122e63bb98c055
push id500
push userjoshua.m.grant@gmail.com
push dateThu, 29 Jan 2015 01:48:36 +0000
reviewerssmaug
bugs917322
milestone38.0a1
Bug 917322 part.4 Create utility methods of TextEventDispatcher r=smaug
dom/base/nsDOMWindowUtils.cpp
widget/TextEventDispatcher.cpp
widget/TextEventDispatcher.h
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -2201,18 +2201,22 @@ nsDOMWindowUtils::CreateCompositionStrin
 
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
 
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (NS_WARN_IF(!widget)) {
     return NS_ERROR_FAILURE;
   }
   nsRefPtr<TextEventDispatcher> dispatcher(widget->GetTextEventDispatcher());
-  // XXX Ignore the result of InitForTest() for now.
-  dispatcher->InitForTests();
+  nsresult rv = dispatcher->GetState();
+  if (rv == NS_ERROR_NOT_INITIALIZED) {
+    dispatcher->InitForTests();
+  } else if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
   NS_ADDREF(*aResult = new CompositionStringSynthesizer(dispatcher));
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::SendQueryContentEvent(uint32_t aType,
                                         uint32_t aOffset, uint32_t aLength,
                                         int32_t aX, int32_t aY,
--- a/widget/TextEventDispatcher.cpp
+++ b/widget/TextEventDispatcher.cpp
@@ -51,16 +51,35 @@ TextEventDispatcher::InitForTests()
 
 void
 TextEventDispatcher::OnDestroyWidget()
 {
   mWidget = nullptr;
   mPendingComposition.Clear();
 }
 
+nsresult
+TextEventDispatcher::GetState() const
+{
+  if (!mInitialized) {
+    return NS_ERROR_NOT_INITIALIZED;
+  }
+  if (!mWidget || mWidget->Destroyed()) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+  return NS_OK;
+}
+
+void
+TextEventDispatcher::InitEvent(WidgetCompositionEvent& aEvent) const
+{
+  aEvent.time = PR_IntervalNow();
+  aEvent.mFlags.mIsSynthesizedForTests = mForTests;
+}
+
 /******************************************************************************
  * TextEventDispatcher::PendingComposition
  *****************************************************************************/
 
 TextEventDispatcher::PendingComposition::PendingComposition()
 {
   Clear();
 }
@@ -128,23 +147,19 @@ TextEventDispatcher::PendingComposition:
 
 nsresult
 TextEventDispatcher::PendingComposition::Flush(
                        const TextEventDispatcher* aDispatcher,
                        nsEventStatus& aStatus)
 {
   aStatus = nsEventStatus_eIgnore;
 
-  if (NS_WARN_IF(!aDispatcher->mInitialized)) {
-    return NS_ERROR_NOT_INITIALIZED;
-  }
-
-  nsCOMPtr<nsIWidget> widget(aDispatcher->mWidget);
-  if (NS_WARN_IF(!widget || widget->Destroyed())) {
-    return NS_ERROR_NOT_AVAILABLE;
+  nsresult rv = aDispatcher->GetState();
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
   }
 
   if (mClauses && !mClauses->IsEmpty() &&
       mClauses->LastElement().mEndOffset != mString.Length()) {
     NS_WARNING("Sum of length of the all clauses must be same as the string "
                "length");
     Clear();
     return NS_ERROR_ILLEGAL_VALUE;
@@ -154,32 +169,31 @@ TextEventDispatcher::PendingComposition:
       NS_WARNING("Caret position is out of the composition string");
       Clear();
       return NS_ERROR_ILLEGAL_VALUE;
     }
     EnsureClauseArray();
     mClauses->AppendElement(mCaret);
   }
 
+  nsCOMPtr<nsIWidget> widget(aDispatcher->mWidget);
   WidgetCompositionEvent compChangeEvent(true, NS_COMPOSITION_CHANGE, widget);
-  compChangeEvent.time = PR_IntervalNow();
+  aDispatcher->InitEvent(compChangeEvent);
   compChangeEvent.mData = mString;
   if (mClauses) {
     MOZ_ASSERT(!mClauses->IsEmpty(),
                "mClauses must be non-empty array when it's not nullptr");
     compChangeEvent.mRanges = mClauses;
   }
 
-  compChangeEvent.mFlags.mIsSynthesizedForTests = aDispatcher->mForTests;
-
   // While this method dispatches a composition event, some other event handler
   // cause more clauses to be added.  So, we should clear pending composition
   // before dispatching the event.
   Clear();
-  nsresult rv = widget->DispatchEvent(&compChangeEvent, aStatus);
+  rv = widget->DispatchEvent(&compChangeEvent, aStatus);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   return NS_OK;
 }
 
 } // namespace widget
--- a/widget/TextEventDispatcher.h
+++ b/widget/TextEventDispatcher.h
@@ -48,16 +48,27 @@ public:
   nsresult InitForTests();
 
   /**
    * OnDestroyWidget() is called when mWidget is being destroyed.
    */
   void OnDestroyWidget();
 
   /**
+   * GetState() returns current state of this class.
+   *
+   * @return        NS_OK: Fine to compose text.
+   *                NS_ERROR_NOT_INITIALIZED: Init() or InitForTests() should
+   *                                          be called.
+   *                NS_ERROR_NOT_AVAILABLE: The widget isn't available for
+   *                                        composition.
+   */
+  nsresult GetState() const;
+
+  /**
    * SetPendingCompositionString() sets new composition string which will be
    * dispatched with NS_COMPOSITION_CHANGE event by calling Flush().
    *
    * @param aString         New composition string.
    */
   nsresult SetPendingCompositionString(const nsAString& aString)
   {
     return mPendingComposition.SetString(aString);
@@ -137,14 +148,20 @@ private:
     TextRange mCaret;
 
     void EnsureClauseArray();
   };
   PendingComposition mPendingComposition;
 
   bool mInitialized;
   bool mForTests;
+
+  /**
+   * InitEvent() initializes aEvent.  This must be called before dispatching
+   * the event.
+   */
+  void InitEvent(WidgetCompositionEvent& aEvent) const;
 };
 
 } // namespace widget
 } // namespace mozilla
 
 #endif // #ifndef mozilla_widget_textcompositionsynthesizer_h_