Bug 1347433 part.2 Implement TextEventDispatcher::PendingComposition::ReplaceNativeLineBreakers() and TextEventDispatcher::PendingComposition::Set() should use it r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 15 Mar 2017 18:59:34 +0900
changeset 499689 8bf0a15d2ad342bd3cd7fa8a3bd994369a3d07fe
parent 499688 dd4589cf1adfda479bf5cf2d850069e67c906b9a
child 499690 c152fe9ec769aafec2621de3d6e6c2f33704c49e
push id49481
push usermasayuki@d-toybox.com
push dateThu, 16 Mar 2017 03:20:05 +0000
reviewersm_kato
bugs1347433
milestone55.0a1
Bug 1347433 part.2 Implement TextEventDispatcher::PendingComposition::ReplaceNativeLineBreakers() and TextEventDispatcher::PendingComposition::Set() should use it r?m_kato MozReview-Commit-ID: 5mPiRGwUuej
widget/TextEventDispatcher.cpp
widget/TextEventDispatcher.h
--- a/widget/TextEventDispatcher.cpp
+++ b/widget/TextEventDispatcher.cpp
@@ -655,49 +655,75 @@ TextEventDispatcher::PendingComposition:
 }
 
 nsresult
 TextEventDispatcher::PendingComposition::Set(const nsAString& aString,
                                              const TextRangeArray* aRanges)
 {
   Clear();
 
-  nsAutoString str(aString);
-  // Don't expose CRLF to web contents, instead, use LF.
-  str.ReplaceSubstring(NS_LITERAL_STRING("\r\n"), NS_LITERAL_STRING("\n"));
-  nsresult rv = SetString(str);
+  nsresult rv = SetString(aString);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   if (!aRanges || aRanges->IsEmpty()) {
-    // Create dummy range if aString isn't empty.
-    if (!aString.IsEmpty()) {
-      rv = AppendClause(str.Length(), TextRangeType::eRawClause);
+    // Create dummy range if mString isn't empty.
+    if (!mString.IsEmpty()) {
+      rv = AppendClause(mString.Length(), TextRangeType::eRawClause);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
+      ReplaceNativeLineBreakers();
     }
     return NS_OK;
   }
 
   // Adjust offsets in the ranges for XP linefeed character (only \n).
   for (uint32_t i = 0; i < aRanges->Length(); ++i) {
     TextRange range = aRanges->ElementAt(i);
-    AdjustRange(range, aString);
     if (range.mRangeType == TextRangeType::eCaret) {
       mCaret = range;
     } else {
       EnsureClauseArray();
       mClauses->AppendElement(range);
     }
   }
+  ReplaceNativeLineBreakers();
   return NS_OK;
 }
 
+void
+TextEventDispatcher::PendingComposition::ReplaceNativeLineBreakers()
+{
+  // 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"));
+
+  // If the length isn't changed, we don't need to adjust any offset and length
+  // of mClauses nor mCaret.
+  if (nativeString.Length() == mString.Length()) {
+    return;
+  }
+
+  if (mClauses) {
+    for (TextRange& clause : *mClauses) {
+      AdjustRange(clause, nativeString);
+    }
+  }
+  if (mCaret.mRangeType == TextRangeType::eCaret) {
+    AdjustRange(mCaret, nativeString);
+  }
+}
+
 // static
 void
 TextEventDispatcher::PendingComposition::AdjustRange(
                                            TextRange& aRange,
                                            const nsAString& aNativeString)
 {
   TextRange nativeRange = aRange;
   // XXX Following code wastes runtime cost because this causes computing
--- a/widget/TextEventDispatcher.h
+++ b/widget/TextEventDispatcher.h
@@ -329,16 +329,22 @@ private:
   private:
     nsString mString;
     RefPtr<TextRangeArray> mClauses;
     TextRange mCaret;
 
     void EnsureClauseArray();
 
     /**
+     * ReplaceNativeLineBreakers() replaces "\r\n" and "\r" to "\n" and adjust
+     * each clause information and the caret information.
+     */
+    void ReplaceNativeLineBreakers();
+
+    /**
      * AdjustRange() adjusts aRange as in the string with XP line breakers.
      *
      * @param aRange            The reference to a range in aNativeString.
      *                          This will be modified.
      * @param aNativeString     The string with native line breakers.
      *                          This may include "\r\n" and/or "\r".
      */
     static void AdjustRange(TextRange& aRange, const nsAString& aNativeString);