mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-12 12:55:46 +00:00
Bug 754480 - Remove PresShell members associated with mContentToScrollTo, put that data in a temporary content property instead. part=3/3 r=bz
This commit is contained in:
parent
7268272a07
commit
eef4cdb2e4
@ -914,7 +914,10 @@ PresShell::Destroy()
|
||||
NS_RELEASE(gKeyDownTarget);
|
||||
}
|
||||
|
||||
mContentToScrollTo = nsnull;
|
||||
if (mContentToScrollTo) {
|
||||
mContentToScrollTo->DeleteProperty(nsGkAtoms::scrolling);
|
||||
mContentToScrollTo = nsnull;
|
||||
}
|
||||
|
||||
if (mPresContext) {
|
||||
// We need to notify the destroying the nsPresContext to ESM for
|
||||
@ -3149,23 +3152,39 @@ static void ScrollToShowRect(nsIScrollableFrame* aScrollFrame,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
DeleteScrollIntoViewData(void* aObject, nsIAtom* aPropertyName,
|
||||
void* aPropertyValue, void* aData)
|
||||
{
|
||||
PresShell::ScrollIntoViewData* data =
|
||||
static_cast<PresShell::ScrollIntoViewData*>(aPropertyValue);
|
||||
delete data;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PresShell::ScrollContentIntoView(nsIContent* aContent,
|
||||
nsIPresShell::ScrollAxis aVertical,
|
||||
nsIPresShell::ScrollAxis aHorizontal,
|
||||
PRUint32 aFlags)
|
||||
{
|
||||
nsCOMPtr<nsIContent> content = aContent; // Keep content alive while flushing.
|
||||
NS_ENSURE_TRUE(content, NS_ERROR_NULL_POINTER);
|
||||
nsCOMPtr<nsIDocument> currentDoc = content->GetCurrentDoc();
|
||||
NS_ENSURE_TRUE(aContent, NS_ERROR_NULL_POINTER);
|
||||
nsCOMPtr<nsIDocument> currentDoc = aContent->GetCurrentDoc();
|
||||
NS_ENSURE_STATE(currentDoc);
|
||||
|
||||
NS_ASSERTION(mDidInitialReflow, "should have done initial reflow by now");
|
||||
|
||||
if (mContentToScrollTo) {
|
||||
mContentToScrollTo->DeleteProperty(nsGkAtoms::scrolling);
|
||||
}
|
||||
mContentToScrollTo = aContent;
|
||||
mContentScrollVAxis = aVertical;
|
||||
mContentScrollHAxis = aHorizontal;
|
||||
mContentToScrollToFlags = aFlags;
|
||||
ScrollIntoViewData* data = new ScrollIntoViewData();
|
||||
data->mContentScrollVAxis = aVertical;
|
||||
data->mContentScrollHAxis = aHorizontal;
|
||||
data->mContentToScrollToFlags = aFlags;
|
||||
if (NS_FAILED(mContentToScrollTo->SetProperty(nsGkAtoms::scrolling, data,
|
||||
::DeleteScrollIntoViewData))) {
|
||||
mContentToScrollTo = nsnull;
|
||||
}
|
||||
|
||||
// Flush layout and attempt to scroll in the process.
|
||||
currentDoc->SetNeedLayoutFlush();
|
||||
@ -3180,21 +3199,19 @@ PresShell::ScrollContentIntoView(nsIContent* aContent,
|
||||
// than a single best-effort scroll followed by one final scroll on the first
|
||||
// completed reflow.
|
||||
if (mContentToScrollTo) {
|
||||
DoScrollContentIntoView(content, aVertical, aHorizontal, aFlags);
|
||||
DoScrollContentIntoView();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
PresShell::DoScrollContentIntoView(nsIContent* aContent,
|
||||
nsIPresShell::ScrollAxis aVertical,
|
||||
nsIPresShell::ScrollAxis aHorizontal,
|
||||
PRUint32 aFlags)
|
||||
PresShell::DoScrollContentIntoView()
|
||||
{
|
||||
NS_ASSERTION(mDidInitialReflow, "should have done initial reflow by now");
|
||||
|
||||
nsIFrame* frame = aContent->GetPrimaryFrame();
|
||||
nsIFrame* frame = mContentToScrollTo->GetPrimaryFrame();
|
||||
if (!frame) {
|
||||
mContentToScrollTo->DeleteProperty(nsGkAtoms::scrolling);
|
||||
mContentToScrollTo = nsnull;
|
||||
return;
|
||||
}
|
||||
@ -3213,6 +3230,13 @@ PresShell::DoScrollContentIntoView(nsIContent* aContent,
|
||||
return;
|
||||
}
|
||||
|
||||
ScrollIntoViewData* data = static_cast<ScrollIntoViewData*>(
|
||||
mContentToScrollTo->GetProperty(nsGkAtoms::scrolling));
|
||||
if (NS_UNLIKELY(!data)) {
|
||||
mContentToScrollTo = nsnull;
|
||||
return;
|
||||
}
|
||||
|
||||
// This is a two-step process.
|
||||
// Step 1: Find the bounds of the rect we want to scroll into view. For
|
||||
// example, for an inline frame we may want to scroll in the whole
|
||||
@ -3225,7 +3249,8 @@ PresShell::DoScrollContentIntoView(nsIContent* aContent,
|
||||
// even if that assumption was false.)
|
||||
nsRect frameBounds;
|
||||
bool haveRect = false;
|
||||
bool useWholeLineHeightForInlines = aVertical.mWhenToScroll != nsIPresShell::SCROLL_IF_NOT_FULLY_VISIBLE;
|
||||
bool useWholeLineHeightForInlines =
|
||||
data->mContentScrollVAxis.mWhenToScroll != nsIPresShell::SCROLL_IF_NOT_FULLY_VISIBLE;
|
||||
// Reuse the same line iterator across calls to AccumulateFrameBounds. We set
|
||||
// it every time we detect a new block (stored in prevBlock).
|
||||
nsIFrame* prevBlock = nsnull;
|
||||
@ -3238,8 +3263,9 @@ PresShell::DoScrollContentIntoView(nsIContent* aContent,
|
||||
frameBounds, haveRect, prevBlock, lines, curLine);
|
||||
} while ((frame = frame->GetNextContinuation()));
|
||||
|
||||
ScrollFrameRectIntoView(container, frameBounds, aVertical, aHorizontal,
|
||||
aFlags);
|
||||
ScrollFrameRectIntoView(container, frameBounds, data->mContentScrollVAxis,
|
||||
data->mContentScrollHAxis,
|
||||
data->mContentToScrollToFlags);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -3836,11 +3862,11 @@ PresShell::FlushPendingNotifications(mozFlushType aType)
|
||||
mViewManager->FlushDelayedResize(true);
|
||||
if (ProcessReflowCommands(aType < Flush_Layout) && mContentToScrollTo) {
|
||||
// We didn't get interrupted. Go ahead and scroll to our content
|
||||
DoScrollContentIntoView(mContentToScrollTo,
|
||||
mContentScrollVAxis,
|
||||
mContentScrollHAxis,
|
||||
mContentToScrollToFlags);
|
||||
mContentToScrollTo = nsnull;
|
||||
DoScrollContentIntoView();
|
||||
if (mContentToScrollTo) {
|
||||
mContentToScrollTo->DeleteProperty(nsGkAtoms::scrolling);
|
||||
mContentToScrollTo = nsnull;
|
||||
}
|
||||
}
|
||||
} else if (!mIsDestroying && mSuppressInterruptibleReflows &&
|
||||
aType == Flush_InterruptibleLayout) {
|
||||
|
@ -362,6 +362,14 @@ public:
|
||||
size_t *aPresContextSize) const;
|
||||
size_t SizeOfTextRuns(nsMallocSizeOfFun aMallocSizeOf) const;
|
||||
|
||||
// This data is stored as a content property (nsGkAtoms::scrolling) on
|
||||
// mContentToScrollTo when we have a pending ScrollIntoView.
|
||||
struct ScrollIntoViewData {
|
||||
ScrollAxis mContentScrollVAxis;
|
||||
ScrollAxis mContentScrollHAxis;
|
||||
PRUint32 mContentToScrollToFlags;
|
||||
};
|
||||
|
||||
protected:
|
||||
virtual ~PresShell();
|
||||
|
||||
@ -408,10 +416,7 @@ protected:
|
||||
#endif
|
||||
|
||||
// Helper for ScrollContentIntoView
|
||||
void DoScrollContentIntoView(nsIContent* aContent,
|
||||
ScrollAxis aVertical,
|
||||
ScrollAxis aHorizontal,
|
||||
PRUint32 aFlags);
|
||||
void DoScrollContentIntoView();
|
||||
|
||||
friend struct AutoRenderingStateSaveRestore;
|
||||
friend struct RenderingState;
|
||||
@ -774,12 +779,9 @@ protected:
|
||||
// Information needed to properly handle scrolling content into view if the
|
||||
// pre-scroll reflow flush can be interrupted. mContentToScrollTo is
|
||||
// non-null between the initial scroll attempt and the first time we finish
|
||||
// processing all our dirty roots. mContentScrollVPosition and
|
||||
// mContentScrollHPosition are only used when it's non-null.
|
||||
// processing all our dirty roots. mContentToScrollTo has a content property
|
||||
// storing the details for the scroll operation, see ScrollIntoViewData above.
|
||||
nsCOMPtr<nsIContent> mContentToScrollTo;
|
||||
ScrollAxis mContentScrollVAxis;
|
||||
ScrollAxis mContentScrollHAxis;
|
||||
PRUint32 mContentToScrollToFlags;
|
||||
|
||||
nscoord mLastAnchorScrollPositionY;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user