Bug 1166436 part.2 mozilla::ContentCache should store a selection range and TabParent should use it r=m_kato
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 05 Jun 2015 18:28:19 +0900
changeset 247317 c152e396e9c3592c7fac82ceb946188304bb6f01
parent 247316 7082d6cfb3718e624d844226c0dbfb89e07ed4dc
child 247318 a4b5f272f88aa00d8a10c2a959bed1de99eba29d
push id60677
push usermasayuki@d-toybox.com
push dateFri, 05 Jun 2015 09:28:37 +0000
treeherdermozilla-inbound@cbaeacbb9700 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato
bugs1166436
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 1166436 part.2 mozilla::ContentCache should store a selection range and TabParent should use it r=m_kato
dom/ipc/TabParent.cpp
dom/ipc/TabParent.h
widget/ContentCache.cpp
widget/ContentCache.h
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -256,18 +256,16 @@ NS_IMPL_ISUPPORTS(TabParent,
                   nsISupportsWeakReference)
 
 TabParent::TabParent(nsIContentParent* aManager,
                      const TabId& aTabId,
                      const TabContext& aContext,
                      uint32_t aChromeFlags)
   : TabContext(aContext)
   , mFrameElement(nullptr)
-  , mIMESelectionAnchor(0)
-  , mIMESelectionFocus(0)
   , mWritingMode()
   , mIMEComposing(false)
   , mIMECompositionEnding(false)
   , mIMEEventCountAfterEnding(0)
   , mIMECompositionStart(0)
   , mIMECompositionRectOffset(0)
   , mRect(0, 0, 0, 0)
   , mDimensions(0, 0)
@@ -1893,18 +1891,17 @@ TabParent::RecvNotifyIMEFocus(const bool
 {
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget) {
     *aPreference = nsIMEUpdatePreference();
     return true;
   }
 
   mIMETabParent = aFocus ? this : nullptr;
-  mIMESelectionAnchor = 0;
-  mIMESelectionFocus = 0;
+  mContentCache.SetSelection(0);
   widget->NotifyIME(IMENotification(aFocus ? NOTIFY_IME_OF_FOCUS :
                                              NOTIFY_IME_OF_BLUR));
 
   if (aFocus) {
     *aPreference = widget->GetIMEUpdatePreference();
   } else {
     mContentCache.Clear();
   }
@@ -1965,33 +1962,28 @@ TabParent::RecvNotifyIMESelection(const 
                                   const uint32_t& aFocus,
                                   const mozilla::WritingMode& aWritingMode,
                                   const bool& aCausedByComposition)
 {
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget)
     return true;
 
-  mIMESelectionAnchor = aAnchor;
-  mIMESelectionFocus = aFocus;
+  mContentCache.SetSelection(aAnchor, aFocus);
   mWritingMode = aWritingMode;
   const nsIMEUpdatePreference updatePreference =
     widget->GetIMEUpdatePreference();
   if (updatePreference.WantSelectionChange() &&
       (updatePreference.WantChangesCausedByComposition() ||
        !aCausedByComposition)) {
     IMENotification notification(NOTIFY_IME_OF_SELECTION_CHANGE);
-    notification.mSelectionChangeData.mOffset =
-      std::min(mIMESelectionAnchor, mIMESelectionFocus);
-    notification.mSelectionChangeData.mLength =
-      mIMESelectionAnchor > mIMESelectionFocus ?
-        mIMESelectionAnchor - mIMESelectionFocus :
-        mIMESelectionFocus - mIMESelectionAnchor;
+    notification.mSelectionChangeData.mOffset = mContentCache.SelectionStart();
+    notification.mSelectionChangeData.mLength = mContentCache.SelectionLength();
     notification.mSelectionChangeData.mReversed =
-      mIMESelectionFocus < mIMESelectionAnchor;
+      mContentCache.SelectionReversed();
     notification.mSelectionChangeData.SetWritingMode(mWritingMode);
     notification.mSelectionChangeData.mCausedByComposition =
       aCausedByComposition;
     widget->NotifyIME(notification);
   }
   return true;
 }
 
@@ -2220,32 +2212,28 @@ TabParent::HandleQueryContentEvent(Widge
   aEvent.mSucceeded = false;
   aEvent.mWasAsync = false;
   aEvent.mReply.mFocusedWidget = nsCOMPtr<nsIWidget>(GetWidget()).get();
 
   switch (aEvent.message)
   {
   case NS_QUERY_SELECTED_TEXT:
     {
-      aEvent.mReply.mOffset = std::min(mIMESelectionAnchor, mIMESelectionFocus);
-      if (mIMESelectionAnchor == mIMESelectionFocus) {
+      aEvent.mReply.mOffset = mContentCache.SelectionStart();
+      if (mContentCache.SelectionCollapsed()) {
         aEvent.mReply.mString.Truncate(0);
       } else {
-        if (mIMESelectionAnchor > mContentCache.TextLength() ||
-            mIMESelectionFocus > mContentCache.TextLength()) {
+        if (NS_WARN_IF(mContentCache.SelectionEndIsGraterThanTextLength())) {
           break;
         }
-        uint32_t selLen = mIMESelectionAnchor > mIMESelectionFocus ?
-                          mIMESelectionAnchor - mIMESelectionFocus :
-                          mIMESelectionFocus - mIMESelectionAnchor;
         aEvent.mReply.mString = Substring(mContentCache.Text(),
                                           aEvent.mReply.mOffset,
-                                          selLen);
+                                          mContentCache.SelectionLength());
       }
-      aEvent.mReply.mReversed = mIMESelectionFocus < mIMESelectionAnchor;
+      aEvent.mReply.mReversed = mContentCache.SelectionReversed();
       aEvent.mReply.mHasSelection = true;
       aEvent.mReply.mWritingMode = mWritingMode;
       aEvent.mSucceeded = true;
     }
     break;
   case NS_QUERY_TEXT_CONTENT:
     {
       uint32_t inputOffset = aEvent.mInput.mOffset,
@@ -2323,17 +2311,17 @@ TabParent::SendCompositionEvent(WidgetCo
     return false;
   }
 
   if (event.CausesDOMTextEvent()) {
     return SendCompositionChangeEvent(event);
   }
 
   mIMEComposing = !event.CausesDOMCompositionEndEvent();
-  mIMECompositionStart = std::min(mIMESelectionAnchor, mIMESelectionFocus);
+  mIMECompositionStart = mContentCache.SelectionStart();
   if (mIMECompositionEnding) {
     mIMEEventCountAfterEnding++;
     return true;
   }
   return PBrowserParent::SendCompositionEvent(event);
 }
 
 /**
@@ -2351,33 +2339,33 @@ TabParent::SendCompositionChangeEvent(Wi
     mIMECompositionText = event.mData;
     mIMEEventCountAfterEnding++;
     return true;
   }
 
   // We must be able to simulate the selection because
   // we might not receive selection updates in time
   if (!mIMEComposing) {
-    mIMECompositionStart = std::min(mIMESelectionAnchor, mIMESelectionFocus);
+    mIMECompositionStart = mContentCache.SelectionStart();
   }
-  mIMESelectionAnchor = mIMESelectionFocus =
-      mIMECompositionStart + event.mData.Length();
+  mContentCache.SetSelection(mIMECompositionStart + event.mData.Length());
   mIMEComposing = !event.CausesDOMCompositionEndEvent();
 
   return PBrowserParent::SendCompositionEvent(event);
 }
 
 bool
 TabParent::SendSelectionEvent(WidgetSelectionEvent& event)
 {
   if (mIsDestroyed) {
     return false;
   }
-  mIMESelectionAnchor = event.mOffset + (event.mReversed ? event.mLength : 0);
-  mIMESelectionFocus = event.mOffset + (!event.mReversed ? event.mLength : 0);
+  mContentCache.SetSelection(
+    event.mOffset + (event.mReversed ? event.mLength : 0),
+    event.mOffset + (!event.mReversed ? event.mLength : 0));
   return PBrowserParent::SendSelectionEvent(event);
 }
 
 /*static*/ TabParent*
 TabParent::GetFrom(nsFrameLoader* aFrameLoader)
 {
   if (!aFrameLoader) {
     return nullptr;
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -475,18 +475,16 @@ protected:
     bool InitBrowserConfiguration(const nsCString& aURI,
                                   BrowserConfiguration& aConfiguration);
 
     void SetHasContentOpener(bool aHasContentOpener);
 
     // IME
     static TabParent *mIMETabParent;
     ContentCache mContentCache;
-    uint32_t mIMESelectionAnchor;
-    uint32_t mIMESelectionFocus;
     mozilla::WritingMode mWritingMode;
     bool mIMEComposing;
     bool mIMECompositionEnding;
     uint32_t mIMEEventCountAfterEnding;
     // Buffer to store composition text during ResetInputState
     // Compositions in almost all cases are small enough for nsAutoString
     nsAutoString mIMECompositionText;
     uint32_t mIMECompositionStart;
--- a/widget/ContentCache.cpp
+++ b/widget/ContentCache.cpp
@@ -16,9 +16,16 @@ ContentCache::Clear()
 }
 
 void
 ContentCache::SetText(const nsAString& aText)
 {
   mText = aText;
 }
 
+void
+ContentCache::SetSelection(uint32_t aAnchorOffset, uint32_t aFocusOffset)
+{
+  mSelection.mAnchor = aAnchorOffset;
+  mSelection.mFocus = aFocusOffset;
+}
+
 } // namespace mozilla
--- a/widget/ContentCache.h
+++ b/widget/ContentCache.h
@@ -24,16 +24,55 @@ class ContentCache final
 {
 public:
   void Clear();
 
   void SetText(const nsAString& aText);
   const nsString& Text() const { return mText; }
   uint32_t TextLength() const { return mText.Length(); }
 
+  void SetSelection(uint32_t aCaretOffset)
+  {
+    SetSelection(aCaretOffset, aCaretOffset);
+  }
+  void SetSelection(uint32_t aAnchorOffset, uint32_t aFocusOffset);
+  bool SelectionCollapsed() const { return mSelection.Collapsed(); }
+  bool SelectionReversed() const { return mSelection.Reversed(); }
+  bool SelectionEndIsGraterThanTextLength() const
+  {
+    return SelectionEnd() > TextLength();
+  }
+  uint32_t SelectionAnchor() const { return mSelection.mAnchor; }
+  uint32_t SelectionFocus() const { return mSelection.mFocus; }
+  uint32_t SelectionStart() const { return mSelection.StartOffset(); }
+  uint32_t SelectionEnd() const { return mSelection.EndOffset(); }
+  uint32_t SelectionLength() const { return mSelection.Length(); }
+
 private:
   // Whole text in the target
   nsString mText;
+
+  struct Selection final
+  {
+    // Following values are offset in "flat text".
+    uint32_t mAnchor;
+    uint32_t mFocus;
+
+    Selection()
+      : mAnchor(0)
+      , mFocus(0)
+    {
+    }
+
+    bool Collapsed() const { return mFocus == mAnchor; }
+    bool Reversed() const { return mFocus < mAnchor; }
+    uint32_t StartOffset() const { return Reversed() ? mFocus : mAnchor; }
+    uint32_t EndOffset() const { return Reversed() ? mAnchor : mFocus; }
+    uint32_t Length() const
+    {
+      return Reversed() ? mAnchor - mFocus : mFocus - mAnchor;
+    }
+  } mSelection;
 };
 
 } // namespace mozilla
 
 #endif // mozilla_ContentCache_h