diff --git a/layout/html/base/src/nsScrollFrame.cpp b/layout/html/base/src/nsScrollFrame.cpp index cade60df608..c9207b3a8b7 100644 --- a/layout/html/base/src/nsScrollFrame.cpp +++ b/layout/html/base/src/nsScrollFrame.cpp @@ -27,6 +27,7 @@ #include "nsIViewManager.h" #include "nsBodyFrame.h" #include "nsHTMLFrame.h" +#include "nsCSSLayout.h" #include "nsBodyFrame.h" @@ -344,7 +345,7 @@ nsScrollInnerFrame::Reflow(nsIPresContext* aPresContext, kIViewIID, (void **)&view); if ((NS_OK != rv) || (NS_OK != view->Init(viewManager, - mRect, + mRect, parentView))) { NS_RELEASE(parentView); NS_RELEASE(viewManager); @@ -361,30 +362,45 @@ nsScrollInnerFrame::Reflow(nsIPresContext* aPresContext, if (nsnull == view) { return NS_OK; } + NS_RELEASE(view); if (nsnull == mFirstChild) { mFirstChild = new nsScrollBodyFrame(mContent, this); mChildCount = 1; } - // Allow the frame to be as wide as our max width, and as high - // as it wants to be. - nsSize maxSize(aReflowState.maxSize.width, NS_UNCONSTRAINEDSIZE); - nsReflowState kidReflowState(mFirstChild, aReflowState, maxSize); + // Allow the child frame to be as wide as our max width (minus a + // scroll bar width), and as high as it wants to be. + nsSize maxSize; + nsIDeviceContext* dc = aPresContext->GetDeviceContext(); + maxSize.width = aReflowState.maxSize.width - + NS_TO_INT_ROUND(dc->GetScrollBarWidth()); + NS_RELEASE(dc); + maxSize.height = NS_UNCONSTRAINEDSIZE; - // Get the child's desired size. Our child's desired height is our - // desired size + // Reflow the child + nsReflowMetrics kidMetrics(aDesiredSize.maxElementSize); + nsReflowState kidReflowState(mFirstChild, aReflowState, maxSize); mFirstChild->WillReflow(*aPresContext); - aStatus = ReflowChild(mFirstChild, aPresContext, aDesiredSize, + aStatus = ReflowChild(mFirstChild, aPresContext, kidMetrics, kidReflowState); NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status"); // Place and size the child - nsRect rect(0, 0, aDesiredSize.width, aDesiredSize.height); + nsRect rect(0, 0, kidMetrics.width, kidMetrics.height); mFirstChild->SetRect(rect); mFirstChild->DidReflow(*aPresContext, NS_FRAME_REFLOW_FINISHED); - NS_RELEASE(view); + // Determine our size. Our width is our maxWidth and our height is + // either our child's height or our maxHeight if our maxHeight is + // constrained. + aDesiredSize.width = aReflowState.maxSize.width; + if (NS_UNCONSTRAINEDSIZE == aReflowState.maxSize.height) { + aDesiredSize.height = kidMetrics.height; + } + else { + aDesiredSize.height = aReflowState.maxSize.height; + } NS_FRAME_TRACE_MSG( ("exit nsScrollInnerFrame::Reflow: status=%d width=%d height=%d", @@ -410,7 +426,7 @@ nsScrollInnerFrame::ListTag(FILE* out) const //---------------------------------------------------------------------- -class nsScrollOuterFrame : public nsContainerFrame { +class nsScrollOuterFrame : public nsHTMLContainerFrame { public: nsScrollOuterFrame(nsIContent* aContent, nsIFrame* aParent); @@ -422,13 +438,15 @@ public: NS_IMETHOD ListTag(FILE* out = stdout) const; protected: + virtual PRIntn GetSkipSides() const; }; nsScrollOuterFrame::nsScrollOuterFrame(nsIContent* aContent, nsIFrame* aParent) - : nsContainerFrame(aContent, aParent) + : nsHTMLContainerFrame(aContent, aParent) { } +//XXX incremental reflow pass through NS_IMETHODIMP nsScrollOuterFrame::Reflow(nsIPresContext* aPresContext, nsReflowMetrics& aDesiredSize, @@ -449,14 +467,28 @@ nsScrollOuterFrame::Reflow(nsIPresContext* aPresContext, nsMargin borderPadding; spacing->CalcBorderPaddingFor(this, borderPadding); nscoord lr = borderPadding.left + borderPadding.right; + nscoord tb = borderPadding.top + borderPadding.bottom; - // Allow the frame to be as wide as our max width, and as high - // as it wants to be. - nsSize maxSize(aReflowState.maxSize.width - lr, NS_UNCONSTRAINEDSIZE); - nsReflowState kidReflowState(mFirstChild, aReflowState, maxSize); + // Get style size and determine how much area is available for the + // child (the scroll inner frame) to layout into. + nsSize maxSize, styleSize; + PRIntn sf = nsCSSLayout::GetStyleSize(aPresContext, aReflowState, + styleSize); + if (NS_SIZE_HAS_WIDTH & sf) { + maxSize.width = styleSize.width - lr; + } + else { + maxSize.width = aReflowState.maxSize.width; + } + if (NS_SIZE_HAS_HEIGHT & sf) { + maxSize.height = styleSize.height - tb; + } + else { + maxSize.height = NS_UNCONSTRAINEDSIZE; + } - // Get the child's desired size. Our child's desired height is - // approximately our desired size + // Reflow the child and get its desired size + nsReflowState kidReflowState(mFirstChild, aReflowState, maxSize); mFirstChild->WillReflow(*aPresContext); aStatus = ReflowChild(mFirstChild, aPresContext, aDesiredSize, kidReflowState); @@ -468,15 +500,26 @@ nsScrollOuterFrame::Reflow(nsIPresContext* aPresContext, mFirstChild->SetRect(rect); mFirstChild->DidReflow(*aPresContext, NS_FRAME_REFLOW_FINISHED); - aDesiredSize.width += lr; - aDesiredSize.height += borderPadding.top + borderPadding.bottom; + // The scroll outer frame either shrink wraps around it's single + // child OR uses the style width/height. + if (NS_SIZE_HAS_WIDTH & sf) { + aDesiredSize.width = styleSize.width; + } + else { + aDesiredSize.width += lr; + } + if (NS_SIZE_HAS_HEIGHT & sf) { + aDesiredSize.height = styleSize.height; + } + else { + aDesiredSize.height += tb; + } aDesiredSize.ascent = aDesiredSize.height; aDesiredSize.descent = 0; NS_FRAME_TRACE_MSG( ("exit nsScrollOuterFrame::Reflow: status=%d width=%d height=%d", aStatus, aDesiredSize.width, aDesiredSize.height)); - return NS_OK; } @@ -496,6 +539,12 @@ nsScrollOuterFrame::ListTag(FILE* out) const return NS_OK; } +PRIntn +nsScrollOuterFrame::GetSkipSides() const +{ + return 0; +} + //---------------------------------------------------------------------- nsresult diff --git a/layout/html/base/src/nsScrollFrame.h b/layout/html/base/src/nsScrollFrame.h index e51aca53504..e69de29bb2d 100644 --- a/layout/html/base/src/nsScrollFrame.h +++ b/layout/html/base/src/nsScrollFrame.h @@ -1,27 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * The contents of this file are subject to the Netscape Public License - * Version 1.0 (the "NPL"); you may not use this file except in - * compliance with the NPL. You may obtain a copy of the NPL at - * http://www.mozilla.org/NPL/ - * - * Software distributed under the NPL is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL - * for the specific language governing rights and limitations under the - * NPL. - * - * The Initial Developer of this code under the NPL is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All Rights - * Reserved. - */ -#ifndef nsScrollFrame_h___ -#define nsScrollFrame_h___ - -#include "nsContainerFrame.h" - -extern nsresult NS_NewScrollFrame(nsIFrame** aInstancePtrResult, - nsIContent* aContent, - nsIFrame* aParent); - -#endif /* nsScrollFrame_h___ */