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 226210 7b196aeab6de7296dee5896f6557cb85cde0a962
parent 226209 a3c0661108138058c16363814ac44855b5fb7d14
child 226211 c7fac3ab77af8edfcd9a7175f6122e63bb98c055
push id28187
push usercbook@mozilla.com
push dateWed, 28 Jan 2015 13:20:48 +0000
treeherdermozilla-central@fc21937ca612 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs917322
milestone38.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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_