Bug 425253. Propagate reflow-depth tracking through XUL box layout. r+sr=dbaron,a=damon

This commit is contained in:
roc+%cs.cmu.edu 2008-04-10 04:39:42 +00:00
Родитель bf1d22b29b
Коммит dace788ee4
11 изменённых файлов: 48 добавлений и 25 удалений

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

@ -88,7 +88,6 @@
#include "nsContentCreatorFunctions.h" #include "nsContentCreatorFunctions.h"
#include "nsLayoutUtils.h" #include "nsLayoutUtils.h"
#include "nsDisplayList.h" #include "nsDisplayList.h"
#include "nsBoxLayoutState.h"
#include "nsITheme.h" #include "nsITheme.h"
#include "nsThemeConstants.h" #include "nsThemeConstants.h"
@ -574,8 +573,8 @@ nsComboboxControlFrame::GetIntrinsicWidth(nsIRenderingContext* aRenderingContext
nsIScrollableFrame* scrollable; nsIScrollableFrame* scrollable;
CallQueryInterface(mListControlFrame, &scrollable); CallQueryInterface(mListControlFrame, &scrollable);
NS_ASSERTION(scrollable, "List must be a scrollable frame"); NS_ASSERTION(scrollable, "List must be a scrollable frame");
nsBoxLayoutState bls(presContext, aRenderingContext); scrollbarWidth =
scrollbarWidth = scrollable->GetDesiredScrollbarSizes(&bls).LeftRight(); scrollable->GetDesiredScrollbarSizes(presContext, aRenderingContext).LeftRight();
} }
nscoord displayWidth = 0; nscoord displayWidth = 0;
@ -680,8 +679,9 @@ nsComboboxControlFrame::Reflow(nsPresContext* aPresContext,
nsIScrollableFrame* scrollable; nsIScrollableFrame* scrollable;
CallQueryInterface(mListControlFrame, &scrollable); CallQueryInterface(mListControlFrame, &scrollable);
NS_ASSERTION(scrollable, "List must be a scrollable frame"); NS_ASSERTION(scrollable, "List must be a scrollable frame");
nsBoxLayoutState bls(PresContext(), aReflowState.rendContext); buttonWidth =
buttonWidth = scrollable->GetDesiredScrollbarSizes(&bls).LeftRight(); scrollable->GetDesiredScrollbarSizes(PresContext(),
aReflowState.rendContext).LeftRight();
if (buttonWidth > aReflowState.ComputedWidth()) { if (buttonWidth > aReflowState.ComputedWidth()) {
buttonWidth = 0; buttonWidth = 0;
} }

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

@ -90,7 +90,6 @@
#include "nsIDOMKeyListener.h" #include "nsIDOMKeyListener.h"
#include "nsLayoutUtils.h" #include "nsLayoutUtils.h"
#include "nsDisplayList.h" #include "nsDisplayList.h"
#include "nsBoxLayoutState.h"
// Constants // Constants
const nscoord kMaxDropDownRows = 20; // This matches the setting for 4.x browsers const nscoord kMaxDropDownRows = 20; // This matches the setting for 4.x browsers
@ -535,8 +534,8 @@ nsListControlFrame::GetPrefWidth(nsIRenderingContext *aRenderingContext)
// content. Combobox frames depend on this happening in the dropdown, // content. Combobox frames depend on this happening in the dropdown,
// and standalone listboxes are overflow:scroll so they need it too. // and standalone listboxes are overflow:scroll so they need it too.
result = GetScrolledFrame()->GetPrefWidth(aRenderingContext); result = GetScrolledFrame()->GetPrefWidth(aRenderingContext);
nsBoxLayoutState bls(PresContext(), aRenderingContext); result = NSCoordSaturatingAdd(result,
result = NSCoordSaturatingAdd(result, GetDesiredScrollbarSizes(&bls).LeftRight()); GetDesiredScrollbarSizes(PresContext(), aRenderingContext).LeftRight());
return result; return result;
} }
@ -551,8 +550,7 @@ nsListControlFrame::GetMinWidth(nsIRenderingContext *aRenderingContext)
// content. Combobox frames depend on this happening in the dropdown, // content. Combobox frames depend on this happening in the dropdown,
// and standalone listboxes are overflow:scroll so they need it too. // and standalone listboxes are overflow:scroll so they need it too.
result = GetScrolledFrame()->GetMinWidth(aRenderingContext); result = GetScrolledFrame()->GetMinWidth(aRenderingContext);
nsBoxLayoutState bls(PresContext(), aRenderingContext); result += GetDesiredScrollbarSizes(PresContext(), aRenderingContext).LeftRight();
result += GetDesiredScrollbarSizes(&bls).LeftRight();
return result; return result;
} }

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

@ -1383,8 +1383,8 @@ nsTextControlFrame::CalcIntrinsicSize(nsIRenderingContext* aRenderingContext,
CallQueryInterface(first, &scrollableFrame); CallQueryInterface(first, &scrollableFrame);
NS_ASSERTION(scrollableFrame, "Child must be scrollable"); NS_ASSERTION(scrollableFrame, "Child must be scrollable");
nsBoxLayoutState bls(PresContext(), aRenderingContext); nsMargin scrollbarSizes =
nsMargin scrollbarSizes = scrollableFrame->GetDesiredScrollbarSizes(&bls); scrollableFrame->GetDesiredScrollbarSizes(PresContext(), aRenderingContext);
aIntrinsicSize.width += scrollbarSizes.LeftRight(); aIntrinsicSize.width += scrollbarSizes.LeftRight();

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

@ -84,7 +84,6 @@
#include "nsIAccessibilityService.h" #include "nsIAccessibilityService.h"
#endif #endif
#include "nsLayoutUtils.h" #include "nsLayoutUtils.h"
#include "nsBoxLayoutState.h"
#include "nsDisplayList.h" #include "nsDisplayList.h"
#include "nsContentErrors.h" #include "nsContentErrors.h"
#include "nsCSSAnonBoxes.h" #include "nsCSSAnonBoxes.h"
@ -822,9 +821,9 @@ CalculateContainingBlockSizeForAbsolutes(const nsHTMLReflowState& aReflowState,
CallQueryInterface(aLastRS->frame, &scrollFrame); CallQueryInterface(aLastRS->frame, &scrollFrame);
nsMargin scrollbars(0,0,0,0); nsMargin scrollbars(0,0,0,0);
if (scrollFrame) { if (scrollFrame) {
nsBoxLayoutState dummyState(aLastRS->frame->PresContext(), scrollbars =
aLastRS->rendContext); scrollFrame->GetDesiredScrollbarSizes(aLastRS->frame->PresContext(),
scrollbars = scrollFrame->GetDesiredScrollbarSizes(&dummyState); aLastRS->rendContext);
if (!lastButOneRS->mFlags.mAssumingHScrollbar) { if (!lastButOneRS->mFlags.mAssumingHScrollbar) {
scrollbars.top = scrollbars.bottom = 0; scrollbars.top = scrollbars.bottom = 0;
} }

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

@ -6198,6 +6198,7 @@ nsFrame::BoxReflow(nsBoxLayoutState& aState,
// messes up dimensions. // messes up dimensions.
reflowState.parentReflowState = &parentReflowState; reflowState.parentReflowState = &parentReflowState;
reflowState.mCBReflowState = &parentReflowState; reflowState.mCBReflowState = &parentReflowState;
reflowState.mReflowDepth = aState.GetReflowDepth();
// mComputedWidth and mComputedHeight are content-box, not // mComputedWidth and mComputedHeight are content-box, not
// border-box // border-box

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

@ -253,7 +253,9 @@ struct ScrollReflowState {
ScrollReflowState(nsIScrollableFrame* aFrame, ScrollReflowState(nsIScrollableFrame* aFrame,
const nsHTMLReflowState& aState) : const nsHTMLReflowState& aState) :
mReflowState(aState), mReflowState(aState),
mBoxState(aState.frame->PresContext(), aState.rendContext), // mBoxState is just used for scrollbars so we don't need to
// worry about the reflow depth here
mBoxState(aState.frame->PresContext(), aState.rendContext, 0),
mStyles(aFrame->GetScrollbarStyles()) { mStyles(aFrame->GetScrollbarStyles()) {
} }
}; };
@ -706,7 +708,9 @@ nsHTMLScrollFrame::GetIntrinsicVScrollbarWidth(nsIRenderingContext *aRenderingCo
if (ss.mVertical != NS_STYLE_OVERFLOW_SCROLL || !mInner.mVScrollbarBox) if (ss.mVertical != NS_STYLE_OVERFLOW_SCROLL || !mInner.mVScrollbarBox)
return 0; return 0;
nsBoxLayoutState bls(PresContext(), aRenderingContext); // Don't need to worry about reflow depth here since it's
// just for scrollbars
nsBoxLayoutState bls(PresContext(), aRenderingContext, 0);
nsSize vScrollbarPrefSize(0, 0); nsSize vScrollbarPrefSize(0, 0);
GetScrollbarMetrics(bls, mInner.mVScrollbarBox, GetScrollbarMetrics(bls, mInner.mVScrollbarBox,
nsnull, &vScrollbarPrefSize, PR_TRUE); nsnull, &vScrollbarPrefSize, PR_TRUE);

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

@ -51,6 +51,7 @@
#include "nsIScrollableView.h" #include "nsIScrollableView.h"
#include "nsIView.h" #include "nsIView.h"
#include "nsIReflowCallback.h" #include "nsIReflowCallback.h"
#include "nsBoxLayoutState.h"
class nsPresContext; class nsPresContext;
class nsIPresShell; class nsIPresShell;
@ -364,6 +365,11 @@ public:
return mInner.GetActualScrollbarSizes(); return mInner.GetActualScrollbarSizes();
} }
virtual nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState); virtual nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState);
virtual nsMargin GetDesiredScrollbarSizes(nsPresContext* aPresContext,
nsIRenderingContext* aRC) {
nsBoxLayoutState bls(aPresContext, aRC, 0);
return GetDesiredScrollbarSizes(&bls);
}
virtual nsGfxScrollFrameInner::ScrollbarStyles GetScrollbarStyles() const; virtual nsGfxScrollFrameInner::ScrollbarStyles GetScrollbarStyles() const;
/** /**
@ -561,6 +567,11 @@ public:
return mInner.GetActualScrollbarSizes(); return mInner.GetActualScrollbarSizes();
} }
virtual nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState); virtual nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState);
virtual nsMargin GetDesiredScrollbarSizes(nsPresContext* aPresContext,
nsIRenderingContext* aRC) {
nsBoxLayoutState bls(aPresContext, aRC, 0);
return GetDesiredScrollbarSizes(&bls);
}
virtual nsGfxScrollFrameInner::ScrollbarStyles GetScrollbarStyles() const; virtual nsGfxScrollFrameInner::ScrollbarStyles GetScrollbarStyles() const;
/** /**

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

@ -85,7 +85,9 @@ public:
* be visible due to overflowing content, are. * be visible due to overflowing content, are.
*/ */
virtual nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState) = 0; virtual nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState) = 0;
virtual nsMargin GetDesiredScrollbarSizes(nsPresContext* aPresContext,
nsIRenderingContext* aRC) = 0;
/** /**
* Get the position of the scrolled view. * Get the position of the scrolled view.
*/ */

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

@ -705,7 +705,8 @@ nsBoxFrame::Reflow(nsPresContext* aPresContext,
aStatus = NS_FRAME_COMPLETE; aStatus = NS_FRAME_COMPLETE;
// create the layout state // create the layout state
nsBoxLayoutState state(aPresContext, aReflowState.rendContext); nsBoxLayoutState state(aPresContext, aReflowState.rendContext,
aReflowState.mReflowDepth);
nsSize computedSize(aReflowState.ComputedWidth(),aReflowState.ComputedHeight()); nsSize computedSize(aReflowState.ComputedWidth(),aReflowState.ComputedHeight());

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

@ -45,10 +45,12 @@
#include "nsBoxLayoutState.h" #include "nsBoxLayoutState.h"
nsBoxLayoutState::nsBoxLayoutState(nsPresContext* aPresContext, nsBoxLayoutState::nsBoxLayoutState(nsPresContext* aPresContext,
nsIRenderingContext* aRenderingContext) nsIRenderingContext* aRenderingContext,
PRUint16 aReflowDepth)
: mPresContext(aPresContext) : mPresContext(aPresContext)
, mRenderingContext(aRenderingContext) , mRenderingContext(aRenderingContext)
, mLayoutFlags(0) , mLayoutFlags(0)
, mReflowDepth(aReflowDepth)
, mPaintingDisabled(PR_FALSE) , mPaintingDisabled(PR_FALSE)
{ {
NS_ASSERTION(mPresContext, "PresContext must be non-null"); NS_ASSERTION(mPresContext, "PresContext must be non-null");
@ -58,6 +60,7 @@ nsBoxLayoutState::nsBoxLayoutState(const nsBoxLayoutState& aState)
: mPresContext(aState.mPresContext) : mPresContext(aState.mPresContext)
, mRenderingContext(aState.mRenderingContext) , mRenderingContext(aState.mRenderingContext)
, mLayoutFlags(aState.mLayoutFlags) , mLayoutFlags(aState.mLayoutFlags)
, mReflowDepth(aState.mReflowDepth + 1)
, mPaintingDisabled(aState.mPaintingDisabled) , mPaintingDisabled(aState.mPaintingDisabled)
{ {
NS_ASSERTION(mPresContext, "PresContext must be non-null"); NS_ASSERTION(mPresContext, "PresContext must be non-null");

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

@ -59,7 +59,8 @@ class nsHTMLReflowCommand;
class nsBoxLayoutState class nsBoxLayoutState
{ {
public: public:
nsBoxLayoutState(nsPresContext* aPresContext, nsIRenderingContext* aRenderingContext = nsnull) NS_HIDDEN; nsBoxLayoutState(nsPresContext* aPresContext, nsIRenderingContext* aRenderingContext = nsnull,
PRUint16 aReflowDepth = 0) NS_HIDDEN;
nsBoxLayoutState(const nsBoxLayoutState& aState) NS_HIDDEN; nsBoxLayoutState(const nsBoxLayoutState& aState) NS_HIDDEN;
nsPresContext* PresContext() const { return mPresContext; } nsPresContext* PresContext() const { return mPresContext; }
@ -78,16 +79,19 @@ public:
// doing box layout or intrinsic size calculation will cause bugs. // doing box layout or intrinsic size calculation will cause bugs.
nsIRenderingContext* GetRenderingContext() const { return mRenderingContext; } nsIRenderingContext* GetRenderingContext() const { return mRenderingContext; }
void PushStackMemory() { PresShell()->PushStackMemory(); } void PushStackMemory() { PresShell()->PushStackMemory(); ++mReflowDepth; }
void PopStackMemory() { PresShell()->PopStackMemory(); } void PopStackMemory() { PresShell()->PopStackMemory(); --mReflowDepth; }
void* AllocateStackMemory(size_t aSize) void* AllocateStackMemory(size_t aSize)
{ return PresShell()->AllocateStackMemory(aSize); } { return PresShell()->AllocateStackMemory(aSize); }
PRUint16 GetReflowDepth() { return mReflowDepth; }
private: private:
nsCOMPtr<nsPresContext> mPresContext; nsCOMPtr<nsPresContext> mPresContext;
nsIRenderingContext *mRenderingContext; nsIRenderingContext *mRenderingContext;
PRUint32 mLayoutFlags; PRUint32 mLayoutFlags;
PRBool mPaintingDisabled; PRUint16 mReflowDepth;
PRPackedBool mPaintingDisabled;
}; };
#endif #endif