diff --git a/dom/events/IMEContentObserver.cpp b/dom/events/IMEContentObserver.cpp index 852b3221c608..83b76163ac08 100644 --- a/dom/events/IMEContentObserver.cpp +++ b/dom/events/IMEContentObserver.cpp @@ -708,9 +708,12 @@ IMEContentObserver::HandleQueryContentEvent(WidgetQueryContentEvent* aEvent) // value. Note that don't update selection cache here since if you update // selection cache here, IMENotificationSender won't notify IME of selection // change because it looks like that the selection isn't actually changed. - if (aEvent->mMessage == eQuerySelectedText && aEvent->mUseNativeLineBreak && - aEvent->mInput.mSelectionType == SelectionType::eNormal && - mSelectionData.IsValid() && !mNeedsToNotifyIMEOfSelectionChange) { + bool isSelectionCacheAvailable = + aEvent->mUseNativeLineBreak && mSelectionData.IsValid() && + !mNeedsToNotifyIMEOfSelectionChange; + if (isSelectionCacheAvailable && + aEvent->mMessage == eQuerySelectedText && + aEvent->mInput.mSelectionType == SelectionType::eNormal) { aEvent->mReply.mContentsRoot = mRootContent; aEvent->mReply.mHasSelection = !mSelectionData.IsCollapsed(); aEvent->mReply.mOffset = mSelectionData.mOffset; @@ -728,6 +731,32 @@ IMEContentObserver::HandleQueryContentEvent(WidgetQueryContentEvent* aEvent) ("IMECO: 0x%p IMEContentObserver::HandleQueryContentEvent(aEvent={ " "mMessage=%s })", this, ToChar(aEvent->mMessage))); + // If we can make the event's input offset absolute with TextComposition or + // mSelection, we should set it here for reducing the cost of computing + // selection start offset. If ContentEventHandler receives a + // WidgetQueryContentEvent whose input offset is relative to insertion point, + // it computes current selection start offset (this may be expensive) and + // make the offset absolute value itself. + // Note that calling MakeOffsetAbsolute() makes the event a query event with + // absolute offset. So, ContentEventHandler doesn't pay any additional cost + // after calling MakeOffsetAbsolute() here. + if (aEvent->mInput.mRelativeToInsertionPoint && + aEvent->mInput.IsValidEventMessage(aEvent->mMessage)) { + RefPtr composition = + IMEStateManager::GetTextCompositionFor(aEvent->mWidget); + if (composition) { + uint32_t compositionStart = composition->NativeOffsetOfStartComposition(); + if (NS_WARN_IF(!aEvent->mInput.MakeOffsetAbsolute(compositionStart))) { + return NS_ERROR_FAILURE; + } + } else if (isSelectionCacheAvailable) { + uint32_t selectionStart = mSelectionData.mOffset; + if (NS_WARN_IF(!aEvent->mInput.MakeOffsetAbsolute(selectionStart))) { + return NS_ERROR_FAILURE; + } + } + } + AutoRestore handling(mIsHandlingQueryContentEvent); mIsHandlingQueryContentEvent = true; ContentEventHandler handler(GetPresContext());