Bug 1120750 - Part 1: Move GetSelectionBoundingRect to nsContentUtils. r=roc

This commit is contained in:
Morris Tseng 2015-02-04 21:58:00 -05:00
parent 67b3ab2787
commit f6684364a0
4 changed files with 44 additions and 34 deletions

View File

@ -60,6 +60,7 @@
#include "nsAttrValue.h"
#include "nsAttrValueInlines.h"
#include "nsBindingManager.h"
#include "nsCaret.h"
#include "nsCCUncollectableMarker.h"
#include "nsCharSeparatedTokenizer.h"
#include "nsCOMPtr.h"
@ -6798,6 +6799,39 @@ nsContentUtils::GetSelectionInTextControl(Selection* aSelection,
aOutEndOffset = std::max(anchorOffset, focusOffset);
}
/* static */
nsRect
nsContentUtils::GetSelectionBoundingRect(Selection* aSel)
{
nsRect res;
// Bounding client rect may be empty after calling GetBoundingClientRect
// when range is collapsed. So we get caret's rect when range is
// collapsed.
if (aSel->IsCollapsed()) {
nsIFrame* frame = nsCaret::GetGeometry(aSel, &res);
if (frame) {
nsIFrame* relativeTo =
nsLayoutUtils::GetContainingBlockForClientRect(frame);
res = nsLayoutUtils::TransformFrameRectToAncestor(frame, res, relativeTo);
}
} else {
int32_t rangeCount = aSel->GetRangeCount();
nsLayoutUtils::RectAccumulator accumulator;
for (int32_t idx = 0; idx < rangeCount; ++idx) {
nsRange* range = aSel->GetRangeAt(idx);
nsRange::CollectClientRects(&accumulator, range,
range->GetStartParent(), range->StartOffset(),
range->GetEndParent(), range->EndOffset(),
true, false);
}
res = accumulator.mResultRect.IsEmpty() ? accumulator.mFirstRect :
accumulator.mResultRect;
}
return res;
}
nsIEditor*
nsContentUtils::GetHTMLEditor(nsPresContext* aPresContext)
{

View File

@ -2176,6 +2176,14 @@ public:
int32_t& aOutStartOffset,
int32_t& aOutEndOffset);
/**
* Takes a selection, and return selection's bounding rect which is relative
* to root frame.
*
* @param aSel Selection to check
*/
static nsRect GetSelectionBoundingRect(mozilla::dom::Selection* aSel);
/**
* Takes a frame for anonymous content within a text control (<input> or
* <textarea>), and returns an offset in the text content, adjusted for a

View File

@ -500,7 +500,7 @@ SelectionCarets::UpdateSelectionCarets()
nsIFrame* commonAncestorFrame =
nsLayoutUtils::FindNearestCommonAncestorFrame(startFrame, endFrame);
nsRect selectionRectInRootFrame = GetSelectionBoundingRect(selection);
nsRect selectionRectInRootFrame = nsContentUtils::GetSelectionBoundingRect(selection);
nsRect selectionRectInCommonAncestorFrame = selectionRectInRootFrame;
nsLayoutUtils::TransformRect(rootFrame, commonAncestorFrame,
selectionRectInCommonAncestorFrame);
@ -1029,37 +1029,6 @@ GetSelectionStates(int16_t aReason)
return states;
}
nsRect
SelectionCarets::GetSelectionBoundingRect(Selection* aSel)
{
nsRect res;
// Bounding client rect may be empty after calling GetBoundingClientRect
// when range is collapsed. So we get caret's rect when range is
// collapsed.
if (aSel->IsCollapsed()) {
nsIFrame* frame = nsCaret::GetGeometry(aSel, &res);
if (frame) {
nsIFrame* relativeTo =
nsLayoutUtils::GetContainingBlockForClientRect(frame);
res = nsLayoutUtils::TransformFrameRectToAncestor(frame, res, relativeTo);
}
} else {
int32_t rangeCount = aSel->GetRangeCount();
nsLayoutUtils::RectAccumulator accumulator;
for (int32_t idx = 0; idx < rangeCount; ++idx) {
nsRange* range = aSel->GetRangeAt(idx);
nsRange::CollectClientRects(&accumulator, range,
range->GetStartParent(), range->StartOffset(),
range->GetEndParent(), range->EndOffset(),
true, false);
}
res = accumulator.mResultRect.IsEmpty() ? accumulator.mFirstRect :
accumulator.mResultRect;
}
return res;
}
void
SelectionCarets::DispatchCustomEvent(const nsAString& aEvent)
{
@ -1098,7 +1067,7 @@ SelectionCarets::DispatchSelectionStateChangedEvent(Selection* aSelection,
if (aSelection) {
// XXX: Do we need to flush layout?
mPresShell->FlushPendingNotifications(Flush_Layout);
nsRect rect = GetSelectionBoundingRect(aSelection);
nsRect rect = nsContentUtils::GetSelectionBoundingRect(aSelection);
nsRefPtr<DOMRect>domRect = new DOMRect(ToSupports(doc));
domRect->SetLayoutRect(rect);

View File

@ -208,7 +208,6 @@ private:
void DispatchSelectionStateChangedEvent(dom::Selection* aSelection,
const dom::Sequence<dom::SelectionState>& aStates);
void DispatchCustomEvent(const nsAString& aEvent);
nsRect GetSelectionBoundingRect(dom::Selection* aSel);
/**
* Detecting long tap using timer