nsresult nsQueryContentEventHandler::OnQuerySelectedText(nsQueryContentEvent* aEvent) { nsresult rv = Init(aEvent); if (NS_FAILED(rv)) return rv; NS_ASSERTION(aEvent->mReply.mString.IsEmpty(), "The reply string must be empty"); rv = GetFlatTextOffsetOfRange(mFirstSelectedRange, &aEvent->mReply.mOffset); NS_ENSURE_SUCCESS(rv, rv); PRBool isCollapsed; rv = mSelection->GetIsCollapsed(&isCollapsed); NS_ENSURE_SUCCESS(rv, rv); if (!isCollapsed) { nsCOMPtr<nsIDOMRange> domRange; rv = mSelection->GetRangeAt(0, getter_AddRefs(domRange)); NS_ENSURE_SUCCESS(rv, rv); NS_ASSERTION(domRange, "GetRangeAt succeeded, but the result is null"); nsCOMPtr<nsIRange> range(do_QueryInterface(domRange)); NS_ENSURE_TRUE(range, NS_ERROR_FAILURE); rv = GenerateFlatTextContent(range, aEvent->mReply.mString); NS_ENSURE_SUCCESS(rv, rv); } aEvent->mSucceeded = PR_TRUE; return NS_OK; }
nsresult nsContentEventHandler::GetFlatTextOffsetOfRange(nsIContent* aRootContent, nsIRange* aRange, PRUint32* aNativeOffset) { nsINode* startNode = aRange->GetStartParent(); NS_ENSURE_TRUE(startNode, NS_ERROR_FAILURE); PRInt32 startOffset = aRange->StartOffset(); return GetFlatTextOffsetOfRange(aRootContent, startNode, startOffset, aNativeOffset); }
nsresult nsContentEventHandler::OnQuerySelectedText(nsQueryContentEvent* aEvent) { nsresult rv = Init(aEvent); if (NS_FAILED(rv)) return rv; NS_ASSERTION(aEvent->mReply.mString.IsEmpty(), "The reply string must be empty"); rv = GetFlatTextOffsetOfRange(mRootContent, mFirstSelectedRange, &aEvent->mReply.mOffset); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIDOMNode> anchorDomNode, focusDomNode; rv = mSelection->GetAnchorNode(getter_AddRefs(anchorDomNode)); NS_ENSURE_TRUE(anchorDomNode, NS_ERROR_FAILURE); rv = mSelection->GetFocusNode(getter_AddRefs(focusDomNode)); NS_ENSURE_TRUE(focusDomNode, NS_ERROR_FAILURE); PRInt32 anchorOffset, focusOffset; rv = mSelection->GetAnchorOffset(&anchorOffset); NS_ENSURE_SUCCESS(rv, rv); rv = mSelection->GetFocusOffset(&focusOffset); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsINode> anchorNode(do_QueryInterface(anchorDomNode)); nsCOMPtr<nsINode> focusNode(do_QueryInterface(focusDomNode)); NS_ENSURE_TRUE(anchorNode && focusNode, NS_ERROR_UNEXPECTED); PRInt16 compare = nsContentUtils::ComparePoints(anchorNode, anchorOffset, focusNode, focusOffset); aEvent->mReply.mReversed = compare > 0; if (compare) { nsCOMPtr<nsIRange> range = mFirstSelectedRange; rv = GenerateFlatTextContent(range, aEvent->mReply.mString); NS_ENSURE_SUCCESS(rv, rv); } aEvent->mSucceeded = PR_TRUE; return NS_OK; }
nsresult nsQueryContentEventHandler::OnQueryCaretRect(nsQueryContentEvent* aEvent) { nsresult rv = Init(aEvent); if (NS_FAILED(rv)) return rv; nsCOMPtr<nsICaret> caret; rv = mPresShell->GetCaret(getter_AddRefs(caret)); NS_ENSURE_SUCCESS(rv, rv); NS_ASSERTION(caret, "GetCaret succeeded, but the result is 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(mFirstSelectedRange, &offset); NS_ENSURE_SUCCESS(rv, rv); if (offset == aEvent->mInput.mOffset) { PRBool isCollapsed; rv = caret->GetCaretCoordinates(nsICaret::eTopLevelWindowCoordinates, mSelection, &aEvent->mReply.mRect, &isCollapsed, nsnull); NS_ENSURE_SUCCESS(rv, rv); 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); return QueryRectFor(aEvent, range, caret); }
nsresult nsContentEventHandler::OnQueryCharacterAtPoint(nsQueryContentEvent* aEvent) { nsresult rv = Init(aEvent); if (NS_FAILED(rv)) return rv; nsIFrame* rootFrame = mPresShell->GetRootFrame(); NS_ENSURE_TRUE(rootFrame, NS_ERROR_FAILURE); nsIWidget* rootWidget = rootFrame->GetNearestWidget(); NS_ENSURE_TRUE(rootWidget, NS_ERROR_FAILURE); // The root frame's widget might be different, e.g., the event was fired on // a popup but the rootFrame is the document root. if (rootWidget != aEvent->widget) { NS_PRECONDITION(aEvent->widget, "The event must have the widget"); nsIView* view = nsIView::GetViewFor(aEvent->widget); NS_ENSURE_TRUE(view, NS_ERROR_FAILURE); rootFrame = nsLayoutUtils::GetFrameFor(view); NS_ENSURE_TRUE(rootFrame, NS_ERROR_FAILURE); rootWidget = rootFrame->GetNearestWidget(); NS_ENSURE_TRUE(rootWidget, NS_ERROR_FAILURE); } nsQueryContentEvent eventOnRoot(PR_TRUE, NS_QUERY_CHARACTER_AT_POINT, rootWidget); eventOnRoot.refPoint = aEvent->refPoint; if (rootWidget != aEvent->widget) { eventOnRoot.refPoint += aEvent->widget->WidgetToScreenOffset(); eventOnRoot.refPoint -= rootWidget->WidgetToScreenOffset(); } nsPoint ptInRoot = nsLayoutUtils::GetEventCoordinatesRelativeTo(&eventOnRoot, rootFrame); nsIFrame* targetFrame = nsLayoutUtils::GetFrameForPoint(rootFrame, ptInRoot); if (!targetFrame || targetFrame->GetType() != nsGkAtoms::textFrame || !targetFrame->GetContent() || !nsContentUtils::ContentIsDescendantOf(targetFrame->GetContent(), mRootContent)) { // there is no character at the point. aEvent->mReply.mOffset = nsQueryContentEvent::NOT_FOUND; aEvent->mSucceeded = PR_TRUE; return NS_OK; } nsPoint ptInTarget = ptInRoot + rootFrame->GetOffsetToCrossDoc(targetFrame); PRInt32 rootAPD = rootFrame->PresContext()->AppUnitsPerDevPixel(); PRInt32 targetAPD = targetFrame->PresContext()->AppUnitsPerDevPixel(); ptInTarget = ptInTarget.ConvertAppUnits(rootAPD, targetAPD); nsTextFrame* textframe = static_cast<nsTextFrame*>(targetFrame); nsIFrame::ContentOffsets offsets = textframe->GetCharacterOffsetAtFramePoint(ptInTarget); NS_ENSURE_TRUE(offsets.content, NS_ERROR_FAILURE); PRUint32 nativeOffset; rv = GetFlatTextOffsetOfRange(mRootContent, offsets.content, offsets.offset, &nativeOffset); NS_ENSURE_SUCCESS(rv, rv); nsQueryContentEvent textRect(PR_TRUE, NS_QUERY_TEXT_RECT, aEvent->widget); textRect.InitForQueryTextRect(nativeOffset, 1); rv = OnQueryTextRect(&textRect); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_TRUE(textRect.mSucceeded, NS_ERROR_FAILURE); // currently, we don't need to get the actual text. aEvent->mReply.mOffset = nativeOffset; aEvent->mReply.mRect = textRect.mReply.mRect; 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; }