nsresult
nsQueryContentEventHandler::QueryRectFor(nsQueryContentEvent* aEvent,
        nsIRange* aRange,
        nsICaret* aCaret)
{
    PRInt32 offsetInFrame;
    nsIFrame* frame;
    nsresult rv = GetStartFrameAndOffset(aRange, &frame, &offsetInFrame);
    NS_ENSURE_SUCCESS(rv, rv);

    nsPoint posInFrame;
    rv = frame->GetPointFromOffset(aRange->StartOffset(), &posInFrame);
    NS_ENSURE_SUCCESS(rv, rv);

    aEvent->mReply.mRect.y = posInFrame.y;
    aEvent->mReply.mRect.height = frame->GetSize().height;

    if (aEvent->message == NS_QUERY_CHARACTER_RECT) {
        nsPoint nextPos;
        rv = frame->GetPointFromOffset(aRange->EndOffset(), &nextPos);
        NS_ENSURE_SUCCESS(rv, rv);
        aEvent->mReply.mRect.x = PR_MIN(posInFrame.x, nextPos.x);
        aEvent->mReply.mRect.width = PR_ABS(posInFrame.x - nextPos.x);
    } else {
        aEvent->mReply.mRect.x = posInFrame.x;
        aEvent->mReply.mRect.width = aCaret->GetCaretRect().width;
    }

    // The coordinates are app units here, they will be converted to system
    // coordinates by view manager.
    rv = ConvertToRootViewRelativeOffset(frame, aEvent->mReply.mRect);
    NS_ENSURE_SUCCESS(rv, rv);

    aEvent->mSucceeded = PR_TRUE;
    return NS_OK;
}
nsresult
nsContentEventHandler::OnQueryCaretRect(nsQueryContentEvent* aEvent)
{
  nsresult rv = Init(aEvent);
  if (NS_FAILED(rv))
    return rv;

  nsRefPtr<nsCaret> caret = mPresShell->GetCaret();
  NS_ASSERTION(caret, "GetCaret returned null");

  // When the selection is collapsed and the queried offset is current caret
  // position, we should return the "real" caret rect.
  PRBool selectionIsCollapsed;
  rv = mSelection->GetIsCollapsed(&selectionIsCollapsed);
  NS_ENSURE_SUCCESS(rv, rv);

  if (selectionIsCollapsed) {
    PRUint32 offset;
    rv = GetFlatTextOffsetOfRange(mRootContent, mFirstSelectedRange, &offset);
    NS_ENSURE_SUCCESS(rv, rv);
    if (offset == aEvent->mInput.mOffset) {
      nsRect rect;
      nsIFrame* caretFrame = caret->GetGeometry(mSelection, &rect);
      if (!caretFrame)
        return NS_ERROR_FAILURE;
      rv = ConvertToRootViewRelativeOffset(caretFrame, rect);
      NS_ENSURE_SUCCESS(rv, rv);
      aEvent->mReply.mRect =
        rect.ToOutsidePixels(caretFrame->PresContext()->AppUnitsPerDevPixel());
      aEvent->mSucceeded = PR_TRUE;
      return NS_OK;
    }
  }

  // Otherwise, we should set the guessed caret rect.
  nsCOMPtr<nsIRange> range = new nsRange();
  NS_ENSURE_TRUE(range, NS_ERROR_OUT_OF_MEMORY);
  rv = SetRangeFromFlatTextOffset(range, aEvent->mInput.mOffset, 0, PR_TRUE);
  NS_ENSURE_SUCCESS(rv, rv);

  PRInt32 offsetInFrame;
  nsIFrame* frame;
  rv = GetStartFrameAndOffset(range, &frame, &offsetInFrame);
  NS_ENSURE_SUCCESS(rv, rv);

  nsPoint posInFrame;
  rv = frame->GetPointFromOffset(range->StartOffset(), &posInFrame);
  NS_ENSURE_SUCCESS(rv, rv);

  nsRect rect;
  rect.x = posInFrame.x;
  rect.y = posInFrame.y;
  rect.width = caret->GetCaretRect().width;
  rect.height = frame->GetSize().height;

  rv = ConvertToRootViewRelativeOffset(frame, rect);
  NS_ENSURE_SUCCESS(rv, rv);

  aEvent->mReply.mRect =
      rect.ToOutsidePixels(mPresContext->AppUnitsPerDevPixel());
  aEvent->mSucceeded = PR_TRUE;
  return NS_OK;
}