Bug 1347433 part.3 TextEventDispatcher::PendingComposition::Flush() should replace native line breakers in the composition string before dispatching composition event r=m_kato
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 15 Mar 2017 19:09:30 +0900
changeset 347909 eaf379d6fc13817124ce58bac152028b277ceeda
parent 347908 c27841632c8ad1ba886667f63c002dabbcbbb50b
child 347910 9339469b766a46500d09fefb8e3171413b2786e0
push id31507
push usercbook@mozilla.com
push dateThu, 16 Mar 2017 14:35:12 +0000
treeherdermozilla-central@3ea221e3ebbb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato
bugs1347433
milestone55.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 1347433 part.3 TextEventDispatcher::PendingComposition::Flush() should replace native line breakers in the composition string before dispatching composition event r=m_kato So, finally, Flush() should replace native line breakers in the composition string before dispatching composition events. However, if the composition string was set by Set(), i.e., it's already been replaced with native line breakers, we shouldn't try to do it again due to performance reason. Therefore, this patch adds |mReplacedNativeLineBreakers| to manage if it's already been called. MozReview-Commit-ID: 5Y7ULWeP153
widget/TextEventDispatcher.cpp
widget/TextEventDispatcher.h
--- a/widget/TextEventDispatcher.cpp
+++ b/widget/TextEventDispatcher.cpp
@@ -593,39 +593,43 @@ TextEventDispatcher::PendingComposition:
 }
 
 void
 TextEventDispatcher::PendingComposition::Clear()
 {
   mString.Truncate();
   mClauses = nullptr;
   mCaret.mRangeType = TextRangeType::eUninitialized;
+  mReplacedNativeLineBreakers = false;
 }
 
 void
 TextEventDispatcher::PendingComposition::EnsureClauseArray()
 {
   if (mClauses) {
     return;
   }
   mClauses = new TextRangeArray();
 }
 
 nsresult
 TextEventDispatcher::PendingComposition::SetString(const nsAString& aString)
 {
+  MOZ_ASSERT(!mReplacedNativeLineBreakers);
   mString = aString;
   return NS_OK;
 }
 
 nsresult
 TextEventDispatcher::PendingComposition::AppendClause(
                                            uint32_t aLength,
                                            TextRangeType aTextRangeType)
 {
+  MOZ_ASSERT(!mReplacedNativeLineBreakers);
+
   if (NS_WARN_IF(!aLength)) {
     return NS_ERROR_INVALID_ARG;
   }
 
   switch (aTextRangeType) {
     case TextRangeType::eRawClause:
     case TextRangeType::eSelectedRawClause:
     case TextRangeType::eConvertedClause:
@@ -643,16 +647,18 @@ TextEventDispatcher::PendingComposition:
       return NS_ERROR_INVALID_ARG;
   }
 }
 
 nsresult
 TextEventDispatcher::PendingComposition::SetCaret(uint32_t aOffset,
                                                   uint32_t aLength)
 {
+  MOZ_ASSERT(!mReplacedNativeLineBreakers);
+
   mCaret.mStartOffset = aOffset;
   mCaret.mEndOffset = mCaret.mStartOffset + aLength;
   mCaret.mRangeType = TextRangeType::eCaret;
   return NS_OK;
 }
 
 nsresult
 TextEventDispatcher::PendingComposition::Set(const nsAString& aString,
@@ -689,16 +695,18 @@ TextEventDispatcher::PendingComposition:
   }
   ReplaceNativeLineBreakers();
   return NS_OK;
 }
 
 void
 TextEventDispatcher::PendingComposition::ReplaceNativeLineBreakers()
 {
+  mReplacedNativeLineBreakers = true;
+
   // If the composition string is empty, we don't need to do anything.
   if (mString.IsEmpty()) {
     return;
   }
 
   nsAutoString nativeString(mString);
   // Don't expose CRLF to web contents, instead, use LF.
   mString.ReplaceSubstring(NS_LITERAL_STRING("\r\n"), NS_LITERAL_STRING("\n"));
@@ -774,16 +782,22 @@ TextEventDispatcher::PendingComposition:
       NS_WARNING("Caret position is out of the composition string");
       Clear();
       return NS_ERROR_ILLEGAL_VALUE;
     }
     EnsureClauseArray();
     mClauses->AppendElement(mCaret);
   }
 
+  // If the composition string is set without Set(), we need to replace native
+  // line breakers in the composition string with XP line breaker.
+  if (!mReplacedNativeLineBreakers) {
+    ReplaceNativeLineBreakers();
+  }
+
   RefPtr<TextEventDispatcher> kungFuDeathGrip(aDispatcher);
   nsCOMPtr<nsIWidget> widget(aDispatcher->mWidget);
   WidgetCompositionEvent compChangeEvent(true, eCompositionChange, widget);
   aDispatcher->InitEvent(compChangeEvent);
   if (aEventTime) {
     compChangeEvent.AssignEventTime(*aEventTime);
   }
   compChangeEvent.mData = mString;
--- a/widget/TextEventDispatcher.h
+++ b/widget/TextEventDispatcher.h
@@ -325,16 +325,17 @@ private:
                    const WidgetEventTime* aEventTime);
     const TextRangeArray* GetClauses() const { return mClauses; }
     void Clear();
 
   private:
     nsString mString;
     RefPtr<TextRangeArray> mClauses;
     TextRange mCaret;
+    bool mReplacedNativeLineBreakers;
 
     void EnsureClauseArray();
 
     /**
      * ReplaceNativeLineBreakers() replaces "\r\n" and "\r" to "\n" and adjust
      * each clause information and the caret information.
      */
     void ReplaceNativeLineBreakers();