Bug 1347433 part.2 Implement TextEventDispatcher::PendingComposition::ReplaceNativeLineBreakers() and TextEventDispatcher::PendingComposition::Set() should use it r?m_kato
MozReview-Commit-ID: 5mPiRGwUuej
--- 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);