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
--- 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()");
}