Bug 1286464 part.9 ContentEventHandler::OnQueryTextRectArray() shouldn't append same rect for following character of a lien breaker when the query range starts from middle of the line breaker r=smaug draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 05 Aug 2016 13:53:08 +0900
changeset 400165 3afaca4d6e9f09e2054c4a6bd876635cfef6c58c
parent 400164 3117d68f056dc69550a16f52adade82049ba8277
child 400166 dca28a6e4661eef3c8a102916c451e0f021bf6d5
push id26081
push usermasayuki@d-toybox.com
push dateFri, 12 Aug 2016 17:11:29 +0000
reviewerssmaug
bugs1286464
milestone51.0a1
Bug 1286464 part.9 ContentEventHandler::OnQueryTextRectArray() shouldn't append same rect for following character of a lien breaker when the query range starts from middle of the line breaker r=smaug If the query range starts middle of a line breaker, i.e., "\r[\n", ContentEventHandler::OnQueryTextRectArray() does not need to (in other words, should not) append same rect anymore. This patch checks if the range starts middle of a line breaker and in such case, skip to append same rect. MozReview-Commit-ID: H5gdtAakGcP
dom/events/ContentEventHandler.cpp
--- a/dom/events/ContentEventHandler.cpp
+++ b/dom/events/ContentEventHandler.cpp
@@ -1587,25 +1587,40 @@ ContentEventHandler::OnQueryTextRectArra
 
     // get the starting frame rect
     nsRect frameRect(nsPoint(0, 0), firstFrame->GetRect().Size());
     rv = ConvertToRootRelativeOffset(firstFrame, frameRect);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
+    bool startsBetweenLineBreaker = false;
     AutoTArray<nsRect, 16> charRects;
 
     bool isLineBreaker = ShouldBreakLineBefore(firstContent, mRootContent);
     if (isLineBreaker) {
       // TODO: If the frame isn't <br> and there was previous text frame or
       //       <br>, we can set the rect to caret rect at the end.  Currently,
       //       this sets the rect to caret rect at the start of the node.
       FrameRelativeRect brRect = GetLineBreakerRectBefore(firstFrame);
       charRects.AppendElement(brRect.RectRelativeTo(firstFrame));
+      if (kBRLength > 1 && offset == aEvent->mInput.mOffset && offset) {
+        // If the first frame for the previous offset of the query range and
+        // the first frame for the start of query range are same, that means
+        // the start offset is between the first line breaker (i.e., the range
+        // starts between "\r" and "\n").
+        rv = SetRangeFromFlatTextOffset(range, aEvent->mInput.mOffset - 1, 1,
+                                        lineBreakType, true, nullptr);
+        if (NS_WARN_IF(NS_FAILED(rv))) {
+          return NS_ERROR_UNEXPECTED;
+        }
+        FrameAndNodeOffset frameForPrevious =
+          GetFirstFrameHavingFlatTextInRange(range);
+        startsBetweenLineBreaker = frameForPrevious.mFrame == firstFrame.mFrame;
+      }
     } else {
       rv = firstFrame->GetCharacterRectsInRange(firstFrame.mStartOffsetInNode,
                                                 kEndOffset - offset, charRects);
       if (NS_WARN_IF(NS_FAILED(rv)) || NS_WARN_IF(charRects.IsEmpty())) {
         // XXX: If the node isn't a text node and does not cause a line break,
         //      we need to recompute with new range, but how?
         return rv;
       }
@@ -1634,18 +1649,27 @@ ContentEventHandler::OnQueryTextRectArra
       MOZ_ASSERT(kBRLength == 2);
 
       // If it's already reached the end of query range, we don't need to do
       // anymore.
       if (offset == kEndOffset) {
         break;
       }
 
-      // TODO: If the query range is stated between a line breaker, i.e., \r[\n,
-      //       We shouldn't append a rect here.
+      // If the query range starts from between a line breaker, i.e., it starts
+      // between "\r" and "\n", the appended rect was for the "\n".  Therefore,
+      // we don't need to append same rect anymore for current "\r\n".
+      if (startsBetweenLineBreaker) {
+        continue;
+      }
+
+      // The appended rect was for "\r" of "\r\n".  Therefore, we need to
+      // append same rect for "\n" too because querying rect of "\r" and "\n"
+      // should return same rect.  E.g., IME may query previous character's
+      // rect of first character of a line.
       aEvent->mReply.mRectArray.AppendElement(rect);
       offset++;
     }
   }
   aEvent->mSucceeded = true;
   return NS_OK;
 }