Bug 305120. Make overflow/underflow events be posted by HTML again. Also, only post an overflow event when we go from not-overflowing to overflowing instead of every time we reflow with overflow. r+sr=dbaron

This commit is contained in:
roc+%cs.cmu.edu 2005-08-31 00:57:27 +00:00
Родитель 05ec30a017
Коммит 2dac54badf
2 изменённых файлов: 38 добавлений и 47 удалений

Просмотреть файл

@ -689,6 +689,8 @@ nsHTMLScrollFrame::PlaceScrollArea(const ScrollReflowState& aState)
mInner.mScrolledFrame->GetView(),
&childRect,
NS_FRAME_NO_MOVE_VIEW);
mInner.PostOverflowEvents();
}
PRBool
@ -950,9 +952,7 @@ NS_NewXULScrollFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRBool aIsR
nsXULScrollFrame::nsXULScrollFrame(nsIPresShell* aShell, PRBool aIsRoot)
: nsBoxFrame(aShell, aIsRoot),
mInner(this, aIsRoot),
mMaxElementWidth(0),
mHorizontalOverflow(PR_FALSE),
mVerticalOverflow(PR_FALSE)
mMaxElementWidth(0)
{
SetLayoutManager(nsnull);
}
@ -1353,7 +1353,9 @@ nsGfxScrollFrameInner::nsGfxScrollFrameInner(nsContainerFrame* aOuter, PRBool aI
mSupppressScrollbarUpdate(PR_FALSE),
mDidLoadHistoryVScrollbarHint(PR_FALSE),
mHistoryVScrollbarHint(PR_FALSE),
mHadNonInitialReflow(PR_FALSE)
mHadNonInitialReflow(PR_FALSE),
mHorizontalOverflow(PR_FALSE),
mVerticalOverflow(PR_FALSE)
{
}
@ -2116,57 +2118,43 @@ nsXULScrollFrame::LayoutScrollArea(nsBoxLayoutState& aState, const nsRect& aRect
aState.SetLayoutFlags(oldflags);
childRect = mInner.mScrolledFrame->GetRect();
// XXX hack! force the scrolled frame to think it has overflow
// to avoid problems with incorrect event targeting.
mInner.mScrolledFrame->AddStateBits(NS_FRAME_OUTSIDE_CHILDREN);
mInner.PostOverflowEvents();
}
// first see what changed
PRBool vertChanged = PR_FALSE;
PRBool horizChanged = PR_FALSE;
void nsGfxScrollFrameInner::PostOverflowEvents()
{
nsSize childSize = mScrolledFrame->GetSize();
nsSize scrollportSize = mScrollableView->View()->GetBounds().Size();
PRBool newVerticalOverflow = childSize.height > scrollportSize.height;
PRBool vertChanged = mVerticalOverflow != newVerticalOverflow;
mVerticalOverflow = newVerticalOverflow;
if (mVerticalOverflow && childRect.height <= aRect.height) {
mVerticalOverflow = PR_FALSE;
vertChanged = PR_TRUE;
} else if (childRect.height > aRect.height) {
// XXX we fire an event every time we reflow with overflowing height. Do
// we really need to?
if (!mVerticalOverflow) {
mVerticalOverflow = PR_TRUE;
}
vertChanged = PR_TRUE;
}
PRBool newHorizontalOverflow = childSize.width > scrollportSize.width;
PRBool horizChanged = mHorizontalOverflow != newHorizontalOverflow;
mHorizontalOverflow = newHorizontalOverflow;
if (mHorizontalOverflow && childRect.width <= aRect.width) {
mHorizontalOverflow = PR_FALSE;
horizChanged = PR_TRUE;
} else if (childRect.width > aRect.width) {
// XXX we fire an event every time we reflow with overflowing width. Do
// we really need to?
if (!mHorizontalOverflow) {
mHorizontalOverflow = PR_TRUE;
}
horizChanged = PR_TRUE;
}
// if either changed
if (vertChanged || horizChanged)
{
// are there 2 events or 1?
if (vertChanged && horizChanged) {
if (mVerticalOverflow == mHorizontalOverflow)
{
if (vertChanged) {
if (horizChanged) {
if (mVerticalOverflow == mHorizontalOverflow) {
// both either overflowed or underflowed. 1 event
mInner.PostScrollPortEvent(mVerticalOverflow, nsScrollPortEvent::both);
PostScrollPortEvent(mVerticalOverflow, nsScrollPortEvent::both);
} else {
// one overflowed and one underflowed
mInner.PostScrollPortEvent(mVerticalOverflow, nsScrollPortEvent::vertical);
mInner.PostScrollPortEvent(mHorizontalOverflow, nsScrollPortEvent::horizontal);
PostScrollPortEvent(mVerticalOverflow, nsScrollPortEvent::vertical);
PostScrollPortEvent(mHorizontalOverflow, nsScrollPortEvent::horizontal);
}
} else if (vertChanged) // only one changed either vert or horiz
mInner.PostScrollPortEvent(mVerticalOverflow, nsScrollPortEvent::vertical);
else
mInner.PostScrollPortEvent(mHorizontalOverflow, nsScrollPortEvent::horizontal);
} else {
PostScrollPortEvent(mVerticalOverflow, nsScrollPortEvent::vertical);
}
} else {
if (horizChanged) {
PostScrollPortEvent(mHorizontalOverflow, nsScrollPortEvent::horizontal);
}
}
}

Просмотреть файл

@ -78,6 +78,7 @@ public:
void CreateAnonymousContent(nsISupportsArray& aAnonymousChildren);
void PostScrollPortEvent(PRBool aOverflow, nsScrollPortEvent::orientType aType);
void PostOverflowEvents();
nsresult GetChildContentAndOffsetsFromPoint(nsPresContext* aCX,
const nsPoint& aPoint,
@ -168,6 +169,10 @@ public:
// The value of the hint loaded
PRPackedBool mHistoryVScrollbarHint:1;
PRPackedBool mHadNonInitialReflow:1;
// State used only by PostScrollEvents so we know
// which overflow states have changed.
PRPackedBool mHorizontalOverflow:1;
PRPackedBool mVerticalOverflow:1;
};
/**
@ -500,8 +505,6 @@ private:
friend class nsGfxScrollFrameInner;
nsGfxScrollFrameInner mInner;
nscoord mMaxElementWidth;
PRPackedBool mHorizontalOverflow;
PRPackedBool mVerticalOverflow;
};
#endif /* nsGfxScrollFrame_h___ */