Bug 1172466 part.1 Make helper classes to notify IME nested classes of IMEContentObserver r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 17 Jun 2015 10:03:57 +0900
changeset 267386 c215b9a30b7395a9db4c527992c23ab45f5021e9
parent 267385 9345403c76288e468409cc12411f8ce16ed1a630
child 267387 83a659053a5239769f32ddaa3ac214b11af2c07c
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-esr52@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1172466
milestone41.0a1
Bug 1172466 part.1 Make helper classes to notify IME nested classes of IMEContentObserver r=smaug
dom/events/IMEContentObserver.cpp
dom/events/IMEContentObserver.h
--- a/dom/events/IMEContentObserver.cpp
+++ b/dom/events/IMEContentObserver.cpp
@@ -25,24 +25,27 @@
 #include "nsIFrame.h"
 #include "nsINode.h"
 #include "nsIPresShell.h"
 #include "nsISelectionController.h"
 #include "nsISelectionPrivate.h"
 #include "nsISupports.h"
 #include "nsIWidget.h"
 #include "nsPresContext.h"
-#include "nsThreadUtils.h"
 #include "nsWeakReference.h"
 #include "WritingModes.h"
 
 namespace mozilla {
 
 using namespace widget;
 
+/******************************************************************************
+ * mozilla::IMEContentObserver
+ ******************************************************************************/
+
 NS_IMPL_CYCLE_COLLECTION_CLASS(IMEContentObserver)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IMEContentObserver)
   nsAutoScriptBlocker scriptBlocker;
 
   tmp->NotifyIMEOfBlur();
   tmp->UnregisterObservers();
 
@@ -379,71 +382,16 @@ IMEContentObserver::GetSelectionAndRoot(
   }
 
   NS_ASSERTION(mSelection && mRootContent, "uninitialized content observer");
   NS_ADDREF(*aSelection = mSelection);
   NS_ADDREF(*aRootContent = mRootContent);
   return NS_OK;
 }
 
-// Helper class, used for selection change notification
-class SelectionChangeEvent : public nsRunnable
-{
-public:
-  SelectionChangeEvent(IMEContentObserver* aDispatcher,
-                       bool aCausedByComposition)
-    : mDispatcher(aDispatcher)
-    , mCausedByComposition(aCausedByComposition)
-  {
-    MOZ_ASSERT(mDispatcher);
-  }
-
-  NS_IMETHOD Run()
-  {
-    nsCOMPtr<nsIWidget> widget = mDispatcher->GetWidget();
-    nsPresContext* presContext = mDispatcher->GetPresContext();
-    if (!widget || !presContext) {
-      return NS_OK;
-    }
-
-    // XXX Cannot we cache some information for reducing the cost to compute
-    //     selection offset and writing mode?
-    WidgetQueryContentEvent selection(true, NS_QUERY_SELECTED_TEXT, widget);
-    ContentEventHandler handler(presContext);
-    handler.OnQuerySelectedText(&selection);
-    if (NS_WARN_IF(!selection.mSucceeded)) {
-      return NS_OK;
-    }
-
-    // The widget might be destroyed during querying the content since it
-    // causes flushing layout.
-    widget = mDispatcher->GetWidget();
-    if (!widget || NS_WARN_IF(widget->Destroyed())) {
-      return NS_OK;
-    }
-
-    IMENotification notification(NOTIFY_IME_OF_SELECTION_CHANGE);
-    notification.mSelectionChangeData.mOffset =
-      selection.mReply.mOffset;
-    notification.mSelectionChangeData.mLength =
-      selection.mReply.mString.Length();
-    notification.mSelectionChangeData.SetWritingMode(
-                                        selection.GetWritingMode());
-    notification.mSelectionChangeData.mReversed = selection.mReply.mReversed;
-    notification.mSelectionChangeData.mCausedByComposition =
-      mCausedByComposition;
-    widget->NotifyIME(notification);
-    return NS_OK;
-  }
-
-private:
-  nsRefPtr<IMEContentObserver> mDispatcher;
-  bool mCausedByComposition;
-};
-
 nsresult
 IMEContentObserver::NotifySelectionChanged(nsIDOMDocument* aDOMDocument,
                                            nsISelection* aSelection,
                                            int16_t aReason)
 {
   bool causedByComposition = IsEditorHandlingEventForComposition();
   if (causedByComposition &&
       !mUpdatePreference.WantChangesCausedByComposition()) {
@@ -454,39 +402,16 @@ IMEContentObserver::NotifySelectionChang
   nsresult rv = aSelection->GetRangeCount(&count);
   NS_ENSURE_SUCCESS(rv, rv);
   if (count > 0 && mWidget) {
     MaybeNotifyIMEOfSelectionChange(causedByComposition);
   }
   return NS_OK;
 }
 
-// Helper class, used for position change notification
-class PositionChangeEvent final : public nsRunnable
-{
-public:
-  explicit PositionChangeEvent(IMEContentObserver* aDispatcher)
-    : mDispatcher(aDispatcher)
-  {
-    MOZ_ASSERT(mDispatcher);
-  }
-
-  NS_IMETHOD Run()
-  {
-    if (mDispatcher->GetWidget()) {
-      mDispatcher->GetWidget()->NotifyIME(
-        IMENotification(NOTIFY_IME_OF_POSITION_CHANGE));
-    }
-    return NS_OK;
-  }
-
-private:
-  nsRefPtr<IMEContentObserver> mDispatcher;
-};
-
 void
 IMEContentObserver::ScrollPositionChanged()
 {
   MaybeNotifyIMEOfPositionChange();
 }
 
 NS_IMETHODIMP
 IMEContentObserver::Reflow(DOMHighResTimeStamp aStart,
@@ -577,50 +502,16 @@ IMEContentObserver::OnMouseButtonEvent(n
     return false;
   }
 
   bool consumed = (rv == NS_SUCCESS_EVENT_CONSUMED);
   aMouseEvent->mFlags.mDefaultPrevented = consumed;
   return consumed;
 }
 
-// Helper class, used for text change notification
-class TextChangeEvent : public nsRunnable
-{
-public:
-  TextChangeEvent(IMEContentObserver* aDispatcher,
-                  IMEContentObserver::TextChangeData& aData)
-    : mDispatcher(aDispatcher)
-    , mData(aData)
-  {
-    MOZ_ASSERT(mDispatcher);
-    MOZ_ASSERT(mData.mStored);
-    // Reset mStored because this now consumes the data.
-    aData.mStored = false;
-  }
-
-  NS_IMETHOD Run()
-  {
-    if (mDispatcher->GetWidget()) {
-      IMENotification notification(NOTIFY_IME_OF_TEXT_CHANGE);
-      notification.mTextChangeData.mStartOffset = mData.mStartOffset;
-      notification.mTextChangeData.mOldEndOffset = mData.mRemovedEndOffset;
-      notification.mTextChangeData.mNewEndOffset = mData.mAddedEndOffset;
-      notification.mTextChangeData.mCausedByComposition =
-        mData.mCausedOnlyByComposition;
-      mDispatcher->GetWidget()->NotifyIME(notification);
-    }
-    return NS_OK;
-  }
-
-private:
-  nsRefPtr<IMEContentObserver> mDispatcher;
-  IMEContentObserver::TextChangeData mData;
-};
-
 void
 IMEContentObserver::StoreTextChangeData(const TextChangeData& aTextChangeData)
 {
   MOZ_ASSERT(aTextChangeData.mStartOffset <= aTextChangeData.mRemovedEndOffset,
              "end of removed text must be same or larger than start");
   MOZ_ASSERT(aTextChangeData.mStartOffset <= aTextChangeData.mAddedEndOffset,
              "end of added text must be same or larger than start");
 
@@ -1114,35 +1005,16 @@ IMEContentObserver::MaybeNotifyIMEOfSele
 
 void
 IMEContentObserver::MaybeNotifyIMEOfPositionChange()
 {
   mIsPositionChangeEventPending = true;
   FlushMergeableNotifications();
 }
 
-class AsyncMergeableNotificationsFlusher : public nsRunnable
-{
-public:
-  explicit AsyncMergeableNotificationsFlusher(IMEContentObserver* aIMEContentObserver)
-    : mIMEContentObserver(aIMEContentObserver)
-  {
-    MOZ_ASSERT(mIMEContentObserver);
-  }
-
-  NS_IMETHOD Run()
-  {
-    mIMEContentObserver->FlushMergeableNotifications();
-    return NS_OK;
-  }
-
-private:
-  nsRefPtr<IMEContentObserver> mIMEContentObserver;
-};
-
 void
 IMEContentObserver::FlushMergeableNotifications()
 {
   // If this is already detached from the widget, this doesn't need to notify
   // anything.
   if (!mWidget) {
     return;
   }
@@ -1649,9 +1521,97 @@ IMEContentObserver::TestMergingTextChang
     "text");
   MOZ_ASSERT(mTextChangeData.mAddedEndOffset == 82, // 70 + (36 - 24)
     "Test 6-4-3: mAddedEndOffset should be the first end of added text without "
     "removed text length by the new change");
   mTextChangeData.mStored = false;
 }
 #endif // #ifdef DEBUG
 
+/******************************************************************************
+ * mozilla::IMEContentObserver::SelectionChangeEvent
+ ******************************************************************************/
+
+NS_IMETHODIMP
+IMEContentObserver::SelectionChangeEvent::Run()
+{
+  nsCOMPtr<nsIWidget> widget = mIMEContentObserver->mWidget;
+  nsPresContext* presContext = mIMEContentObserver->GetPresContext();
+  if (!widget || !presContext) {
+    return NS_OK;
+  }
+
+  // XXX Cannot we cache some information for reducing the cost to compute
+  //     selection offset and writing mode?
+  WidgetQueryContentEvent selection(true, NS_QUERY_SELECTED_TEXT, widget);
+  ContentEventHandler handler(presContext);
+  handler.OnQuerySelectedText(&selection);
+  if (NS_WARN_IF(!selection.mSucceeded)) {
+    return NS_OK;
+  }
+
+  // The widget might be destroyed during querying the content since it
+  // causes flushing layout.
+  widget = mIMEContentObserver->mWidget;
+  if (!widget || NS_WARN_IF(widget->Destroyed())) {
+    return NS_OK;
+  }
+
+  IMENotification notification(NOTIFY_IME_OF_SELECTION_CHANGE);
+  notification.mSelectionChangeData.mOffset =
+    selection.mReply.mOffset;
+  notification.mSelectionChangeData.mLength =
+    selection.mReply.mString.Length();
+  notification.mSelectionChangeData.SetWritingMode(
+                                      selection.GetWritingMode());
+  notification.mSelectionChangeData.mReversed = selection.mReply.mReversed;
+  notification.mSelectionChangeData.mCausedByComposition =
+    mCausedByComposition;
+  widget->NotifyIME(notification);
+  return NS_OK;
+}
+
+/******************************************************************************
+ * mozilla::IMEContentObserver::TextChangeEvent
+ ******************************************************************************/
+
+NS_IMETHODIMP
+IMEContentObserver::TextChangeEvent::Run()
+{
+  if (!mIMEContentObserver->mWidget) {
+    return NS_OK;
+  }
+  IMENotification notification(NOTIFY_IME_OF_TEXT_CHANGE);
+  notification.mTextChangeData.mStartOffset = mData.mStartOffset;
+  notification.mTextChangeData.mOldEndOffset = mData.mRemovedEndOffset;
+  notification.mTextChangeData.mNewEndOffset = mData.mAddedEndOffset;
+  notification.mTextChangeData.mCausedByComposition =
+    mData.mCausedOnlyByComposition;
+  mIMEContentObserver->mWidget->NotifyIME(notification);
+  return NS_OK;
+}
+
+/******************************************************************************
+ * mozilla::IMEContentObserver::PositionChangeEvent
+ ******************************************************************************/
+
+NS_IMETHODIMP
+IMEContentObserver::PositionChangeEvent::Run()
+{
+  if (mIMEContentObserver->mWidget) {
+    mIMEContentObserver->mWidget->NotifyIME(
+      IMENotification(NOTIFY_IME_OF_POSITION_CHANGE));
+  }
+  return NS_OK;
+}
+
+/******************************************************************************
+ * mozilla::IMEContentObserver::AsyncMergeableNotificationsFlusher
+ ******************************************************************************/
+
+NS_IMETHODIMP
+IMEContentObserver::AsyncMergeableNotificationsFlusher::Run()
+{
+  mIMEContentObserver->FlushMergeableNotifications();
+  return NS_OK;
+}
+
 } // namespace mozilla
--- a/dom/events/IMEContentObserver.h
+++ b/dom/events/IMEContentObserver.h
@@ -13,16 +13,17 @@
 #include "nsIDocShell.h" // XXX Why does only this need to be included here?
 #include "nsIEditor.h"
 #include "nsIEditorObserver.h"
 #include "nsIReflowObserver.h"
 #include "nsISelectionListener.h"
 #include "nsIScrollObserver.h"
 #include "nsIWidget.h" // for nsIMEUpdatePreference
 #include "nsStubMutationObserver.h"
+#include "nsThreadUtils.h"
 #include "nsWeakReference.h"
 
 class nsIContent;
 class nsINode;
 class nsISelection;
 class nsPresContext;
 
 namespace mozilla {
@@ -33,18 +34,16 @@ class EventStateManager;
 // in the currently focused editor
 class IMEContentObserver final : public nsISelectionListener
                                , public nsStubMutationObserver
                                , public nsIReflowObserver
                                , public nsIScrollObserver
                                , public nsSupportsWeakReference
                                , public nsIEditorObserver
 {
-  friend class AsyncMergeableNotificationsFlusher;
-
 public:
   IMEContentObserver();
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(IMEContentObserver,
                                            nsISelectionListener)
   NS_DECL_NSIEDITOROBSERVER
   NS_DECL_NSISELECTIONLISTENER
@@ -253,13 +252,84 @@ private:
   uint32_t mSuppressNotifications;
   int64_t mPreCharacterDataChangeLength;
 
   bool mIsObserving;
   bool mIsSelectionChangeEventPending;
   bool mSelectionChangeCausedOnlyByComposition;
   bool mIsPositionChangeEventPending;
   bool mIsFlushingPendingNotifications;
+
+
+  /**
+   * Helper classes to notify IME.
+   */
+
+  class SelectionChangeEvent : public nsRunnable
+  {
+  public:
+    SelectionChangeEvent(IMEContentObserver* aIMEContentObserver,
+                         bool aCausedByComposition)
+      : mIMEContentObserver(aIMEContentObserver)
+      , mCausedByComposition(aCausedByComposition)
+    {
+      MOZ_ASSERT(mIMEContentObserver);
+    }
+    NS_IMETHOD Run() override;
+
+  private:
+    nsRefPtr<IMEContentObserver> mIMEContentObserver;
+    bool mCausedByComposition;
+  };
+
+  class TextChangeEvent : public nsRunnable
+  {
+  public:
+    TextChangeEvent(IMEContentObserver* aIMEContentObserver,
+                    TextChangeData& aData)
+      : mIMEContentObserver(aIMEContentObserver)
+      , mData(aData)
+    {
+      MOZ_ASSERT(mIMEContentObserver);
+      MOZ_ASSERT(mData.mStored);
+      // Reset mStored because this now consumes the data.
+      aData.mStored = false;
+    }
+    NS_IMETHOD Run() override;
+
+  private:
+    nsRefPtr<IMEContentObserver> mIMEContentObserver;
+    TextChangeData mData;
+  };
+
+  class PositionChangeEvent final : public nsRunnable
+  {
+  public:
+    explicit PositionChangeEvent(IMEContentObserver* aIMEContentObserver)
+      : mIMEContentObserver(aIMEContentObserver)
+    {
+      MOZ_ASSERT(mIMEContentObserver);
+    }
+    NS_IMETHOD Run() override;
+
+  private:
+    nsRefPtr<IMEContentObserver> mIMEContentObserver;
+  };
+
+  class AsyncMergeableNotificationsFlusher : public nsRunnable
+  {
+  public:
+    explicit AsyncMergeableNotificationsFlusher(
+      IMEContentObserver* aIMEContentObserver)
+      : mIMEContentObserver(aIMEContentObserver)
+    {
+      MOZ_ASSERT(mIMEContentObserver);
+    }
+    NS_IMETHOD Run() override;
+
+  private:
+    nsRefPtr<IMEContentObserver> mIMEContentObserver;
+  };
 };
 
 } // namespace mozilla
 
 #endif // mozilla_IMEContentObserver_h_