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
--- 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;