зеркало из https://github.com/mozilla/gecko-dev.git
Bug 987040 - Part 2: Add a flag indicate whether CollectClientRects should flush layout or not. r=ehsan
This commit is contained in:
Родитель
bdc2515786
Коммит
cc9241e019
|
@ -2749,13 +2749,17 @@ static void ExtractRectFromOffset(nsIFrame* aFrame,
|
|||
}
|
||||
|
||||
static nsTextFrame*
|
||||
GetTextFrameForContent(nsIContent* aContent)
|
||||
GetTextFrameForContent(nsIContent* aContent, bool aFlushLayout)
|
||||
{
|
||||
nsIPresShell* presShell = aContent->OwnerDoc()->GetShell();
|
||||
if (presShell) {
|
||||
presShell->FrameConstructor()->EnsureFrameForTextNode(
|
||||
static_cast<nsGenericDOMDataNode*>(aContent));
|
||||
aContent->OwnerDoc()->FlushPendingNotifications(Flush_Layout);
|
||||
|
||||
if (aFlushLayout) {
|
||||
aContent->OwnerDoc()->FlushPendingNotifications(Flush_Layout);
|
||||
}
|
||||
|
||||
nsIFrame* frame = aContent->GetPrimaryFrame();
|
||||
if (frame && frame->GetType() == nsGkAtoms::textFrame) {
|
||||
return static_cast<nsTextFrame*>(frame);
|
||||
|
@ -2766,9 +2770,10 @@ GetTextFrameForContent(nsIContent* aContent)
|
|||
|
||||
static nsresult GetPartialTextRect(nsLayoutUtils::RectCallback* aCallback,
|
||||
nsIContent* aContent, int32_t aStartOffset,
|
||||
int32_t aEndOffset, bool aClampToEdge)
|
||||
int32_t aEndOffset, bool aClampToEdge,
|
||||
bool aFlushLayout)
|
||||
{
|
||||
nsTextFrame* textFrame = GetTextFrameForContent(aContent);
|
||||
nsTextFrame* textFrame = GetTextFrameForContent(aContent, aFlushLayout);
|
||||
if (textFrame) {
|
||||
nsIFrame* relativeTo = nsLayoutUtils::GetContainingBlockForClientRect(textFrame);
|
||||
for (nsTextFrame* f = textFrame; f; f = static_cast<nsTextFrame*>(f->GetNextContinuation())) {
|
||||
|
@ -2801,7 +2806,7 @@ nsRange::CollectClientRects(nsLayoutUtils::RectCallback* aCollector,
|
|||
nsRange* aRange,
|
||||
nsINode* aStartParent, int32_t aStartOffset,
|
||||
nsINode* aEndParent, int32_t aEndOffset,
|
||||
bool aClampToEdge)
|
||||
bool aClampToEdge, bool aFlushLayout)
|
||||
{
|
||||
// Hold strong pointers across the flush
|
||||
nsCOMPtr<nsINode> startContainer = aStartParent;
|
||||
|
@ -2812,11 +2817,12 @@ nsRange::CollectClientRects(nsLayoutUtils::RectCallback* aCollector,
|
|||
return;
|
||||
}
|
||||
|
||||
aStartParent->OwnerDoc()->FlushPendingNotifications(Flush_Layout);
|
||||
|
||||
// Recheck whether we're still in the document
|
||||
if (!aStartParent->IsInDoc()) {
|
||||
return;
|
||||
if (aFlushLayout) {
|
||||
aStartParent->OwnerDoc()->FlushPendingNotifications(Flush_Layout);
|
||||
// Recheck whether we're still in the document
|
||||
if (!aStartParent->IsInDoc()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
RangeSubtreeIterator iter;
|
||||
|
@ -2828,7 +2834,7 @@ nsRange::CollectClientRects(nsLayoutUtils::RectCallback* aCollector,
|
|||
// the range is collapsed, only continue if the cursor is in a text node
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(aStartParent);
|
||||
if (content && content->IsNodeOfType(nsINode::eTEXT)) {
|
||||
nsTextFrame* textFrame = GetTextFrameForContent(content);
|
||||
nsTextFrame* textFrame = GetTextFrameForContent(content, aFlushLayout);
|
||||
if (textFrame) {
|
||||
int32_t outOffset;
|
||||
nsIFrame* outFrame;
|
||||
|
@ -2858,10 +2864,12 @@ nsRange::CollectClientRects(nsLayoutUtils::RectCallback* aCollector,
|
|||
if (node == startContainer) {
|
||||
int32_t offset = startContainer == endContainer ?
|
||||
aEndOffset : content->GetText()->GetLength();
|
||||
GetPartialTextRect(aCollector, content, aStartOffset, offset, aClampToEdge);
|
||||
GetPartialTextRect(aCollector, content, aStartOffset, offset,
|
||||
aClampToEdge, aFlushLayout);
|
||||
continue;
|
||||
} else if (node == endContainer) {
|
||||
GetPartialTextRect(aCollector, content, 0, aEndOffset, aClampToEdge);
|
||||
GetPartialTextRect(aCollector, content, 0, aEndOffset,
|
||||
aClampToEdge, aFlushLayout);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -2883,7 +2891,7 @@ nsRange::GetBoundingClientRect(nsIDOMClientRect** aResult)
|
|||
}
|
||||
|
||||
already_AddRefed<DOMRect>
|
||||
nsRange::GetBoundingClientRect(bool aClampToEdge)
|
||||
nsRange::GetBoundingClientRect(bool aClampToEdge, bool aFlushLayout)
|
||||
{
|
||||
nsRefPtr<DOMRect> rect = new DOMRect(ToSupports(this));
|
||||
if (!mStartParent) {
|
||||
|
@ -2892,7 +2900,7 @@ nsRange::GetBoundingClientRect(bool aClampToEdge)
|
|||
|
||||
nsLayoutUtils::RectAccumulator accumulator;
|
||||
CollectClientRects(&accumulator, this, mStartParent, mStartOffset,
|
||||
mEndParent, mEndOffset, aClampToEdge);
|
||||
mEndParent, mEndOffset, aClampToEdge, aFlushLayout);
|
||||
|
||||
nsRect r = accumulator.mResultRect.IsEmpty() ? accumulator.mFirstRect :
|
||||
accumulator.mResultRect;
|
||||
|
@ -2908,7 +2916,7 @@ nsRange::GetClientRects(nsIDOMClientRectList** aResult)
|
|||
}
|
||||
|
||||
already_AddRefed<DOMRectList>
|
||||
nsRange::GetClientRects(bool aClampToEdge)
|
||||
nsRange::GetClientRects(bool aClampToEdge, bool aFlushLayout)
|
||||
{
|
||||
if (!mStartParent) {
|
||||
return nullptr;
|
||||
|
@ -2920,7 +2928,7 @@ nsRange::GetClientRects(bool aClampToEdge)
|
|||
nsLayoutUtils::RectListBuilder builder(rectList);
|
||||
|
||||
CollectClientRects(&builder, this, mStartParent, mStartOffset,
|
||||
mEndParent, mEndOffset, aClampToEdge);
|
||||
mEndParent, mEndOffset, aClampToEdge, aFlushLayout);
|
||||
return rectList.forget();
|
||||
}
|
||||
|
||||
|
|
|
@ -217,8 +217,10 @@ public:
|
|||
void SetStartAfter(nsINode& aNode, ErrorResult& aErr);
|
||||
void SetStartBefore(nsINode& aNode, ErrorResult& aErr);
|
||||
void SurroundContents(nsINode& aNode, ErrorResult& aErr);
|
||||
already_AddRefed<DOMRect> GetBoundingClientRect(bool aClampToEdge = true);
|
||||
already_AddRefed<DOMRectList> GetClientRects(bool aClampToEdge = true);
|
||||
already_AddRefed<DOMRect> GetBoundingClientRect(bool aClampToEdge = true,
|
||||
bool aFlushLayout = true);
|
||||
already_AddRefed<DOMRectList> GetClientRects(bool aClampToEdge = true,
|
||||
bool aFlushLayout = true);
|
||||
|
||||
nsINode* GetParentObject() const { return mOwner; }
|
||||
virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE MOZ_FINAL;
|
||||
|
@ -260,7 +262,7 @@ public:
|
|||
nsRange* aRange,
|
||||
nsINode* aStartParent, int32_t aStartOffset,
|
||||
nsINode* aEndParent, int32_t aEndOffset,
|
||||
bool aClampToEdge);
|
||||
bool aClampToEdge, bool aFlushLayout);
|
||||
|
||||
typedef nsTHashtable<nsPtrHashKey<nsRange> > RangeHashTable;
|
||||
protected:
|
||||
|
|
|
@ -9279,7 +9279,7 @@ nsGlobalWindow::UpdateCommands(const nsAString& anAction, nsISelection* aSel, in
|
|||
nsresult rv = aSel->GetRangeAt(0, getter_AddRefs(range));
|
||||
if (NS_SUCCEEDED(rv) && range) {
|
||||
nsRefPtr<nsRange> nsrange = static_cast<nsRange*>(range.get());
|
||||
init.mBoundingClientRect = nsrange->GetBoundingClientRect(true);
|
||||
init.mBoundingClientRect = nsrange->GetBoundingClientRect(true, false);
|
||||
range->ToString(init.mSelectedText);
|
||||
init.mReason = aReason;
|
||||
}
|
||||
|
|
|
@ -382,7 +382,7 @@ SelectionCarets::UpdateSelectionCarets()
|
|||
nsLayoutUtils::FirstAndLastRectCollector collector;
|
||||
nsRange::CollectClientRects(&collector, range,
|
||||
range->GetStartParent(), range->StartOffset(),
|
||||
range->GetEndParent(), range->EndOffset(), true);
|
||||
range->GetEndParent(), range->EndOffset(), true, true);
|
||||
|
||||
nsIFrame* canvasFrame = mPresShell->GetCanvasFrame();
|
||||
nsIFrame* rootFrame = mPresShell->GetRootFrame();
|
||||
|
|
Загрузка…
Ссылка в новой задаче