Bug 1275528 part.2 IMEContentObserver should use selection cache for computing absolute offset of WidgetQueryContentEvent if it's possible r?smaug draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Mon, 20 Jun 2016 15:57:38 +0900
changeset 380001 48e9de3ea7f2336b63fdf5d19736277abe90a55c
parent 380000 3cd96da5b7d335833fad504c20fd9e6d3a57bddd
child 380002 05228f50107c2030ab6c442e57a8a8bd851524a1
push id21107
push usermasayuki@d-toybox.com
push dateMon, 20 Jun 2016 10:09:39 +0000
reviewerssmaug
bugs1275528
milestone50.0a1
Bug 1275528 part.2 IMEContentObserver should use selection cache for computing absolute offset of WidgetQueryContentEvent if it's possible r?smaug IMEContentObserver may have cache of normal selection. If it's available, IMEContentObserver should use it for computing absolute offset of WidgetQueryContentEvent whose mInput::mOffset is relative offset to selection. This patch just improves the performance of such query. MozReview-Commit-ID: KHLgCc2uQzs
dom/events/IMEContentObserver.cpp
--- a/dom/events/IMEContentObserver.cpp
+++ b/dom/events/IMEContentObserver.cpp
@@ -703,19 +703,22 @@ IMEContentObserver::HandleQueryContentEv
   // If the instance has normal selection cache and the query event queries
   // normal selection's range, it should use the cached selection which was
   // sent to the widget.  However, if this instance has already received new
   // selection change notification but hasn't updated the cache yet (i.e.,
   // not sending selection change notification to IME, don't use the cached
   // 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;
     aEvent->mReply.mString = mSelectionData.String();
     aEvent->mReply.mWritingMode = mSelectionData.GetWritingMode();
     aEvent->mReply.mReversed = mSelectionData.mReversed;
     aEvent->mSucceeded = true;
     MOZ_LOG(sIMECOLog, LogLevel::Debug,
@@ -723,16 +726,42 @@ IMEContentObserver::HandleQueryContentEv
        "mMessage=%s })", this, ToChar(aEvent->mMessage)));
     return NS_OK;
   }
 
   MOZ_LOG(sIMECOLog, LogLevel::Debug,
     ("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<TextComposition> 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<bool> handling(mIsHandlingQueryContentEvent);
   mIsHandlingQueryContentEvent = true;
   ContentEventHandler handler(GetPresContext());
   nsresult rv = handler.HandleQueryContentEvent(aEvent);
 
   if (!IsInitializedWithPlugin() &&
       NS_WARN_IF(aEvent->mReply.mContentsRoot != mRootContent)) {
     // Focus has changed unexpectedly, so make the query fail.