Bug 1286464 part.6 ContentEventHandler::OnQueryCaretRect() should use eQueryTextRect event when it needs to guess the caret rect r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 29 Jul 2016 00:37:09 +0900
changeset 400377 909162ca9772e0a2c8486e1af95751716751476c
parent 400376 4ddcedb282564f1c1012f5d47fbd88ae18695e52
child 400378 e275c2f030b485ce003eb1731fd62e48723f412e
push id26138
push usergszorc@mozilla.com
push dateSat, 13 Aug 2016 03:04:36 +0000
reviewerssmaug
bugs1286464
milestone51.0a1
Bug 1286464 part.6 ContentEventHandler::OnQueryCaretRect() should use eQueryTextRect event when it needs to guess the caret rect r=smaug ContentEventHandler::OnQueryTextRect() is now too complicated. So, we shouldn't duplicate similar code in OnQueryCaretRect(). When it needs to guess a caret rect from a character rect, we shouldn't compute character rect by itself. MozReview-Commit-ID: 5G4MzQJzmoV
dom/events/ContentEventHandler.cpp
widget/TextEvents.h
--- a/dom/events/ContentEventHandler.cpp
+++ b/dom/events/ContentEventHandler.cpp
@@ -1673,28 +1673,25 @@ ContentEventHandler::OnQueryEditorRect(W
 nsresult
 ContentEventHandler::OnQueryCaretRect(WidgetQueryContentEvent* aEvent)
 {
   nsresult rv = Init(aEvent);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
-  LineBreakType lineBreakType = GetLineBreakType(aEvent);
-
-  nsRect caretRect;
-
   // When the selection is collapsed and the queried offset is current caret
   // position, we should return the "real" caret rect.
   if (mSelection->IsCollapsed()) {
+    nsRect caretRect;
     nsIFrame* caretFrame = nsCaret::GetGeometry(mSelection, &caretRect);
     if (caretFrame) {
       uint32_t offset;
       rv = GetFlatTextLengthBefore(mFirstSelectedRange,
-                                   &offset, lineBreakType);
+                                   &offset, GetLineBreakType(aEvent));
       NS_ENSURE_SUCCESS(rv, rv);
       if (offset == aEvent->mInput.mOffset) {
         rv = ConvertToRootRelativeOffset(caretFrame, caretRect);
         NS_ENSURE_SUCCESS(rv, rv);
         nscoord appUnitsPerDevPixel =
           caretFrame->PresContext()->AppUnitsPerDevPixel();
         aEvent->mReply.mRect = LayoutDeviceIntRect::FromUnknownRect(
           caretRect.ToOutsidePixels(appUnitsPerDevPixel));
@@ -1704,62 +1701,33 @@ ContentEventHandler::OnQueryCaretRect(Wi
         aEvent->mReply.mWritingMode = caretFrame->GetWritingMode();
         aEvent->mReply.mOffset = aEvent->mInput.mOffset;
         aEvent->mSucceeded = true;
         return NS_OK;
       }
     }
   }
 
-  // Otherwise, we should set the guessed caret rect.
-  RefPtr<nsRange> range = new nsRange(mRootContent);
-  rv = SetRangeFromFlatTextOffset(range, aEvent->mInput.mOffset, 0,
-                                  lineBreakType, true,
-                                  &aEvent->mReply.mOffset);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = AdjustCollapsedRangeMaybeIntoTextNode(range);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
+  // Otherwise, we should guess the caret rect from the character's rect.
+  WidgetQueryContentEvent queryTextRectEvent(eQueryTextRect, *aEvent);
+  WidgetQueryContentEvent::Options options(*aEvent);
+  queryTextRectEvent.InitForQueryTextRect(aEvent->mInput.mOffset, 1, options);
+  rv = OnQueryTextRect(&queryTextRectEvent);
+  if (NS_WARN_IF(NS_FAILED(rv)) || NS_WARN_IF(!queryTextRectEvent.mSucceeded)) {
+    return NS_ERROR_FAILURE;
   }
-
-  int32_t xpOffsetInFrame;
-  nsIFrame* frame;
-  rv = GetStartFrameAndOffset(range, frame, xpOffsetInFrame);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsPoint posInFrame;
-  rv = frame->GetPointFromOffset(range->StartOffset(), &posInFrame);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  aEvent->mReply.mWritingMode = frame->GetWritingMode();
-  bool isVertical = aEvent->mReply.mWritingMode.IsVertical();
-
-  nsRect rect;
-  rect.x = posInFrame.x;
-  rect.y = posInFrame.y;
-
-  RefPtr<nsFontMetrics> fontMetrics =
-    nsLayoutUtils::GetInflatedFontMetricsForFrame(frame);
-  if (isVertical) {
-    rect.width = fontMetrics->MaxHeight();
-    rect.height = caretRect.height;
+  queryTextRectEvent.mReply.mString.Truncate();
+  aEvent->mReply = queryTextRectEvent.mReply;
+  if (aEvent->GetWritingMode().IsVertical()) {
+    aEvent->mReply.mRect.height = 1;
   } else {
-    rect.width = caretRect.width;
-    rect.height = fontMetrics->MaxHeight();
+    aEvent->mReply.mRect.width = 1;
   }
-
-  rv = ConvertToRootRelativeOffset(frame, rect);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  aEvent->mReply.mRect = LayoutDeviceIntRect::FromUnknownRect(
-      rect.ToOutsidePixels(mPresContext->AppUnitsPerDevPixel()));
   // Returning empty rect may cause native IME confused, let's make sure to
   // return non-empty rect.
-  EnsureNonEmptyRect(aEvent->mReply.mRect);
   aEvent->mSucceeded = true;
   return NS_OK;
 }
 
 nsresult
 ContentEventHandler::OnQueryContentState(WidgetQueryContentEvent* aEvent)
 {
   nsresult rv = Init(aEvent);
--- a/widget/TextEvents.h
+++ b/widget/TextEvents.h
@@ -627,16 +627,27 @@ public:
                           nsIWidget* aWidget)
     : WidgetGUIEvent(aIsTrusted, aMessage, aWidget, eQueryContentEventClass)
     , mSucceeded(false)
     , mUseNativeLineBreak(true)
     , mWithFontRanges(false)
   {
   }
 
+  WidgetQueryContentEvent(EventMessage aMessage,
+                          const WidgetQueryContentEvent& aOtherEvent)
+    : WidgetGUIEvent(aOtherEvent.IsTrusted(), aMessage,
+                     const_cast<nsIWidget*>(aOtherEvent.mWidget.get()),
+                     eQueryContentEventClass)
+    , mSucceeded(false)
+    , mUseNativeLineBreak(aOtherEvent.mUseNativeLineBreak)
+    , mWithFontRanges(false)
+  {
+  }
+
   virtual WidgetEvent* Duplicate() const override
   {
     // This event isn't an internal event of any DOM event.
     NS_ASSERTION(!IsAllowedToDispatchDOMEvent(),
       "WidgetQueryContentEvent needs to support Duplicate()");
     MOZ_CRASH("WidgetQueryContentEvent doesn't support Duplicate()");
   }