Bug 210269. Reduce use of SetAttr during reflow. Also, fix up the API that gets the scrollbar dimensions of a scrollframe to always work right for RTL. r+sr=bryner

This commit is contained in:
roc+%cs.cmu.edu 2004-01-09 19:21:20 +00:00
parent c455ced829
commit 3bfe589ac4
21 changed files with 212 additions and 344 deletions

View File

@ -2664,8 +2664,7 @@ nsComputedDOMStyle::GetAbsoluteOffset(PRUint8 aSide, nsIFrame* aFrame,
if (container) {
nscoord margin = GetMarginWidthCoordFor(aSide, aFrame);
nscoord border = GetBorderWidthCoordFor(aSide, container);
nscoord horScrollBarHeight = 0;
nscoord verScrollBarWidth = 0;
nsMargin scrollbarSizes(0, 0, 0, 0);
nsRect rect = aFrame->GetRect();
nsRect containerRect = container->GetRect();
@ -2684,39 +2683,28 @@ nsComputedDOMStyle::GetAbsoluteOffset(PRUint8 aSide, nsIFrame* aFrame,
nsCOMPtr<nsIScrollableFrame> scrollFrame =
do_QueryInterface(scrollingChild);
if (scrollFrame) {
scrollFrame->GetScrollbarSizes(presContext, &verScrollBarWidth,
&horScrollBarHeight);
PRBool verScrollBarVisible;
PRBool horScrollBarVisible;
scrollFrame->GetScrollbarVisibility(presContext, &verScrollBarVisible,
&horScrollBarVisible);
if (!verScrollBarVisible) {
verScrollBarWidth = 0;
}
if (!horScrollBarVisible) {
horScrollBarHeight = 0;
}
scrollbarSizes = scrollFrame->GetActualScrollbarSizes();
}
}
nscoord offset = 0;
switch (aSide) {
case NS_SIDE_TOP:
offset = rect.y - margin - border;
offset = rect.y - margin - border - scrollbarSizes.top;
break;
case NS_SIDE_RIGHT:
offset = containerRect.width - rect.width -
rect.x - margin - border - verScrollBarWidth;
rect.x - margin - border - scrollbarSizes.right;
break;
case NS_SIDE_BOTTOM:
offset = containerRect.height - rect.height -
rect.y - margin - border - horScrollBarHeight;
rect.y - margin - border - scrollbarSizes.bottom;
break;
case NS_SIDE_LEFT:
offset = rect.x - margin - border;
offset = rect.x - margin - border - scrollbarSizes.left;
break;
default:

View File

@ -3094,26 +3094,8 @@ nsCSSRendering::PaintBackgroundWithSC(nsIPresContext* aPresContext,
}
if (scrollableFrame) {
// Now, account for scrollbars, if we have any.
PRBool verticalVisible;
PRBool horizontalVisible;
scrollableFrame->GetScrollbarVisibility(aPresContext, &verticalVisible,
&horizontalVisible);
if (verticalVisible || horizontalVisible) {
nscoord verticalWidth;
nscoord horizontalHeight;
scrollableFrame->GetScrollbarSizes(aPresContext, &verticalWidth,
&horizontalHeight);
if (verticalVisible) {
// Assumes vertical scrollbars are on the right.
viewportArea.width -= verticalWidth;
}
if (horizontalVisible) {
// Assumes horizontal scrollbars are on the bottom.
viewportArea.height -= horizontalHeight;
}
}
nsMargin scrollbars = scrollableFrame->GetActualScrollbarSizes();
viewportArea.Deflate(scrollbars);
}
// Get the anchor point

View File

@ -46,6 +46,7 @@
class nsIFrame;
class nsIBox;
class nsIPresContext;
class nsBoxLayoutState;
// IID for the nsIScrollableFrame interface
#define NS_ISCROLLABLE_FRAME_IID \
@ -78,12 +79,18 @@ public:
NS_IMETHOD GetScrolledFrame(nsIPresContext* aPresContext,
nsIFrame *&aScrolledFrame) const = 0;
/**
* Gets the size of the area that lies inside the scrollbars but clips the scrolled frame
*/
NS_IMETHOD GetClipSize(nsIPresContext* aPresContext,
nscoord *aWidth,
nscoord *aHeight) const = 0;
/**
* Return the actual sizes of all possible scrollbars. Returns 0 for scrollbar
* positions that don't have a scrollbar or where the scrollbar is not visible.
*/
virtual nsMargin GetActualScrollbarSizes() const = 0;
/**
* Return the sizes of all scrollbars assuming that any scrollbars that could
* be visible due to overflowing content, are.
*/
virtual nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState) = 0;
/**
* Get information about whether the vertical and horizontal scrollbars
* are currently visible
@ -99,14 +106,6 @@ public:
*/
NS_IMETHOD GetScrollPreference(nsIPresContext* aPresContext, nsScrollPref* aScrollPreference) const = 0;
/**
* Gets the vertical width and horizontal height of the scrollbars.
*/
NS_IMETHOD GetScrollbarSizes(nsIPresContext* aPresContext,
nscoord *aVbarWidth,
nscoord *aHbarHeight) const = 0;
/**
* Get the position of the scrolled view.
*/

View File

@ -221,21 +221,6 @@ nsGfxScrollFrame::GetScrolledFrame(nsIPresContext* aPresContext, nsIFrame *&aScr
return NS_OK;
}
/**
* Gets the size of the area that lies inside the scrollbars but clips the scrolled frame
*/
NS_IMETHODIMP
nsGfxScrollFrame::GetClipSize(nsIPresContext* aPresContext,
nscoord *aWidth,
nscoord *aHeight) const
{
nsRect rect;
mInner->mScrollAreaBox->GetBounds(rect);
*aWidth = rect.width;
*aHeight = rect.height;
return NS_OK;
}
/**
* Get information about whether the vertical and horizontal scrollbars
* are currently visible
@ -300,32 +285,39 @@ nsGfxScrollFrame::GetScrollPreference(nsIPresContext* aPresContext, nsScrollPref
return NS_OK;
}
/**
* Gets the size of the area that lies inside the scrollbars but clips the scrolled frame
*/
NS_IMETHODIMP
nsGfxScrollFrame::GetScrollbarSizes(nsIPresContext* aPresContext,
nscoord *aVbarWidth,
nscoord *aHbarHeight) const
{
nsBoxLayoutState state(aPresContext);
nsMargin nsGfxScrollFrame::GetActualScrollbarSizes() const {
nsRect bounds = GetRect();
nsRect scrollArea;
mInner->mScrollAreaBox->GetBounds(scrollArea);
*aVbarWidth = 0;
*aHbarHeight = 0;
return nsMargin(scrollArea.x, scrollArea.y,
bounds.width - scrollArea.XMost(),
bounds.height - scrollArea.YMost());
}
nsMargin nsGfxScrollFrame::GetDesiredScrollbarSizes(nsBoxLayoutState* aState) {
nsMargin result(0, 0, 0, 0);
if (mInner->mHScrollbarBox) {
nsSize hs;
mInner->mHScrollbarBox->GetPrefSize(state, hs);
*aHbarHeight = hs.height;
nsSize size;
mInner->mHScrollbarBox->GetPrefSize(*aState, size);
#ifdef IBMBIDI
if (GetStyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL)
result.left = size.width;
else
#endif
result.right = size.width;
}
if (mInner->mVScrollbarBox) {
nsSize vs;
mInner->mVScrollbarBox->GetPrefSize(state, vs);
*aVbarWidth = vs.width;
nsSize size;
mInner->mVScrollbarBox->GetPrefSize(*aState, size);
// We don't currently support any scripts that would require a scrollbar
// at the top. (Are there any?)
result.bottom = size.height;
}
return NS_OK;
return result;
}
NS_IMETHODIMP
@ -403,8 +395,6 @@ nsGfxScrollFrame::CreateAnonymousContent(nsIPresContext* aPresContext,
elementFactory->CreateInstanceByTag(nodeInfo, getter_AddRefs(content));
content->SetAttr(kNameSpaceID_None, nsXULAtoms::orient,
NS_LITERAL_STRING("horizontal"), PR_FALSE);
content->SetAttr(kNameSpaceID_None, nsXULAtoms::collapsed,
NS_LITERAL_STRING("true"), PR_FALSE);
aAnonymousChildren.AppendElement(content);
}
@ -415,8 +405,6 @@ nsGfxScrollFrame::CreateAnonymousContent(nsIPresContext* aPresContext,
elementFactory->CreateInstanceByTag(nodeInfo, getter_AddRefs(content));
content->SetAttr(kNameSpaceID_None, nsXULAtoms::orient,
NS_LITERAL_STRING("vertical"), PR_FALSE);
content->SetAttr(kNameSpaceID_None, nsXULAtoms::collapsed,
NS_LITERAL_STRING("true"), PR_FALSE);
aAnonymousChildren.AppendElement(content);
}
@ -697,8 +685,6 @@ nsGfxScrollFrame::GetPrefSize(nsBoxLayoutState& aState, nsSize& aSize)
nsSize vSize(0,0);
if (mInner->mVScrollbarBox &&
styles.mVertical == NS_STYLE_OVERFLOW_SCROLL) {
// make sure they are visible.
mInner->SetScrollbarVisibility(mInner->mVScrollbarBox, PR_TRUE);
mInner->mVScrollbarBox->GetPrefSize(aState, vSize);
nsBox::AddMargin(mInner->mVScrollbarBox, vSize);
}
@ -706,7 +692,6 @@ nsGfxScrollFrame::GetPrefSize(nsBoxLayoutState& aState, nsSize& aSize)
nsSize hSize(0,0);
if (mInner->mHScrollbarBox &&
styles.mHorizontal == NS_STYLE_OVERFLOW_SCROLL) {
mInner->SetScrollbarVisibility(mInner->mHScrollbarBox, PR_TRUE);
mInner->mHScrollbarBox->GetPrefSize(aState, hSize);
nsBox::AddMargin(mInner->mHScrollbarBox, hSize);
}
@ -746,7 +731,6 @@ nsGfxScrollFrame::GetPrefSize(nsBoxLayoutState& aState, nsSize& aSize)
&& mInner->mHScrollbarBox
&& styles.mHorizontal == NS_STYLE_OVERFLOW_AUTO) {
// Add height of horizontal scrollbar which will be needed
mInner->SetScrollbarVisibility(mInner->mHScrollbarBox, PR_TRUE);
mInner->mHScrollbarBox->GetPrefSize(aState, hSize);
nsBox::AddMargin(mInner->mHScrollbarBox, hSize);
}
@ -757,7 +741,6 @@ nsGfxScrollFrame::GetPrefSize(nsBoxLayoutState& aState, nsSize& aSize)
&& mInner->mVScrollbarBox
&& styles.mVertical == NS_STYLE_OVERFLOW_AUTO) {
// Add width of vertical scrollbar which will be needed
mInner->SetScrollbarVisibility(mInner->mVScrollbarBox, PR_TRUE);
mInner->mVScrollbarBox->GetPrefSize(aState, vSize);
nsBox::AddMargin(mInner->mVScrollbarBox, vSize);
}
@ -1159,15 +1142,11 @@ nsGfxScrollFrameInner::AddRemoveScrollbar(nsBoxLayoutState& aState, nsRect& aScr
if (mNeverHasHorizontalScrollbar || !mHScrollbarBox)
return PR_FALSE;
if (aAdd)
SetScrollbarVisibility(mHScrollbarBox, aAdd);
nsSize hSize;
mHScrollbarBox->GetPrefSize(aState, hSize);
nsBox::AddMargin(mHScrollbarBox, hSize);
if (!aAdd)
SetScrollbarVisibility(mHScrollbarBox, aAdd);
SetScrollbarVisibility(mHScrollbarBox, aAdd);
PRBool hasHorizontalScrollbar;
PRBool fit = AddRemoveScrollbar(hasHorizontalScrollbar, aScrollAreaSize.y, aScrollAreaSize.height, hSize.height, aOnTop, aAdd);
@ -1180,16 +1159,12 @@ nsGfxScrollFrameInner::AddRemoveScrollbar(nsBoxLayoutState& aState, nsRect& aScr
if (mNeverHasVerticalScrollbar || !mVScrollbarBox)
return PR_FALSE;
if (aAdd)
SetScrollbarVisibility(mVScrollbarBox, aAdd);
nsSize vSize;
mVScrollbarBox->GetPrefSize(aState, vSize);
if (!aAdd)
SetScrollbarVisibility(mVScrollbarBox, aAdd);
nsBox::AddMargin(mVScrollbarBox, vSize);
SetScrollbarVisibility(mVScrollbarBox, aAdd);
PRBool hasVerticalScrollbar;
PRBool fit = AddRemoveScrollbar(hasVerticalScrollbar, aScrollAreaSize.x, aScrollAreaSize.width, vSize.width, aOnTop, aAdd);
mHasVerticalScrollbar = hasVerticalScrollbar; // because mHasVerticalScrollbar is a PRPackedBool
@ -1514,7 +1489,8 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
// layout vertical scrollbar
nsRect vRect(clientRect);
vRect.width = vSize.width;
vRect.width = mHasVerticalScrollbar ? vSize.width : 0;
vRect.y = clientRect.y;
if (mHasHorizontalScrollbar) {
@ -1526,7 +1502,7 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
vRect.x = clientRect.x;
if (scrollBarRight)
vRect.x += clientRect.width - vSize.width;
vRect.x += clientRect.width - vRect.width;
if (mHasVerticalScrollbar && mVScrollbarBox) {
SetAttribute(mVScrollbarBox, nsXULAtoms::maxpos, maxY);
@ -1551,7 +1527,7 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
// layout horizontal scrollbar
nsRect hRect(clientRect);
hRect.height = hSize.height;
hRect.height = mHasHorizontalScrollbar ? hSize.height : 0;
hRect.x = clientRect.x;
@ -1564,7 +1540,7 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
hRect.y = clientRect.y;
if (scrollBarBottom)
hRect.y += clientRect.height - hSize.height;
hRect.y += clientRect.height - hRect.height;
if (mHasHorizontalScrollbar && mHScrollbarBox) {
SetAttribute(mHScrollbarBox, nsXULAtoms::maxpos, maxX);
@ -1718,30 +1694,6 @@ nsGfxScrollFrameInner::SetScrollbarVisibility(nsIBox* aScrollbar, PRBool aVisibl
if (!aScrollbar)
return;
nsIFrame* frame = nsnull;
aScrollbar->GetFrame(&frame);
nsIContent* content = frame->GetContent();
PRBool old = PR_TRUE;
nsAutoString value;
if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttr(kNameSpaceID_None, nsXULAtoms::collapsed, value))
old = PR_FALSE;
if (aVisible == old)
return;
if (!aVisible) {
content->SetAttr(kNameSpaceID_None, nsXULAtoms::collapsed, NS_LITERAL_STRING("true"), PR_TRUE);
} else {
// disable laziness; we never want to recreate these scrollbars again
// once we've created them
// disable laziness FIRST so only one recreation happens.
content->UnsetAttr(kNameSpaceID_None, nsXULAtoms::collapsed, PR_TRUE);
}
nsCOMPtr<nsIScrollbarFrame> scrollbar(do_QueryInterface(aScrollbar));
if (scrollbar) {
// See if we have a mediator.

View File

@ -159,15 +159,10 @@ public:
nsIContent* aChild,
PRInt32 aModType);
NS_IMETHOD GetClipSize(nsIPresContext* aPresContext,
nscoord *aWidth,
nscoord *aHeight) const;
NS_IMETHOD GetScrollPreference(nsIPresContext* aPresContext, nsScrollPref* aScrollPreference) const;
NS_IMETHOD GetScrollbarSizes(nsIPresContext* aPresContext,
nscoord *aVbarWidth,
nscoord *aHbarHeight) const;
virtual nsMargin GetActualScrollbarSizes() const;
virtual nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState);
/**
* Get the "type" of the frame

View File

@ -46,6 +46,7 @@
class nsIFrame;
class nsIBox;
class nsIPresContext;
class nsBoxLayoutState;
// IID for the nsIScrollableFrame interface
#define NS_ISCROLLABLE_FRAME_IID \
@ -78,12 +79,18 @@ public:
NS_IMETHOD GetScrolledFrame(nsIPresContext* aPresContext,
nsIFrame *&aScrolledFrame) const = 0;
/**
* Gets the size of the area that lies inside the scrollbars but clips the scrolled frame
*/
NS_IMETHOD GetClipSize(nsIPresContext* aPresContext,
nscoord *aWidth,
nscoord *aHeight) const = 0;
/**
* Return the actual sizes of all possible scrollbars. Returns 0 for scrollbar
* positions that don't have a scrollbar or where the scrollbar is not visible.
*/
virtual nsMargin GetActualScrollbarSizes() const = 0;
/**
* Return the sizes of all scrollbars assuming that any scrollbars that could
* be visible due to overflowing content, are.
*/
virtual nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState) = 0;
/**
* Get information about whether the vertical and horizontal scrollbars
* are currently visible
@ -99,14 +106,6 @@ public:
*/
NS_IMETHOD GetScrollPreference(nsIPresContext* aPresContext, nsScrollPref* aScrollPreference) const = 0;
/**
* Gets the vertical width and horizontal height of the scrollbars.
*/
NS_IMETHOD GetScrollbarSizes(nsIPresContext* aPresContext,
nscoord *aVbarWidth,
nscoord *aHbarHeight) const = 0;
/**
* Get the position of the scrolled view.
*/

View File

@ -186,9 +186,8 @@ ViewportFrame::GetFirstChild(nsIAtom* aListName) const
return nsContainerFrame::GetFirstChild(aListName);
}
void
ViewportFrame::AdjustReflowStateForScrollbars(nsIPresContext* aPresContext,
nsHTMLReflowState& aReflowState) const
nsPoint
ViewportFrame::AdjustReflowStateForScrollbars(nsHTMLReflowState* aReflowState) const
{
// Calculate how much room is available for fixed frames. That means
// determining if the viewport is scrollable and whether the vertical and/or
@ -199,18 +198,14 @@ ViewportFrame::AdjustReflowStateForScrollbars(nsIPresContext* aPresContext,
nsCOMPtr<nsIScrollableFrame> scrollingFrame(do_QueryInterface(kidFrame));
if (scrollingFrame) {
nscoord sbWidth = 0, sbHeight = 0;
PRBool sbHVisible = PR_FALSE, sbVVisible = PR_FALSE;
scrollingFrame->GetScrollbarSizes(aPresContext, &sbWidth, &sbHeight);
scrollingFrame->GetScrollbarVisibility(aPresContext, &sbVVisible, &sbHVisible);
if (sbVVisible) {
aReflowState.mComputedWidth -= sbWidth;
aReflowState.availableWidth -= sbWidth;
}
if (sbHVisible) {
aReflowState.mComputedHeight -= sbHeight;
}
nsMargin scrollbars = scrollingFrame->GetActualScrollbarSizes();
aReflowState->mComputedWidth -= scrollbars.left + scrollbars.right;
aReflowState->availableWidth -= scrollbars.left + scrollbars.right;
aReflowState->mComputedHeight -= scrollbars.top + scrollbars.bottom;
// XXX why don't we also adjust "aReflowState->availableHeight"?
return nsPoint(scrollbars.left, scrollbars.top);
}
return nsPoint(0, 0);
}
NS_IMETHODIMP
@ -280,8 +275,16 @@ ViewportFrame::Reflow(nsIPresContext* aPresContext,
// Make a copy of the reflow state and change the computed width and height
// to reflect the available space for the fixed items
nsHTMLReflowState reflowState(aReflowState);
AdjustReflowStateForScrollbars(aPresContext, reflowState);
nsPoint offset = AdjustReflowStateForScrollbars(&reflowState);
#ifdef DEBUG
nsIFrame* f;
mFixedContainer.FirstChild(this, nsLayoutAtoms::fixedList, &f);
NS_ASSERTION(!f || (offset.x == 0 && offset.y == 0),
"We don't handle correct positioning of fixed frames with "
"scrollbars in odd positions");
#endif
nsReflowType reflowType = eReflowType_ContentChanged;
if (aReflowState.path) {
// XXXwaterson this is more restrictive than the previous code

View File

@ -117,8 +117,7 @@ public:
#endif
protected:
void AdjustReflowStateForScrollbars(nsIPresContext* aPresContext,
nsHTMLReflowState& aReflowState) const;
nsPoint AdjustReflowStateForScrollbars(nsHTMLReflowState* aReflowState) const;
protected:
nsFixedContainingBlock mFixedContainer;

View File

@ -221,21 +221,6 @@ nsGfxScrollFrame::GetScrolledFrame(nsIPresContext* aPresContext, nsIFrame *&aScr
return NS_OK;
}
/**
* Gets the size of the area that lies inside the scrollbars but clips the scrolled frame
*/
NS_IMETHODIMP
nsGfxScrollFrame::GetClipSize(nsIPresContext* aPresContext,
nscoord *aWidth,
nscoord *aHeight) const
{
nsRect rect;
mInner->mScrollAreaBox->GetBounds(rect);
*aWidth = rect.width;
*aHeight = rect.height;
return NS_OK;
}
/**
* Get information about whether the vertical and horizontal scrollbars
* are currently visible
@ -300,32 +285,39 @@ nsGfxScrollFrame::GetScrollPreference(nsIPresContext* aPresContext, nsScrollPref
return NS_OK;
}
/**
* Gets the size of the area that lies inside the scrollbars but clips the scrolled frame
*/
NS_IMETHODIMP
nsGfxScrollFrame::GetScrollbarSizes(nsIPresContext* aPresContext,
nscoord *aVbarWidth,
nscoord *aHbarHeight) const
{
nsBoxLayoutState state(aPresContext);
nsMargin nsGfxScrollFrame::GetActualScrollbarSizes() const {
nsRect bounds = GetRect();
nsRect scrollArea;
mInner->mScrollAreaBox->GetBounds(scrollArea);
*aVbarWidth = 0;
*aHbarHeight = 0;
return nsMargin(scrollArea.x, scrollArea.y,
bounds.width - scrollArea.XMost(),
bounds.height - scrollArea.YMost());
}
nsMargin nsGfxScrollFrame::GetDesiredScrollbarSizes(nsBoxLayoutState* aState) {
nsMargin result(0, 0, 0, 0);
if (mInner->mHScrollbarBox) {
nsSize hs;
mInner->mHScrollbarBox->GetPrefSize(state, hs);
*aHbarHeight = hs.height;
nsSize size;
mInner->mHScrollbarBox->GetPrefSize(*aState, size);
#ifdef IBMBIDI
if (GetStyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL)
result.left = size.width;
else
#endif
result.right = size.width;
}
if (mInner->mVScrollbarBox) {
nsSize vs;
mInner->mVScrollbarBox->GetPrefSize(state, vs);
*aVbarWidth = vs.width;
nsSize size;
mInner->mVScrollbarBox->GetPrefSize(*aState, size);
// We don't currently support any scripts that would require a scrollbar
// at the top. (Are there any?)
result.bottom = size.height;
}
return NS_OK;
return result;
}
NS_IMETHODIMP
@ -403,8 +395,6 @@ nsGfxScrollFrame::CreateAnonymousContent(nsIPresContext* aPresContext,
elementFactory->CreateInstanceByTag(nodeInfo, getter_AddRefs(content));
content->SetAttr(kNameSpaceID_None, nsXULAtoms::orient,
NS_LITERAL_STRING("horizontal"), PR_FALSE);
content->SetAttr(kNameSpaceID_None, nsXULAtoms::collapsed,
NS_LITERAL_STRING("true"), PR_FALSE);
aAnonymousChildren.AppendElement(content);
}
@ -415,8 +405,6 @@ nsGfxScrollFrame::CreateAnonymousContent(nsIPresContext* aPresContext,
elementFactory->CreateInstanceByTag(nodeInfo, getter_AddRefs(content));
content->SetAttr(kNameSpaceID_None, nsXULAtoms::orient,
NS_LITERAL_STRING("vertical"), PR_FALSE);
content->SetAttr(kNameSpaceID_None, nsXULAtoms::collapsed,
NS_LITERAL_STRING("true"), PR_FALSE);
aAnonymousChildren.AppendElement(content);
}
@ -697,8 +685,6 @@ nsGfxScrollFrame::GetPrefSize(nsBoxLayoutState& aState, nsSize& aSize)
nsSize vSize(0,0);
if (mInner->mVScrollbarBox &&
styles.mVertical == NS_STYLE_OVERFLOW_SCROLL) {
// make sure they are visible.
mInner->SetScrollbarVisibility(mInner->mVScrollbarBox, PR_TRUE);
mInner->mVScrollbarBox->GetPrefSize(aState, vSize);
nsBox::AddMargin(mInner->mVScrollbarBox, vSize);
}
@ -706,7 +692,6 @@ nsGfxScrollFrame::GetPrefSize(nsBoxLayoutState& aState, nsSize& aSize)
nsSize hSize(0,0);
if (mInner->mHScrollbarBox &&
styles.mHorizontal == NS_STYLE_OVERFLOW_SCROLL) {
mInner->SetScrollbarVisibility(mInner->mHScrollbarBox, PR_TRUE);
mInner->mHScrollbarBox->GetPrefSize(aState, hSize);
nsBox::AddMargin(mInner->mHScrollbarBox, hSize);
}
@ -746,7 +731,6 @@ nsGfxScrollFrame::GetPrefSize(nsBoxLayoutState& aState, nsSize& aSize)
&& mInner->mHScrollbarBox
&& styles.mHorizontal == NS_STYLE_OVERFLOW_AUTO) {
// Add height of horizontal scrollbar which will be needed
mInner->SetScrollbarVisibility(mInner->mHScrollbarBox, PR_TRUE);
mInner->mHScrollbarBox->GetPrefSize(aState, hSize);
nsBox::AddMargin(mInner->mHScrollbarBox, hSize);
}
@ -757,7 +741,6 @@ nsGfxScrollFrame::GetPrefSize(nsBoxLayoutState& aState, nsSize& aSize)
&& mInner->mVScrollbarBox
&& styles.mVertical == NS_STYLE_OVERFLOW_AUTO) {
// Add width of vertical scrollbar which will be needed
mInner->SetScrollbarVisibility(mInner->mVScrollbarBox, PR_TRUE);
mInner->mVScrollbarBox->GetPrefSize(aState, vSize);
nsBox::AddMargin(mInner->mVScrollbarBox, vSize);
}
@ -1159,15 +1142,11 @@ nsGfxScrollFrameInner::AddRemoveScrollbar(nsBoxLayoutState& aState, nsRect& aScr
if (mNeverHasHorizontalScrollbar || !mHScrollbarBox)
return PR_FALSE;
if (aAdd)
SetScrollbarVisibility(mHScrollbarBox, aAdd);
nsSize hSize;
mHScrollbarBox->GetPrefSize(aState, hSize);
nsBox::AddMargin(mHScrollbarBox, hSize);
if (!aAdd)
SetScrollbarVisibility(mHScrollbarBox, aAdd);
SetScrollbarVisibility(mHScrollbarBox, aAdd);
PRBool hasHorizontalScrollbar;
PRBool fit = AddRemoveScrollbar(hasHorizontalScrollbar, aScrollAreaSize.y, aScrollAreaSize.height, hSize.height, aOnTop, aAdd);
@ -1180,16 +1159,12 @@ nsGfxScrollFrameInner::AddRemoveScrollbar(nsBoxLayoutState& aState, nsRect& aScr
if (mNeverHasVerticalScrollbar || !mVScrollbarBox)
return PR_FALSE;
if (aAdd)
SetScrollbarVisibility(mVScrollbarBox, aAdd);
nsSize vSize;
mVScrollbarBox->GetPrefSize(aState, vSize);
if (!aAdd)
SetScrollbarVisibility(mVScrollbarBox, aAdd);
nsBox::AddMargin(mVScrollbarBox, vSize);
SetScrollbarVisibility(mVScrollbarBox, aAdd);
PRBool hasVerticalScrollbar;
PRBool fit = AddRemoveScrollbar(hasVerticalScrollbar, aScrollAreaSize.x, aScrollAreaSize.width, vSize.width, aOnTop, aAdd);
mHasVerticalScrollbar = hasVerticalScrollbar; // because mHasVerticalScrollbar is a PRPackedBool
@ -1514,7 +1489,8 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
// layout vertical scrollbar
nsRect vRect(clientRect);
vRect.width = vSize.width;
vRect.width = mHasVerticalScrollbar ? vSize.width : 0;
vRect.y = clientRect.y;
if (mHasHorizontalScrollbar) {
@ -1526,7 +1502,7 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
vRect.x = clientRect.x;
if (scrollBarRight)
vRect.x += clientRect.width - vSize.width;
vRect.x += clientRect.width - vRect.width;
if (mHasVerticalScrollbar && mVScrollbarBox) {
SetAttribute(mVScrollbarBox, nsXULAtoms::maxpos, maxY);
@ -1551,7 +1527,7 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
// layout horizontal scrollbar
nsRect hRect(clientRect);
hRect.height = hSize.height;
hRect.height = mHasHorizontalScrollbar ? hSize.height : 0;
hRect.x = clientRect.x;
@ -1564,7 +1540,7 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
hRect.y = clientRect.y;
if (scrollBarBottom)
hRect.y += clientRect.height - hSize.height;
hRect.y += clientRect.height - hRect.height;
if (mHasHorizontalScrollbar && mHScrollbarBox) {
SetAttribute(mHScrollbarBox, nsXULAtoms::maxpos, maxX);
@ -1718,30 +1694,6 @@ nsGfxScrollFrameInner::SetScrollbarVisibility(nsIBox* aScrollbar, PRBool aVisibl
if (!aScrollbar)
return;
nsIFrame* frame = nsnull;
aScrollbar->GetFrame(&frame);
nsIContent* content = frame->GetContent();
PRBool old = PR_TRUE;
nsAutoString value;
if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttr(kNameSpaceID_None, nsXULAtoms::collapsed, value))
old = PR_FALSE;
if (aVisible == old)
return;
if (!aVisible) {
content->SetAttr(kNameSpaceID_None, nsXULAtoms::collapsed, NS_LITERAL_STRING("true"), PR_TRUE);
} else {
// disable laziness; we never want to recreate these scrollbars again
// once we've created them
// disable laziness FIRST so only one recreation happens.
content->UnsetAttr(kNameSpaceID_None, nsXULAtoms::collapsed, PR_TRUE);
}
nsCOMPtr<nsIScrollbarFrame> scrollbar(do_QueryInterface(aScrollbar));
if (scrollbar) {
// See if we have a mediator.

View File

@ -159,15 +159,10 @@ public:
nsIContent* aChild,
PRInt32 aModType);
NS_IMETHOD GetClipSize(nsIPresContext* aPresContext,
nscoord *aWidth,
nscoord *aHeight) const;
NS_IMETHOD GetScrollPreference(nsIPresContext* aPresContext, nsScrollPref* aScrollPreference) const;
NS_IMETHOD GetScrollbarSizes(nsIPresContext* aPresContext,
nscoord *aVbarWidth,
nscoord *aHbarHeight) const;
virtual nsMargin GetActualScrollbarSizes() const;
virtual nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState);
/**
* Get the "type" of the frame

View File

@ -186,9 +186,8 @@ ViewportFrame::GetFirstChild(nsIAtom* aListName) const
return nsContainerFrame::GetFirstChild(aListName);
}
void
ViewportFrame::AdjustReflowStateForScrollbars(nsIPresContext* aPresContext,
nsHTMLReflowState& aReflowState) const
nsPoint
ViewportFrame::AdjustReflowStateForScrollbars(nsHTMLReflowState* aReflowState) const
{
// Calculate how much room is available for fixed frames. That means
// determining if the viewport is scrollable and whether the vertical and/or
@ -199,18 +198,14 @@ ViewportFrame::AdjustReflowStateForScrollbars(nsIPresContext* aPresContext,
nsCOMPtr<nsIScrollableFrame> scrollingFrame(do_QueryInterface(kidFrame));
if (scrollingFrame) {
nscoord sbWidth = 0, sbHeight = 0;
PRBool sbHVisible = PR_FALSE, sbVVisible = PR_FALSE;
scrollingFrame->GetScrollbarSizes(aPresContext, &sbWidth, &sbHeight);
scrollingFrame->GetScrollbarVisibility(aPresContext, &sbVVisible, &sbHVisible);
if (sbVVisible) {
aReflowState.mComputedWidth -= sbWidth;
aReflowState.availableWidth -= sbWidth;
}
if (sbHVisible) {
aReflowState.mComputedHeight -= sbHeight;
}
nsMargin scrollbars = scrollingFrame->GetActualScrollbarSizes();
aReflowState->mComputedWidth -= scrollbars.left + scrollbars.right;
aReflowState->availableWidth -= scrollbars.left + scrollbars.right;
aReflowState->mComputedHeight -= scrollbars.top + scrollbars.bottom;
// XXX why don't we also adjust "aReflowState->availableHeight"?
return nsPoint(scrollbars.left, scrollbars.top);
}
return nsPoint(0, 0);
}
NS_IMETHODIMP
@ -280,8 +275,16 @@ ViewportFrame::Reflow(nsIPresContext* aPresContext,
// Make a copy of the reflow state and change the computed width and height
// to reflect the available space for the fixed items
nsHTMLReflowState reflowState(aReflowState);
AdjustReflowStateForScrollbars(aPresContext, reflowState);
nsPoint offset = AdjustReflowStateForScrollbars(&reflowState);
#ifdef DEBUG
nsIFrame* f;
mFixedContainer.FirstChild(this, nsLayoutAtoms::fixedList, &f);
NS_ASSERTION(!f || (offset.x == 0 && offset.y == 0),
"We don't handle correct positioning of fixed frames with "
"scrollbars in odd positions");
#endif
nsReflowType reflowType = eReflowType_ContentChanged;
if (aReflowState.path) {
// XXXwaterson this is more restrictive than the previous code

View File

@ -117,8 +117,7 @@ public:
#endif
protected:
void AdjustReflowStateForScrollbars(nsIPresContext* aPresContext,
nsHTMLReflowState& aReflowState) const;
nsPoint AdjustReflowStateForScrollbars(nsHTMLReflowState* aReflowState) const;
protected:
nsFixedContainingBlock mFixedContainer;

View File

@ -3094,26 +3094,8 @@ nsCSSRendering::PaintBackgroundWithSC(nsIPresContext* aPresContext,
}
if (scrollableFrame) {
// Now, account for scrollbars, if we have any.
PRBool verticalVisible;
PRBool horizontalVisible;
scrollableFrame->GetScrollbarVisibility(aPresContext, &verticalVisible,
&horizontalVisible);
if (verticalVisible || horizontalVisible) {
nscoord verticalWidth;
nscoord horizontalHeight;
scrollableFrame->GetScrollbarSizes(aPresContext, &verticalWidth,
&horizontalHeight);
if (verticalVisible) {
// Assumes vertical scrollbars are on the right.
viewportArea.width -= verticalWidth;
}
if (horizontalVisible) {
// Assumes horizontal scrollbars are on the bottom.
viewportArea.height -= horizontalHeight;
}
}
nsMargin scrollbars = scrollableFrame->GetActualScrollbarSizes();
viewportArea.Deflate(scrollbars);
}
// Get the anchor point

View File

@ -2664,8 +2664,7 @@ nsComputedDOMStyle::GetAbsoluteOffset(PRUint8 aSide, nsIFrame* aFrame,
if (container) {
nscoord margin = GetMarginWidthCoordFor(aSide, aFrame);
nscoord border = GetBorderWidthCoordFor(aSide, container);
nscoord horScrollBarHeight = 0;
nscoord verScrollBarWidth = 0;
nsMargin scrollbarSizes(0, 0, 0, 0);
nsRect rect = aFrame->GetRect();
nsRect containerRect = container->GetRect();
@ -2684,39 +2683,28 @@ nsComputedDOMStyle::GetAbsoluteOffset(PRUint8 aSide, nsIFrame* aFrame,
nsCOMPtr<nsIScrollableFrame> scrollFrame =
do_QueryInterface(scrollingChild);
if (scrollFrame) {
scrollFrame->GetScrollbarSizes(presContext, &verScrollBarWidth,
&horScrollBarHeight);
PRBool verScrollBarVisible;
PRBool horScrollBarVisible;
scrollFrame->GetScrollbarVisibility(presContext, &verScrollBarVisible,
&horScrollBarVisible);
if (!verScrollBarVisible) {
verScrollBarWidth = 0;
}
if (!horScrollBarVisible) {
horScrollBarHeight = 0;
}
scrollbarSizes = scrollFrame->GetActualScrollbarSizes();
}
}
nscoord offset = 0;
switch (aSide) {
case NS_SIDE_TOP:
offset = rect.y - margin - border;
offset = rect.y - margin - border - scrollbarSizes.top;
break;
case NS_SIDE_RIGHT:
offset = containerRect.width - rect.width -
rect.x - margin - border - verScrollBarWidth;
rect.x - margin - border - scrollbarSizes.right;
break;
case NS_SIDE_BOTTOM:
offset = containerRect.height - rect.height -
rect.y - margin - border - horScrollBarHeight;
rect.y - margin - border - scrollbarSizes.bottom;
break;
case NS_SIDE_LEFT:
offset = rect.x - margin - border;
offset = rect.x - margin - border - scrollbarSizes.left;
break;
default:

View File

@ -322,13 +322,7 @@ nsGridRowLeafLayout::ComputeChildSizes(nsIBox* aBox,
nsCOMPtr<nsIScrollableFrame> scrollable = do_QueryInterface(scrollbox);
if (scrollable) {
// get the clip rect and compare its size to the scrollframe.
// we just need to subtract out the difference.
nsSize clipSize(0,0);
scrollable->GetClipSize(nsnull, &clipSize.width, &clipSize.height);
nscoord diff = 0;
nsMargin scrollbarSizes = scrollable->GetActualScrollbarSizes();
nsRect ourRect;
nsMargin padding(0,0,0,0);
@ -338,10 +332,11 @@ nsGridRowLeafLayout::ComputeChildSizes(nsIBox* aBox,
scrollbox->GetInset(padding);
ourRect.Deflate(padding);
nscoord diff;
if (isHorizontal) {
diff = ourRect.width - clipSize.width;
diff = scrollbarSizes.left + scrollbarSizes.right;
} else {
diff = ourRect.height - clipSize.height;
diff = scrollbarSizes.top + scrollbarSizes.bottom;
}
if (diff > 0) {

View File

@ -1457,10 +1457,8 @@ nsListboxScrollPortFrame::GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize&
scrollFrame->GetScrollPreference(aBoxLayoutState.GetPresContext(), &scrollPref);
if (scrollPref == nsIScrollableFrame::Auto) {
nscoord vbarwidth, hbarheight;
scrollFrame->GetScrollbarSizes(aBoxLayoutState.GetPresContext(),
&vbarwidth, &hbarheight);
aSize.width += vbarwidth;
nsMargin scrollbars = scrollFrame->GetDesiredScrollbarSizes(&aBoxLayoutState);
aSize.width += scrollbars.left + scrollbars.right;
}
}
}
@ -1496,10 +1494,8 @@ nsListboxScrollPortFrame::GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize&
scrollFrame->GetScrollPreference(aBoxLayoutState.GetPresContext(), &scrollPref);
if (scrollPref == nsIScrollableFrame::Auto) {
nscoord vbarwidth, hbarheight;
scrollFrame->GetScrollbarSizes(aBoxLayoutState.GetPresContext(),
&vbarwidth, &hbarheight);
aSize.width += vbarwidth;
nsMargin scrollbars = scrollFrame->GetDesiredScrollbarSizes(&aBoxLayoutState);
aSize.width += scrollbars.left + scrollbars.right;
}
}

View File

@ -1012,17 +1012,14 @@ nsMenuFrame::DoLayout(nsBoxLayoutState& aState)
if (pref == nsIScrollableFrame::Auto)
{
// if our pref height
if (bounds.height < prefSize.height) {
// layout the child
ibox->Layout(aState);
nscoord width;
nscoord height;
scrollframe->GetScrollbarSizes(aState.GetPresContext(), &width, &height);
if (bounds.width < prefSize.width + width)
nsMargin scrollbars = scrollframe->GetActualScrollbarSizes();
if (bounds.width < prefSize.width + scrollbars.left + scrollbars.right)
{
bounds.width += width;
bounds.width += scrollbars.left + scrollbars.right;
//printf("Width=%d\n",width);
ibox->SetBounds(aState, bounds);
}

View File

@ -168,6 +168,26 @@ nsNativeScrollbarFrame::FindScrollbar(nsIFrame* start, nsIFrame** outFrame,
return NS_OK;
}
NS_IMETHODIMP
nsNativeScrollbarFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
nsresult rv = nsBoxFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
NS_ENSURE_SUCCESS(rv, rv);
// nsGfxScrollFrame may have told us to shrink to nothing. If so, make sure our
// desired size agrees.
if (aReflowState.availableWidth == 0) {
aDesiredSize.width = 0;
}
if (aReflowState.availableHeight == 0) {
aDesiredSize.height = 0;
}
return NS_OK;
}
//
// AttributeChanged

View File

@ -249,12 +249,10 @@ nsPopupSetFrame::DoLayout(nsBoxLayoutState& aState)
// layout the child
ibox->Layout(aState);
nscoord width;
nscoord height;
scrollframe->GetScrollbarSizes(aState.GetPresContext(), &width, &height);
if (bounds.width < prefSize.width + width)
nsMargin scrollbars = scrollframe->GetActualScrollbarSizes();
if (bounds.width < prefSize.width + scrollbars.left + scrollbars.right)
{
bounds.width += width;
bounds.width += scrollbars.left + scrollbars.right;
//printf("Width=%d\n",width);
ibox->SetBounds(aState, bounds);
}

View File

@ -100,6 +100,27 @@ nsScrollbarFrame::Init(nsIPresContext* aPresContext,
return rv;
}
NS_IMETHODIMP
nsScrollbarFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
nsresult rv = nsBoxFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
NS_ENSURE_SUCCESS(rv, rv);
// nsGfxScrollFrame may have told us to shrink to nothing. If so, make sure our
// desired size agrees.
if (aReflowState.availableWidth == 0) {
aDesiredSize.width = 0;
}
if (aReflowState.availableHeight == 0) {
aDesiredSize.height = 0;
}
return NS_OK;
}
NS_IMETHODIMP nsScrollbarFrame::IsPercentageBase(PRBool& aBase) const
{
// Return true so that the nsHTMLReflowState code is happy with us

View File

@ -95,6 +95,11 @@ public:
nsStyleContext* aContext,
nsIFrame* aPrevInFlow);
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD IsPercentageBase(PRBool& aBase) const;
// nsIScrollbarFrame