Bug 1305355 part.1 TextComposition::GetSelectionStartOffset() should query normal selection range when composition string is empty r?smaug draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Mon, 26 Sep 2016 21:06:26 +0900
changeset 417812 f92124d5c64beb09ac5567634ebde102e9706b5e
parent 417811 9fee3efa4852f0146bfe63d822d6c71b23430a18
child 417813 f956bfaca1b7fe38a9453d40ea0bf3731651cd4f
push id30511
push usermasayuki@d-toybox.com
push dateTue, 27 Sep 2016 05:42:37 +0000
reviewerssmaug
bugs1305355
milestone52.0a1
Bug 1305355 part.1 TextComposition::GetSelectionStartOffset() should query normal selection range when composition string is empty r?smaug TextComposition::GetSelectionStartOffset() tries to query the start offset of the composition if there is a composition. Therefore, it tries to query first clause when it has some clause information of the composition string. However, even if the composition string is empty, TextComposition::mRanges which refers CompositionEvent::mRanges of the last eCompositionChange event may have empty clause information. In such case, this method tries to query not existing IME selection range. Then, this returns UINT32_MAX and ContentCacheInChild will query character rects around the offset and ContentEventHandler::SetRangeFromFlatTextOffset() will meet odd case. For avoiding this issue, TextComposition::GetSelectionStartOffset() should query normal selection when composition string in the editor is empty. Note that TextComposition::mString will be updated after the editor completes updating its DOM contents. Therefore, TextComposition should refer mLastData which is set before dispatching eCompositionChange in the tree. MozReview-Commit-ID: F2UGCQLXLSz
dom/events/TextComposition.cpp
--- a/dom/events/TextComposition.cpp
+++ b/dom/events/TextComposition.cpp
@@ -434,20 +434,26 @@ TextComposition::HandleSelectionEvent(ns
   handler.OnSelectionEvent(aSelectionEvent);
 }
 
 uint32_t
 TextComposition::GetSelectionStartOffset()
 {
   nsCOMPtr<nsIWidget> widget = mPresContext->GetRootWidget();
   WidgetQueryContentEvent selectedTextEvent(true, eQuerySelectedText, widget);
-  if (mRanges && mRanges->HasClauses()) {
+  // Due to a bug of widget, mRanges may not be nullptr even though composition
+  // string is empty.  So, we need to check it here for avoiding to return
+  // odd start offset.
+  if (!mLastData.IsEmpty() && mRanges && mRanges->HasClauses()) {
     selectedTextEvent.InitForQuerySelectedText(
                         ToSelectionType(mRanges->GetFirstClause()->mRangeType));
   } else {
+    NS_WARNING_ASSERTION(
+      !mLastData.IsEmpty() || !mRanges || !mRanges->HasClauses(),
+      "Shouldn't have empty clause info when composition string is empty");
     selectedTextEvent.InitForQuerySelectedText(SelectionType::eNormal);
   }
 
   // The editor which has this composition is observed by active
   // IMEContentObserver, we can use the cache of it.
   RefPtr<IMEContentObserver> contentObserver =
     IMEStateManager::GetActiveContentObserver();
   bool doQuerySelection = true;