Bug 743402, Part 4: Refactor ApplySkipSides() and GetSkipSides() to return the correct value during reflow by adding an optional nsHTMLReflowState parameter. [r=roc]

This commit is contained in:
Scott Johnson 2013-07-25 10:34:27 -05:00
parent c9182b38da
commit a5680b3063
22 changed files with 85 additions and 40 deletions

View File

@ -5993,24 +5993,6 @@ nsBlockFrame::RecoverFloatsFor(nsIFrame* aFrame,
//////////////////////////////////////////////////////////////////////
// Painting, event handling
int
nsBlockFrame::GetSkipSides() const
{
if (IS_TRUE_OVERFLOW_CONTAINER(this)) {
return (1 << NS_SIDE_TOP) | (1 << NS_SIDE_BOTTOM);
}
int skip = 0;
if (GetPrevInFlow()) {
skip |= 1 << NS_SIDE_TOP;
}
nsIFrame* nif = GetNextInFlow();
if (nif && !IS_TRUE_OVERFLOW_CONTAINER(nif)) {
skip |= 1 << NS_SIDE_BOTTOM;
}
return skip;
}
#ifdef DEBUG
static void ComputeVisualOverflowArea(nsLineList& aLines,
nscoord aWidth, nscoord aHeight,

View File

@ -438,8 +438,6 @@ protected:
void SlideLine(nsBlockReflowState& aState,
nsLineBox* aLine, nscoord aDY);
virtual int GetSkipSides() const MOZ_OVERRIDE;
void ComputeFinalSize(const nsHTMLReflowState& aReflowState,
nsBlockReflowState& aState,
nsHTMLReflowMetrics& aMetrics,

View File

@ -1100,7 +1100,7 @@ nsFlexContainerFrame::GetType() const
/* virtual */
int
nsFlexContainerFrame::GetSkipSides() const
nsFlexContainerFrame::GetSkipSides(const nsHTMLReflowState* aReflowState) const
{
// (same as nsBlockFrame's GetSkipSides impl)
if (IS_TRUE_OVERFLOW_CONTAINER(this)) {

View File

@ -50,7 +50,7 @@ public:
GetPrefWidth(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE;
virtual nsIAtom* GetType() const MOZ_OVERRIDE;
virtual int GetSkipSides() const MOZ_OVERRIDE;
virtual int GetSkipSides(const nsHTMLReflowState* aReflowState = nullptr) const MOZ_OVERRIDE;
#ifdef DEBUG
NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
#endif // DEBUG

View File

@ -958,9 +958,10 @@ nsIFrame::GetUsedPadding() const
}
void
nsIFrame::ApplySkipSides(nsMargin& aMargin) const
nsIFrame::ApplySkipSides(nsMargin& aMargin,
const nsHTMLReflowState* aReflowState) const
{
int skipSides = GetSkipSides();
int skipSides = GetSkipSides(aReflowState);
if (skipSides & (1 << NS_SIDE_TOP))
aMargin.top = 0;
if (skipSides & (1 << NS_SIDE_RIGHT))

View File

@ -985,8 +985,21 @@ public:
/**
* Apply the result of GetSkipSides() on this frame to an nsMargin by
* setting to zero any sides that are skipped.
*
* @param aMargin The margin to apply the result of GetSkipSides() to.
* @param aReflowState An optional reflow state parameter, which is used if
* ApplySkipSides() is being called in the middle of reflow.
*
* @note (See also bug 743402, comment 11) GetSkipSides() and it's sister
* method, ApplySkipSides() checks to see if this frame has a previous
* or next continuation to determine if a side should be skipped.
* Unfortunately, this only works after reflow has been completed. In
* lieu of this, during reflow, an nsHTMLReflowState parameter can be
* passed in, indicating that it should be used to determine if sides
* should be skipped during reflow.
*/
void ApplySkipSides(nsMargin& aMargin) const;
void ApplySkipSides(nsMargin& aMargin,
const nsHTMLReflowState* aReflowState = nullptr) const;
/**
* Like the frame's rect (see |GetRect|), which is the border rect,
@ -2406,8 +2419,16 @@ public:
/**
* Determine whether borders should not be painted on certain sides of the
* frame.
*
* @note (See also bug 743402, comment 11) GetSkipSides() and it's sister
* method, ApplySkipSides() checks to see if this frame has a previous
* or next continuation to determine if a side should be skipped.
* Unfortunately, this only works after reflow has been completed. In
* lieu of this, during reflow, an nsHTMLReflowState parameter can be
* passed in, indicating that it should be used to determine if sides
* should be skipped during reflow.
*/
virtual int GetSkipSides() const { return 0; }
virtual int GetSkipSides(const nsHTMLReflowState* aReflowState = nullptr) const { return 0; }
/**
* @returns true if this frame is selected.

View File

@ -1771,7 +1771,7 @@ nsImageFrame::List(FILE* out, int32_t aIndent, uint32_t aFlags) const
#endif
int
nsImageFrame::GetSkipSides() const
nsImageFrame::GetSkipSides(const nsHTMLReflowState* aReflowState) const
{
int skip = 0;
if (nullptr != GetPrevInFlow()) {

View File

@ -116,7 +116,7 @@ public:
void List(FILE* out, int32_t aIndent, uint32_t aFlags = 0) const;
#endif
virtual int GetSkipSides() const MOZ_OVERRIDE;
virtual int GetSkipSides(const nsHTMLReflowState* aReflowState = nullptr) const MOZ_OVERRIDE;
nsresult GetIntrinsicImageSize(nsSize& aSize);

View File

@ -847,7 +847,7 @@ nsInlineFrame::PushFrames(nsPresContext* aPresContext,
//////////////////////////////////////////////////////////////////////
int
nsInlineFrame::GetSkipSides() const
nsInlineFrame::GetSkipSides(const nsHTMLReflowState* aReflowState) const
{
int skip = 0;
if (!IsLeftMost()) {

View File

@ -136,7 +136,7 @@ protected:
nsInlineFrame(nsStyleContext* aContext) : nsContainerFrame(aContext) {}
virtual int GetSkipSides() const MOZ_OVERRIDE;
virtual int GetSkipSides(const nsHTMLReflowState* aReflowState = nullptr) const MOZ_OVERRIDE;
nsresult ReflowFrames(nsPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,

View File

@ -244,6 +244,43 @@ nsSplittableFrame::GetEffectiveComputedHeight(const nsHTMLReflowState& aReflowSt
return height;
}
int
nsSplittableFrame::GetSkipSides(const nsHTMLReflowState* aReflowState) const
{
if (IS_TRUE_OVERFLOW_CONTAINER(this)) {
return (1 << NS_SIDE_TOP) | (1 << NS_SIDE_BOTTOM);
}
int skip = 0;
if (GetPrevInFlow()) {
skip |= 1 << NS_SIDE_TOP;
}
if (aReflowState) {
// We're in the midst of reflow right now, so it's possible that we haven't
// created a nif yet. If our content height is going to exceed our available
// height, though, then we're going to need a next-in-flow, it just hasn't
// been created yet.
if (NS_UNCONSTRAINEDSIZE != aReflowState->availableHeight) {
nscoord effectiveCH = this->GetEffectiveComputedHeight(*aReflowState);
if (effectiveCH > aReflowState->availableHeight) {
// Our content height is going to exceed our available height, so we're
// going to need a next-in-flow.
skip |= 1 << NS_SIDE_BOTTOM;
}
}
} else {
nsIFrame* nif = GetNextInFlow();
if (nif && !IS_TRUE_OVERFLOW_CONTAINER(nif)) {
skip |= 1 << NS_SIDE_BOTTOM;
}
}
return skip;
}
#ifdef DEBUG
void
nsSplittableFrame::DumpBaseRegressionData(nsPresContext* aPresContext, FILE* out, int32_t aIndent)

View File

@ -92,6 +92,12 @@ protected:
nscoord GetEffectiveComputedHeight(const nsHTMLReflowState& aReflowState,
nscoord aConsumed = NS_INTRINSICSIZE) const;
/**
* @see nsIFrame::GetSkipSides()
* @see nsIFrame::ApplySkipSides()
*/
virtual int GetSkipSides(const nsHTMLReflowState* aReflowState = nullptr) const;
#ifdef DEBUG
virtual void DumpBaseRegressionData(nsPresContext* aPresContext, FILE* out, int32_t aIndent) MOZ_OVERRIDE;
#endif

View File

@ -522,7 +522,7 @@ nsTableCellFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
int
nsTableCellFrame::GetSkipSides() const
nsTableCellFrame::GetSkipSides(const nsHTMLReflowState* aReflowState) const
{
int skip = 0;
if (nullptr != GetPrevInFlow()) {

View File

@ -221,7 +221,7 @@ public:
virtual void InvalidateFrameForRemoval() MOZ_OVERRIDE { InvalidateFrameSubtree(); }
protected:
virtual int GetSkipSides() const MOZ_OVERRIDE;
virtual int GetSkipSides(const nsHTMLReflowState* aReflowState= nullptr) const MOZ_OVERRIDE;
/**
* GetBorderOverflow says how far the cell's own borders extend

View File

@ -337,7 +337,7 @@ nsTableColGroupFrame::RemoveFrame(ChildListID aListID,
}
int
nsTableColGroupFrame::GetSkipSides() const
nsTableColGroupFrame::GetSkipSides(const nsHTMLReflowState* aReflowState) const
{
int skip = 0;
if (nullptr != GetPrevInFlow()) {

View File

@ -212,7 +212,7 @@ protected:
void InsertColsReflow(int32_t aColIndex,
const nsFrameList::Slice& aCols);
virtual int GetSkipSides() const MOZ_OVERRIDE;
virtual int GetSkipSides(const nsHTMLReflowState* aReflowState = nullptr) const MOZ_OVERRIDE;
// data members
int32_t mColCount;

View File

@ -1332,7 +1332,7 @@ nsTableFrame::PaintTableBorderBackground(nsRenderingContext& aRenderingContext,
}
int
nsTableFrame::GetSkipSides() const
nsTableFrame::GetSkipSides(const nsHTMLReflowState* aReflowState) const
{
int skip = 0;
// frame attribute was accounted for in nsHTMLTableElement::MapTableBorderInto

View File

@ -509,7 +509,7 @@ protected:
void InitChildReflowState(nsHTMLReflowState& aReflowState);
virtual int GetSkipSides() const MOZ_OVERRIDE;
virtual int GetSkipSides(const nsHTMLReflowState* aReflowState = nullptr) const MOZ_OVERRIDE;
public:
bool IsRowInserted() const;

View File

@ -592,7 +592,7 @@ nsTableRowFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
int
nsTableRowFrame::GetSkipSides() const
nsTableRowFrame::GetSkipSides(const nsHTMLReflowState* aReflowState) const
{
int skip = 0;
if (nullptr != GetPrevInFlow()) {

View File

@ -249,7 +249,7 @@ protected:
bool aBorderCollapse,
nsTableCellReflowState& aReflowState);
virtual int GetSkipSides() const MOZ_OVERRIDE;
virtual int GetSkipSides(const nsHTMLReflowState* aReflowState = nullptr) const MOZ_OVERRIDE;
// row-specific methods

View File

@ -244,7 +244,7 @@ nsTableRowGroupFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
int
nsTableRowGroupFrame::GetSkipSides() const
nsTableRowGroupFrame::GetSkipSides(const nsHTMLReflowState* aReflowState) const
{
int skip = 0;
if (nullptr != GetPrevInFlow()) {

View File

@ -343,7 +343,7 @@ protected:
bool aBorderCollapse,
nsHTMLReflowState& aReflowState);
virtual int GetSkipSides() const MOZ_OVERRIDE;
virtual int GetSkipSides(const nsHTMLReflowState* aReflowState = nullptr) const MOZ_OVERRIDE;
void PlaceChild(nsPresContext* aPresContext,
nsRowGroupReflowState& aReflowState,