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