--- a/dom/events/ContentEventHandler.cpp
+++ b/dom/events/ContentEventHandler.cpp
@@ -390,16 +390,19 @@ ContentEventHandler::QueryContentRect(ns
nsRect frameRect(nsPoint(0, 0), frame->GetRect().Size());
rv = ConvertToRootRelativeOffset(frame, frameRect);
NS_ENSURE_SUCCESS(rv, rv);
resultRect.UnionRect(resultRect, frameRect);
}
aEvent->mReply.mRect = LayoutDeviceIntRect::FromUnknownRect(
resultRect.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;
}
// Editor places a bogus BR node under its root content if the editor doesn't
// have any text. This happens even for single line editors.
// When we get text content and when we change the selection,
@@ -1382,16 +1385,32 @@ ContentEventHandler::OnQueryTextContent(
"Font ranges doesn't match the string");
}
aEvent->mSucceeded = true;
return NS_OK;
}
+void
+ContentEventHandler::EnsureNonEmptyRect(nsRect& aRect) const
+{
+ // See the comment in ContentEventHandler.h why this doesn't set them to
+ // one device pixel.
+ aRect.height = std::max(1, aRect.height);
+ aRect.width = std::max(1, aRect.width);
+}
+
+void
+ContentEventHandler::EnsureNonEmptyRect(LayoutDeviceIntRect& aRect) const
+{
+ aRect.height = std::max(1, aRect.height);
+ aRect.width = std::max(1, aRect.width);
+}
+
ContentEventHandler::NodePosition
ContentEventHandler::GetNodePositionHavingFlatText(
const NodePosition& aNodePosition)
{
return GetNodePositionHavingFlatText(aNodePosition.mNode,
aNodePosition.mOffset);
}
@@ -1496,20 +1515,19 @@ ContentEventHandler::OnQueryTextRectArra
for (size_t i = 0; i < charRects.Length(); i++) {
nsRect charRect = charRects[i];
charRect.x += frameRect.x;
charRect.y += frameRect.y;
rect = LayoutDeviceIntRect::FromUnknownRect(
charRect.ToOutsidePixels(mPresContext->AppUnitsPerDevPixel()));
-
- // Ensure at least 1px width and height for avoiding empty rect.
- rect.height = std::max(1, rect.height);
- rect.width = std::max(1, rect.width);
+ // Returning empty rect may cause native IME confused, let's make sure to
+ // return non-empty rect.
+ EnsureNonEmptyRect(rect);
aEvent->mReply.mRectArray.AppendElement(rect);
offset++;
}
}
aEvent->mSucceeded = true;
return NS_OK;
}
@@ -1552,24 +1570,26 @@ ContentEventHandler::OnQueryTextRect(Wid
// get the starting frame rect
nsRect rect(nsPoint(0, 0), firstFrame->GetRect().Size());
rv = ConvertToRootRelativeOffset(firstFrame, rect);
NS_ENSURE_SUCCESS(rv, rv);
nsRect frameRect = rect;
nsPoint ptOffset;
firstFrame->GetPointFromOffset(startNodePosition.mOffset, &ptOffset);
- // minus 1 to avoid creating an empty rect
if (firstFrame->GetWritingMode().IsVertical()) {
- rect.y += ptOffset.y - 1;
- rect.height -= ptOffset.y - 1;
+ rect.y += ptOffset.y;
+ rect.height -= ptOffset.y;
} else {
- rect.x += ptOffset.x - 1;
- rect.width -= ptOffset.x - 1;
+ rect.x += ptOffset.x;
+ rect.width -= ptOffset.x;
}
+ // UnionRect() requires non-empty rect. So, let's make sure to get non-emtpy
+ // rect from the first frame.
+ EnsureNonEmptyRect(rect);
// get the ending frame
NodePosition endNodePosition =
GetNodePositionHavingFlatText(range->GetEndParent(), range->EndOffset());
if (NS_WARN_IF(!endNodePosition.IsValid())) {
return NS_ERROR_FAILURE;
}
nsIFrame* lastFrame = nullptr;
@@ -1595,38 +1615,46 @@ ContentEventHandler::OnQueryTextRect(Wid
if (!frame) {
// this can happen when the end offset of the range is 0.
frame = lastFrame;
}
}
frameRect.SetRect(nsPoint(0, 0), frame->GetRect().Size());
rv = ConvertToRootRelativeOffset(frame, frameRect);
NS_ENSURE_SUCCESS(rv, rv);
+ // UnionRect() requires non-empty rect. So, let's make sure to get
+ // non-emtpy rect from the frame.
+ EnsureNonEmptyRect(frameRect);
if (frame != lastFrame) {
// not last frame, so just add rect to previous result
rect.UnionRect(rect, frameRect);
}
}
// get the ending frame rect
lastFrame->GetPointFromOffset(endNodePosition.mOffset, &ptOffset);
- // minus 1 to avoid creating an empty rect
if (lastFrame->GetWritingMode().IsVertical()) {
- frameRect.height -= lastFrame->GetRect().height - ptOffset.y - 1;
+ frameRect.height -= lastFrame->GetRect().height - ptOffset.y;
} else {
- frameRect.width -= lastFrame->GetRect().width - ptOffset.x - 1;
+ frameRect.width -= lastFrame->GetRect().width - ptOffset.x;
}
+ // UnionRect() requires non-empty rect. So, let's make sure to get non-empty
+ // rect from the last frame.
+ EnsureNonEmptyRect(frameRect);
if (firstFrame == lastFrame) {
rect.IntersectRect(rect, frameRect);
} else {
rect.UnionRect(rect, frameRect);
}
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->mReply.mWritingMode = lastFrame->GetWritingMode();
aEvent->mSucceeded = true;
return NS_OK;
}
nsresult
ContentEventHandler::OnQueryEditorRect(WidgetQueryContentEvent* aEvent)
{
@@ -1665,16 +1693,19 @@ ContentEventHandler::OnQueryCaretRect(Wi
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));
+ // Returning empty rect may cause native IME confused, let's make sure
+ // to return non-empty rect.
+ EnsureNonEmptyRect(aEvent->mReply.mRect);
aEvent->mReply.mWritingMode = caretFrame->GetWritingMode();
aEvent->mReply.mOffset = aEvent->mInput.mOffset;
aEvent->mSucceeded = true;
return NS_OK;
}
}
}
@@ -1716,23 +1747,19 @@ ContentEventHandler::OnQueryCaretRect(Wi
rect.height = fontMetrics->MaxHeight();
}
rv = ConvertToRootRelativeOffset(frame, rect);
NS_ENSURE_SUCCESS(rv, rv);
aEvent->mReply.mRect = LayoutDeviceIntRect::FromUnknownRect(
rect.ToOutsidePixels(mPresContext->AppUnitsPerDevPixel()));
- // If the caret rect is empty, let's make it non-empty rect.
- if (!aEvent->mReply.mRect.width) {
- aEvent->mReply.mRect.width = 1;
- }
- if (!aEvent->mReply.mRect.height) {
- aEvent->mReply.mRect.height = 1;
- }
+ // 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);