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 249293 c215b9a30b7395a9db4c527992c23ab45f5021e9
parent 249292 9345403c76288e468409cc12411f8ce16ed1a630
child 249294 83a659053a5239769f32ddaa3ac214b11af2c07c
push id28923
push userryanvm@gmail.com
push dateWed, 17 Jun 2015 18:57:11 +0000
treeherdermozilla-central@099d6cd6725e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1172466
milestone41.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 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_