Bug 864595 - Provide a option which indicate to that offsets outside the frame box are allowed. [r=roc]

This commit is contained in:
Morris Tseng 2014-06-27 13:58:57 -07:00
parent 9bff9ee655
commit c7a843c3cd
4 changed files with 32 additions and 23 deletions

View File

@ -51,7 +51,7 @@ nsDOMCaretPosition::GetClientRect() const
NS_ASSERTION(domRange, "unable to retrieve valid dom range from CaretPosition");
rect = domRange->GetBoundingClientRect();
rect = domRange->GetBoundingClientRect(false);
return rect.forget();
}

View File

@ -2725,17 +2725,23 @@ nsRange::CreateContextualFragment(const nsAString& aFragment, ErrorResult& aRv)
static void ExtractRectFromOffset(nsIFrame* aFrame,
const nsIFrame* aRelativeTo,
const int32_t aOffset, nsRect* aR, bool aKeepLeft)
const int32_t aOffset, nsRect* aR, bool aKeepLeft,
bool aClampToEdge)
{
nsPoint point;
aFrame->GetPointFromOffset(aOffset, &point);
point += aFrame->GetOffsetTo(aRelativeTo);
//given a point.x, extract left or right portion of rect aR
//point.x has to be within this rect
NS_ASSERTION(aR->x <= point.x && point.x <= aR->XMost(),
"point.x should not be outside of rect r");
if (!aClampToEdge && !aR->Contains(point)) {
aR->width = 0;
aR->x = point.x;
return;
}
if (aClampToEdge) {
point = aR->ClampPoint(point);
}
if (aKeepLeft) {
aR->width = point.x - aR->x;
@ -2762,7 +2768,8 @@ GetTextFrameForContent(nsIContent* aContent)
}
static nsresult GetPartialTextRect(nsLayoutUtils::RectCallback* aCallback,
nsIContent* aContent, int32_t aStartOffset, int32_t aEndOffset)
nsIContent* aContent, int32_t aStartOffset,
int32_t aEndOffset, bool aClampToEdge)
{
nsTextFrame* textFrame = GetTextFrameForContent(aContent);
if (textFrame) {
@ -2779,11 +2786,11 @@ static nsresult GetPartialTextRect(nsLayoutUtils::RectCallback* aCallback,
nsRect r(f->GetOffsetTo(relativeTo), f->GetSize());
if (fstart < aStartOffset) {
// aStartOffset is within this frame
ExtractRectFromOffset(f, relativeTo, aStartOffset, &r, rtl);
ExtractRectFromOffset(f, relativeTo, aStartOffset, &r, rtl, aClampToEdge);
}
if (fend > aEndOffset) {
// aEndOffset is in the middle of this frame
ExtractRectFromOffset(f, relativeTo, aEndOffset, &r, !rtl);
ExtractRectFromOffset(f, relativeTo, aEndOffset, &r, !rtl, aClampToEdge);
}
aCallback->AddRect(r);
}
@ -2795,7 +2802,8 @@ static nsresult GetPartialTextRect(nsLayoutUtils::RectCallback* aCallback,
nsRange::CollectClientRects(nsLayoutUtils::RectCallback* aCollector,
nsRange* aRange,
nsINode* aStartParent, int32_t aStartOffset,
nsINode* aEndParent, int32_t aEndOffset)
nsINode* aEndParent, int32_t aEndOffset,
bool aClampToEdge)
{
// Hold strong pointers across the flush
nsCOMPtr<nsINode> startContainer = aStartParent;
@ -2832,7 +2840,7 @@ nsRange::CollectClientRects(nsLayoutUtils::RectCallback* aCollector,
nsIFrame* relativeTo =
nsLayoutUtils::GetContainingBlockForClientRect(outFrame);
nsRect r(outFrame->GetOffsetTo(relativeTo), outFrame->GetSize());
ExtractRectFromOffset(outFrame, relativeTo, aStartOffset, &r, false);
ExtractRectFromOffset(outFrame, relativeTo, aStartOffset, &r, false, aClampToEdge);
r.width = 0;
aCollector->AddRect(r);
}
@ -2851,10 +2859,10 @@ nsRange::CollectClientRects(nsLayoutUtils::RectCallback* aCollector,
if (node == startContainer) {
int32_t offset = startContainer == endContainer ?
aEndOffset : content->GetText()->GetLength();
GetPartialTextRect(aCollector, content, aStartOffset, offset);
GetPartialTextRect(aCollector, content, aStartOffset, offset, aClampToEdge);
continue;
} else if (node == endContainer) {
GetPartialTextRect(aCollector, content, 0, aEndOffset);
GetPartialTextRect(aCollector, content, 0, aEndOffset, aClampToEdge);
continue;
}
}
@ -2870,12 +2878,12 @@ nsRange::CollectClientRects(nsLayoutUtils::RectCallback* aCollector,
NS_IMETHODIMP
nsRange::GetBoundingClientRect(nsIDOMClientRect** aResult)
{
*aResult = GetBoundingClientRect().take();
*aResult = GetBoundingClientRect(true).take();
return NS_OK;
}
already_AddRefed<DOMRect>
nsRange::GetBoundingClientRect()
nsRange::GetBoundingClientRect(bool aClampToEdge)
{
nsRefPtr<DOMRect> rect = new DOMRect(ToSupports(this));
if (!mStartParent) {
@ -2884,7 +2892,7 @@ nsRange::GetBoundingClientRect()
nsLayoutUtils::RectAccumulator accumulator;
CollectClientRects(&accumulator, this, mStartParent, mStartOffset,
mEndParent, mEndOffset);
mEndParent, mEndOffset, aClampToEdge);
nsRect r = accumulator.mResultRect.IsEmpty() ? accumulator.mFirstRect :
accumulator.mResultRect;
@ -2895,12 +2903,12 @@ nsRange::GetBoundingClientRect()
NS_IMETHODIMP
nsRange::GetClientRects(nsIDOMClientRectList** aResult)
{
*aResult = GetClientRects().take();
*aResult = GetClientRects(true).take();
return NS_OK;
}
already_AddRefed<DOMRectList>
nsRange::GetClientRects()
nsRange::GetClientRects(bool aClampToEdge)
{
if (!mStartParent) {
return nullptr;
@ -2912,7 +2920,7 @@ nsRange::GetClientRects()
nsLayoutUtils::RectListBuilder builder(rectList);
CollectClientRects(&builder, this, mStartParent, mStartOffset,
mEndParent, mEndOffset);
mEndParent, mEndOffset, aClampToEdge);
return rectList.forget();
}

View File

@ -217,8 +217,8 @@ public:
void SetStartAfter(nsINode& aNode, ErrorResult& aErr);
void SetStartBefore(nsINode& aNode, ErrorResult& aErr);
void SurroundContents(nsINode& aNode, ErrorResult& aErr);
already_AddRefed<DOMRect> GetBoundingClientRect();
already_AddRefed<DOMRectList> GetClientRects();
already_AddRefed<DOMRect> GetBoundingClientRect(bool aClampToEdge = true);
already_AddRefed<DOMRectList> GetClientRects(bool aClampToEdge = true);
nsINode* GetParentObject() const { return mOwner; }
virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE MOZ_FINAL;
@ -259,7 +259,8 @@ public:
static void CollectClientRects(nsLayoutUtils::RectCallback* aCollector,
nsRange* aRange,
nsINode* aStartParent, int32_t aStartOffset,
nsINode* aEndParent, int32_t aEndOffset);
nsINode* aEndParent, int32_t aEndOffset,
bool aClampToEdge);
typedef nsTHashtable<nsPtrHashKey<nsRange> > RangeHashTable;
protected:

View File

@ -382,7 +382,7 @@ SelectionCarets::UpdateSelectionCarets()
nsLayoutUtils::FirstAndLastRectCollector collector;
nsRange::CollectClientRects(&collector, range,
range->GetStartParent(), range->StartOffset(),
range->GetEndParent(), range->EndOffset());
range->GetEndParent(), range->EndOffset(), true);
nsIFrame* canvasFrame = mPresShell->GetCanvasFrame();
nsIFrame* rootFrame = mPresShell->GetRootFrame();