From 20504d8ff0074d0e7ad1feb1cec15719e5eb7427 Mon Sep 17 00:00:00 2001 From: "roc+@cs.cmu.edu" Date: Thu, 28 Feb 2008 12:37:06 -0800 Subject: [PATCH] Bug 405952. Add scrollbar width to pref and min widths for overflow:scroll elements but for no other overflow values. r+sr=bzbarsky,dbaron,dholbert, a=beltzner --- layout/forms/nsListControlFrame.cpp | 21 +++++++++-- layout/forms/nsListControlFrame.h | 2 +- layout/generic/nsGfxScrollFrame.cpp | 32 +++++++++-------- layout/generic/nsGfxScrollFrame.h | 1 + layout/reftests/bugs/405952-1-ref.html | 42 ++++++++++++++++++++++ layout/reftests/bugs/405952-1.html | 48 ++++++++++++++++++++++++++ layout/reftests/bugs/reftest.list | 1 + 7 files changed, 129 insertions(+), 18 deletions(-) create mode 100644 layout/reftests/bugs/405952-1-ref.html create mode 100644 layout/reftests/bugs/405952-1.html diff --git a/layout/forms/nsListControlFrame.cpp b/layout/forms/nsListControlFrame.cpp index 6c8221641e78..b86dfe9c4f90 100644 --- a/layout/forms/nsListControlFrame.cpp +++ b/layout/forms/nsListControlFrame.cpp @@ -525,14 +525,31 @@ nsListControlFrame::CalcHeightOfARow() return heightOfARow; } +nscoord +nsListControlFrame::GetPrefWidth(nsIRenderingContext *aRenderingContext) +{ + nscoord result; + DISPLAY_PREF_WIDTH(this, result); + + // Always add scrollbar widths to the pref-width of the scrolled + // content. Combobox frames depend on this happening in the dropdown, + // and standalone listboxes are overflow:scroll so they need it too. + result = GetScrolledFrame()->GetPrefWidth(aRenderingContext); + nsBoxLayoutState bls(PresContext(), aRenderingContext); + result = NSCoordSaturatingAdd(result, GetDesiredScrollbarSizes(&bls).LeftRight()); + + return result; +} + nscoord nsListControlFrame::GetMinWidth(nsIRenderingContext *aRenderingContext) { - // Scrollframes typically have an intrinsic min width of 0, but - // that's not how we want to behave. nscoord result; DISPLAY_MIN_WIDTH(this, result); + // Always add scrollbar widths to the min-width of the scrolled + // content. Combobox frames depend on this happening in the dropdown, + // and standalone listboxes are overflow:scroll so they need it too. result = GetScrolledFrame()->GetMinWidth(aRenderingContext); nsBoxLayoutState bls(PresContext(), aRenderingContext); result += GetDesiredScrollbarSizes(&bls).LeftRight(); diff --git a/layout/forms/nsListControlFrame.h b/layout/forms/nsListControlFrame.h index b79bc4ed69d3..be38723b2b7f 100644 --- a/layout/forms/nsListControlFrame.h +++ b/layout/forms/nsListControlFrame.h @@ -91,7 +91,7 @@ public: NS_IMETHOD SetInitialChildList(nsIAtom* aListName, nsIFrame* aChildList); - // Our min width is our pref width + virtual nscoord GetPrefWidth(nsIRenderingContext *aRenderingContext); virtual nscoord GetMinWidth(nsIRenderingContext *aRenderingContext); NS_IMETHOD Reflow(nsPresContext* aCX, diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 0713a9081c0a..504abedbb914 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -699,32 +699,34 @@ nsHTMLScrollFrame::PlaceScrollArea(const ScrollReflowState& aState) NS_FRAME_NO_MOVE_VIEW); } +nscoord +nsHTMLScrollFrame::GetIntrinsicVScrollbarWidth(nsIRenderingContext *aRenderingContext) +{ + nsGfxScrollFrameInner::ScrollbarStyles ss = GetScrollbarStyles(); + if (ss.mVertical != NS_STYLE_OVERFLOW_SCROLL || !mInner.mVScrollbarBox) + return 0; + + nsBoxLayoutState bls(PresContext(), aRenderingContext); + nsSize vScrollbarPrefSize(0, 0); + GetScrollbarMetrics(bls, mInner.mVScrollbarBox, + nsnull, &vScrollbarPrefSize, PR_TRUE); + return vScrollbarPrefSize.width; +} + /* virtual */ nscoord nsHTMLScrollFrame::GetMinWidth(nsIRenderingContext *aRenderingContext) { nscoord result = mInner.mScrolledFrame->GetMinWidth(aRenderingContext); DISPLAY_MIN_WIDTH(this, result); - return result; + return result + GetIntrinsicVScrollbarWidth(aRenderingContext); } /* virtual */ nscoord nsHTMLScrollFrame::GetPrefWidth(nsIRenderingContext *aRenderingContext) { - nscoord result; + nscoord result = mInner.mScrolledFrame->GetPrefWidth(aRenderingContext); DISPLAY_PREF_WIDTH(this, result); - result = mInner.mScrolledFrame->GetPrefWidth(aRenderingContext); - - nsGfxScrollFrameInner::ScrollbarStyles ss = GetScrollbarStyles(); - if (ss.mVertical != NS_STYLE_OVERFLOW_HIDDEN && // ideal? - mInner.mVScrollbarBox) { - nsBoxLayoutState bls(PresContext(), aRenderingContext); - nsSize vScrollbarPrefSize(0, 0); - GetScrollbarMetrics(bls, mInner.mVScrollbarBox, - nsnull, &vScrollbarPrefSize, PR_TRUE); - result = NSCoordSaturatingAdd(result, vScrollbarPrefSize.width); - } - - return result; + return NSCoordSaturatingAdd(result, GetIntrinsicVScrollbarWidth(aRenderingContext)); } NS_IMETHODIMP diff --git a/layout/generic/nsGfxScrollFrame.h b/layout/generic/nsGfxScrollFrame.h index 8f3c75f8dcd5..210cfd58a4d2 100644 --- a/layout/generic/nsGfxScrollFrame.h +++ b/layout/generic/nsGfxScrollFrame.h @@ -275,6 +275,7 @@ public: nsresult ReflowContents(ScrollReflowState* aState, const nsHTMLReflowMetrics& aDesiredSize); void PlaceScrollArea(const ScrollReflowState& aState); + nscoord GetIntrinsicVScrollbarWidth(nsIRenderingContext *aRenderingContext); virtual nscoord GetMinWidth(nsIRenderingContext *aRenderingContext); virtual nscoord GetPrefWidth(nsIRenderingContext *aRenderingContext); diff --git a/layout/reftests/bugs/405952-1-ref.html b/layout/reftests/bugs/405952-1-ref.html new file mode 100644 index 000000000000..53254129955d --- /dev/null +++ b/layout/reftests/bugs/405952-1-ref.html @@ -0,0 +1,42 @@ + + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+ + + diff --git a/layout/reftests/bugs/405952-1.html b/layout/reftests/bugs/405952-1.html new file mode 100644 index 000000000000..d94df11fe7fc --- /dev/null +++ b/layout/reftests/bugs/405952-1.html @@ -0,0 +1,48 @@ + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index 25bdce46d4cf..6a59d5f4f9f0 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -682,6 +682,7 @@ random == 403134-1.html 403134-1-ref.html # bug 405377 == 405517-1.xhtml 405517-1-ref.xhtml == 405577-1.html 405577-1-ref.html == 405584-1.html 405584-1-ref.html +== 405952-1.html 405952-1-ref.html == 406073-1.html 406073-1-ref.html == 406484-1.html 406484-1-ref.html == 406568-1.html 406568-1-ref.html