Backed out 6 changesets (bug 743402) for reftest failures on a CLOSED TREE.

Backed out changeset 19848fff857e (bug 743402)
Backed out changeset 049168537ae0 (bug 743402)
Backed out changeset 3098fea37f2d (bug 743402)
Backed out changeset ada93e976dca (bug 743402)
Backed out changeset c7907c54187f (bug 743402)
Backed out changeset 2edbbf6440c4 (bug 743402)
This commit is contained in:
Ryan VanderMeulen 2013-07-24 15:14:04 -04:00
Родитель afbb972b95
Коммит 6e81109389
32 изменённых файлов: 150 добавлений и 423 удалений

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

@ -907,9 +907,6 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
#endif
const nsHTMLReflowState *reflowState = &aReflowState;
nscoord consumedHeight = GetConsumedHeight();
nscoord effectiveComputedHeight = GetEffectiveComputedHeight(aReflowState,
consumedHeight);
Maybe<nsHTMLReflowState> mutableReflowState;
// If we have non-auto height, we're clipping our kids and we fit,
// make sure our kids fit too.
@ -925,7 +922,7 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
heightExtras.top += aReflowState.mComputedMargin.top;
}
if (effectiveComputedHeight + heightExtras.TopBottom() <=
if (GetEffectiveComputedHeight(aReflowState) + heightExtras.TopBottom() <=
aReflowState.availableHeight) {
mutableReflowState.construct(aReflowState);
mutableReflowState.ref().availableHeight = NS_UNCONSTRAINEDSIZE;
@ -960,12 +957,8 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
bool topMarginRoot, bottomMarginRoot;
IsMarginRoot(&topMarginRoot, &bottomMarginRoot);
// Cache the consumed height in the block reflow state so that we don't have
// to continually recompute it.
nsBlockReflowState state(*reflowState, aPresContext, this,
topMarginRoot, bottomMarginRoot, needFloatManager,
consumedHeight);
topMarginRoot, bottomMarginRoot, needFloatManager);
#ifdef IBMBIDI
if (GetStateBits() & NS_BLOCK_NEEDS_BIDI_RESOLUTION)
@ -1339,13 +1332,47 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
}
// Compute final height
if (NS_UNCONSTRAINEDSIZE != aReflowState.ComputedHeight()
&& (mParent->GetType() != nsGkAtoms::columnSetFrame ||
aReflowState.parentReflowState->availableHeight == NS_UNCONSTRAINEDSIZE)) {
ComputeFinalHeight(aReflowState, &aState.mReflowStatus,
aState.mY + nonCarriedOutVerticalMargin,
borderPadding, aMetrics, aState.mConsumedHeight);
if (!NS_FRAME_IS_COMPLETE(aState.mReflowStatus)) {
if (NS_UNCONSTRAINEDSIZE != aReflowState.ComputedHeight()) {
// Figure out how much of the computed height should be
// applied to this frame.
nscoord computedHeightLeftOver = GetEffectiveComputedHeight(aReflowState);
NS_ASSERTION(!( IS_TRUE_OVERFLOW_CONTAINER(this)
&& computedHeightLeftOver ),
"overflow container must not have computedHeightLeftOver");
aMetrics.height =
NSCoordSaturatingAdd(NSCoordSaturatingAdd(borderPadding.top,
computedHeightLeftOver),
borderPadding.bottom);
if (NS_FRAME_IS_NOT_COMPLETE(aState.mReflowStatus)
&& aMetrics.height < aReflowState.availableHeight) {
// We ran out of height on this page but we're incomplete
// Set status to complete except for overflow
NS_FRAME_SET_OVERFLOW_INCOMPLETE(aState.mReflowStatus);
}
if (NS_FRAME_IS_COMPLETE(aState.mReflowStatus)) {
if (computedHeightLeftOver > 0 &&
NS_UNCONSTRAINEDSIZE != aReflowState.availableHeight &&
aMetrics.height > aReflowState.availableHeight) {
if (ShouldAvoidBreakInside(aReflowState)) {
aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE();
return;
}
// We don't fit and we consumed some of the computed height,
// so we should consume all the available height and then
// break. If our bottom border/padding straddles the break
// point, then this will increase our height and push the
// border/padding to the next page/column.
aMetrics.height = std::max(aReflowState.availableHeight,
aState.mY + nonCarriedOutVerticalMargin);
NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus);
if (!GetNextInFlow())
aState.mReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW;
}
}
else {
// Use the current height; continuations will take up the rest.
// Do extend the height to at least consume the available
// height, otherwise our left/right borders (for example) won't
@ -1353,10 +1380,8 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
aMetrics.height = std::max(aReflowState.availableHeight,
aState.mY + nonCarriedOutVerticalMargin);
// ... but don't take up more height than is available
nscoord effectiveComputedHeight =
GetEffectiveComputedHeight(aReflowState, aState.GetConsumedHeight());
aMetrics.height = std::min(aMetrics.height,
borderPadding.top + effectiveComputedHeight);
borderPadding.top + computedHeightLeftOver);
// XXX It's pretty wrong that our bottom border still gets drawn on
// on its own on the last-in-flow, even if we ran out of height
// here. We need GetSkipSides to check whether we ran out of content
@ -5994,6 +6019,24 @@ 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,
@ -7035,6 +7078,26 @@ nsBlockFrame::GetNearestAncestorBlock(nsIFrame* aCandidate)
return nullptr;
}
nscoord
nsBlockFrame::GetEffectiveComputedHeight(const nsHTMLReflowState& aReflowState) const
{
nscoord height = aReflowState.ComputedHeight();
NS_ABORT_IF_FALSE(height != NS_UNCONSTRAINEDSIZE, "Don't call me!");
if (GetPrevInFlow()) {
// Reduce the height by the computed height of prev-in-flows.
for (nsIFrame* prev = GetPrevInFlow(); prev; prev = prev->GetPrevInFlow()) {
height -= prev->GetRect().height;
}
// We just subtracted our top-border padding, since it was included in the
// first frame's height. Add it back to get the content height.
height += aReflowState.mComputedBorderPadding.top;
// We may have stretched the frame beyond its computed height. Oh well.
height = std::max(0, height);
}
return height;
}
#ifdef IBMBIDI
nsresult
nsBlockFrame::ResolveBidi()

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

@ -412,6 +412,8 @@ protected:
void SlideLine(nsBlockReflowState& aState,
nsLineBox* aLine, nscoord aDY);
virtual int GetSkipSides() const MOZ_OVERRIDE;
void ComputeFinalSize(const nsHTMLReflowState& aReflowState,
nsBlockReflowState& aState,
nsHTMLReflowMetrics& aMetrics,
@ -794,6 +796,13 @@ protected:
void SetOverflowLines(FrameLines* aOverflowLines);
void DestroyOverflowLines();
// Determine the computed height that's in effect for this block
// frame (that is, our computed height minus the heights of our
// previous in-flows).
// XXXbz this clearly makes laying out a block with N in-flows
// O(N^2)! Good thing the constant is tiny.
nscoord GetEffectiveComputedHeight(const nsHTMLReflowState& aReflowState) const;
/**
* This class is useful for efficiently modifying the out of flow
* overflow list. It gives the client direct writable access to

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

@ -35,8 +35,7 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
nsBlockFrame* aFrame,
bool aTopMarginRoot,
bool aBottomMarginRoot,
bool aBlockNeedsFloatManager,
nscoord aConsumedHeight)
bool aBlockNeedsFloatManager)
: mBlock(aFrame),
mPresContext(aPresContext),
mReflowState(aReflowState),
@ -45,8 +44,7 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
mPrevBottomMargin(),
mLineNumber(0),
mFlags(0),
mFloatBreakType(NS_STYLE_CLEAR_NONE),
mConsumedHeight(aConsumedHeight)
mFloatBreakType(NS_STYLE_CLEAR_NONE)
{
SetFlag(BRS_ISFIRSTINFLOW, aFrame->GetPrevInFlow() == nullptr);
SetFlag(BRS_ISOVERFLOWCONTAINER,
@ -115,16 +113,6 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
mMinLineHeight = aReflowState.CalcLineHeight();
}
nscoord
nsBlockReflowState::GetConsumedHeight()
{
if (mConsumedHeight == NS_INTRINSICSIZE) {
mConsumedHeight = mBlock->GetConsumedHeight();
}
return mConsumedHeight;
}
void
nsBlockReflowState::ComputeReplacedBlockOffsetsForFloats(nsIFrame* aFrame,
const nsRect& aFloatAvailableSpace,

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

@ -40,8 +40,7 @@ public:
nsPresContext* aPresContext,
nsBlockFrame* aFrame,
bool aTopMarginRoot, bool aBottomMarginRoot,
bool aBlockNeedsFloatManager,
nscoord aConsumedHeight = NS_INTRINSICSIZE);
bool aBlockNeedsFloatManager);
/**
* Get the available reflow space (the area not occupied by floats)
@ -111,11 +110,6 @@ public:
return result;
}
/**
* Retrieve the height "consumed" by any previous-in-flows.
*/
nscoord GetConsumedHeight();
// Reconstruct the previous bottom margin that goes above |aLine|.
void ReconstructMarginAbove(nsLineList::iterator aLine);
@ -263,9 +257,6 @@ public:
uint8_t mFloatBreakType;
// The amount of computed height "consumed" by previous-in-flows.
nscoord mConsumedHeight;
void SetFlag(uint32_t aFlag, bool aValue)
{
NS_ASSERTION(aFlag<=BRS_LASTFLAG, "bad flag");

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

@ -146,17 +146,16 @@ GetAvailableContentWidth(const nsHTMLReflowState& aReflowState)
return std::max(0, aReflowState.availableWidth - borderPaddingWidth);
}
nscoord
nsColumnSetFrame::GetAvailableContentHeight(const nsHTMLReflowState& aReflowState)
static nscoord
GetAvailableContentHeight(const nsHTMLReflowState& aReflowState)
{
if (aReflowState.availableHeight == NS_INTRINSICSIZE) {
return NS_INTRINSICSIZE;
}
nsMargin bp = aReflowState.mComputedBorderPadding;
ApplySkipSides(bp, &aReflowState);
bp.bottom = aReflowState.mComputedBorderPadding.bottom;
return std::max(0, aReflowState.availableHeight - bp.TopBottom());
nscoord borderPaddingHeight =
aReflowState.mComputedBorderPadding.top +
aReflowState.mComputedBorderPadding.bottom;
return std::max(0, aReflowState.availableHeight - borderPaddingHeight);
}
static nscoord
@ -190,20 +189,11 @@ nsColumnSetFrame::ChooseColumnStrategy(const nsHTMLReflowState& aReflowState,
if (aReflowState.ComputedWidth() != NS_INTRINSICSIZE) {
availContentWidth = aReflowState.ComputedWidth();
}
nscoord consumedHeight = GetConsumedHeight();
// The effective computed height is the height of the current continuation
// of the column set frame. This should be the same as the computed height
// if we have an unconstrained available height.
nscoord computedHeight = GetEffectiveComputedHeight(aReflowState,
consumedHeight);
nscoord colHeight = GetAvailableContentHeight(aReflowState);
if (aReflowState.ComputedHeight() != NS_INTRINSICSIZE) {
colHeight = aReflowState.ComputedHeight();
} else if (aReflowState.mComputedMaxHeight != NS_INTRINSICSIZE) {
colHeight = std::min(colHeight, aReflowState.mComputedMaxHeight);
colHeight = aReflowState.mComputedMaxHeight;
}
nscoord colGap = GetColumnGap(this, colStyle);
@ -312,7 +302,7 @@ nsColumnSetFrame::ChooseColumnStrategy(const nsHTMLReflowState& aReflowState,
#endif
ReflowConfig config = { numColumns, colWidth, expectedWidthLeftOver, colGap,
colHeight, isBalancing, knownFeasibleHeight,
knownInfeasibleHeight, computedHeight, consumedHeight };
knownInfeasibleHeight };
return config;
}
@ -463,8 +453,7 @@ nsColumnSetFrame::ReflowChildren(nsHTMLReflowMetrics& aDesiredSize,
}
// get our border and padding
nsMargin borderPadding = aReflowState.mComputedBorderPadding;
ApplySkipSides(borderPadding, &aReflowState);
const nsMargin &borderPadding = aReflowState.mComputedBorderPadding;
nsRect contentRect(0, 0, 0, 0);
nsOverflowAreas overflowRects;
@ -735,32 +724,30 @@ nsColumnSetFrame::ReflowChildren(nsHTMLReflowMetrics& aDesiredSize,
nsSize contentSize = nsSize(contentRect.XMost(), contentRect.YMost());
// Apply computed and min/max values
if (aConfig.mComputedHeight != NS_INTRINSICSIZE) {
if (aReflowState.availableHeight != NS_INTRINSICSIZE) {
contentSize.height = std::min(contentSize.height,
aConfig.mComputedHeight);
} else {
contentSize.height = aConfig.mComputedHeight;
}
if (aReflowState.ComputedHeight() != NS_INTRINSICSIZE) {
contentSize.height = aReflowState.ComputedHeight();
} else {
// We add the "consumed" height back in so that we're applying
// constraints to the correct height value, then subtract it again
// after we've finished with the min/max calculation. This prevents us from
// having a last continuation that is smaller than the min height. but which
// has prev-in-flows, trigger a larger height than actually required.
contentSize.height = aReflowState.ApplyMinMaxHeight(contentSize.height,
aConfig.mConsumedHeight);
if (NS_UNCONSTRAINEDSIZE != aReflowState.mComputedMaxHeight) {
contentSize.height = std::min(aReflowState.mComputedMaxHeight, contentSize.height);
}
if (NS_UNCONSTRAINEDSIZE != aReflowState.mComputedMinHeight) {
contentSize.height = std::max(aReflowState.mComputedMinHeight, contentSize.height);
}
}
if (aReflowState.ComputedWidth() != NS_INTRINSICSIZE) {
contentSize.width = aReflowState.ComputedWidth();
} else {
contentSize.width = aReflowState.ApplyMinMaxWidth(contentSize.width);
if (NS_UNCONSTRAINEDSIZE != aReflowState.mComputedMaxWidth) {
contentSize.width = std::min(aReflowState.mComputedMaxWidth, contentSize.width);
}
if (NS_UNCONSTRAINEDSIZE != aReflowState.mComputedMinWidth) {
contentSize.width = std::max(aReflowState.mComputedMinWidth, contentSize.width);
}
}
aDesiredSize.height = contentSize.height +
borderPadding.TopBottom();
aDesiredSize.width = contentSize.width +
borderPadding.LeftRight();
aDesiredSize.height = borderPadding.top + contentSize.height +
borderPadding.bottom;
aDesiredSize.width = contentSize.width + borderPadding.left + borderPadding.right;
aDesiredSize.mOverflowAreas = overflowRects;
aDesiredSize.UnionOverflowAreasWithDesiredBounds();
@ -811,13 +798,7 @@ nsColumnSetFrame::FindBestBalanceHeight(const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
bool feasible = aRunWasFeasible;
nsMargin bp = aReflowState.mComputedBorderPadding;
ApplySkipSides(bp);
bp.bottom = aReflowState.mComputedBorderPadding.bottom;
nscoord availableContentHeight =
GetAvailableContentHeight(aReflowState);
nscoord availableContentHeight = GetAvailableContentHeight(aReflowState);
// Termination of the algorithm below is guaranteed because
// aConfig.knownFeasibleHeight - aConfig.knownInfeasibleHeight decreases in every
@ -873,6 +854,7 @@ nsColumnSetFrame::FindBestBalanceHeight(const nsHTMLReflowState& aReflowState,
if (aConfig.mKnownInfeasibleHeight >= aConfig.mKnownFeasibleHeight - 1) {
// aConfig.mKnownFeasibleHeight is where we want to be
break;
}
if (aConfig.mKnownInfeasibleHeight >= availableContentHeight) {
@ -975,7 +957,7 @@ nsColumnSetFrame::Reflow(nsPresContext* aPresContext,
// Our children depend on our height if we have a fixed height.
if (aReflowState.ComputedHeight() != NS_AUTOHEIGHT) {
NS_ASSERTION(aReflowState.ComputedHeight() != NS_INTRINSICSIZE,
"Unexpected computed height");
"Unexpected mComputedHeight");
AddStateBits(NS_FRAME_CONTAINS_RELATIVE_HEIGHT);
}
else {

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

@ -46,12 +46,6 @@ public:
virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
/**
* Retrieve the available height for content of this frame. The available content
* height is the available height for the frame, minus borders and padding.
*/
virtual nscoord GetAvailableContentHeight(const nsHTMLReflowState& aReflowState);
virtual nsIFrame* GetContentInsertionFrame() MOZ_OVERRIDE {
nsIFrame* frame = GetFirstPrincipalChild();
@ -129,14 +123,6 @@ protected:
// The last known height that was 'infeasible'. A column height is
// infeasible if not all child content fits within the specified height.
nscoord mKnownInfeasibleHeight;
// Height of the column set frame
nscoord mComputedHeight;
// The height "consumed" by previous-in-flows.
// The computed height should be equal to the height of the element (i.e.
// the computed height itself) plus the consumed height.
nscoord mConsumedHeight;
};
/**

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

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

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

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

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

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

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

@ -480,28 +480,15 @@ public:
}
return std::max(aWidth, mComputedMinWidth);
}
/**
* Apply the mComputed(Min/Max)Height constraints to the content
* size computed so far.
*
* @param aHeight The height that we've computed an to which we want to apply
* min/max constraints.
* @param aConsumed The amount of the computed height that was consumed by
* our prev-in-flows.
*/
nscoord ApplyMinMaxHeight(nscoord aHeight, nscoord aConsumed = 0) const {
aHeight += aConsumed;
nscoord ApplyMinMaxHeight(nscoord aHeight) const {
if (NS_UNCONSTRAINEDSIZE != mComputedMaxHeight) {
aHeight = std::min(aHeight, mComputedMaxHeight);
}
if (NS_UNCONSTRAINEDSIZE != mComputedMinHeight) {
aHeight = std::max(aHeight, mComputedMinHeight);
}
return aHeight - aConsumed;
return std::max(aHeight, mComputedMinHeight);
}
bool ShouldReflowAllKids() const {

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

@ -985,21 +985,8 @@ 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 nsHTMLReflowState* aReflowState = nullptr) const;
void ApplySkipSides(nsMargin& aMargin) const;
/**
* Like the frame's rect (see |GetRect|), which is the border rect,
@ -2419,16 +2406,8 @@ 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 nsHTMLReflowState* aReflowState = nullptr) const { return 0; }
virtual int GetSkipSides() const { return 0; }
/**
* @returns true if this frame is selected.

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

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

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

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

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

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

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

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

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

@ -12,7 +12,6 @@
#include "nsIContent.h"
#include "nsPresContext.h"
#include "nsStyleContext.h"
#include "nsContainerFrame.h"
NS_IMPL_FRAMEARENA_HELPERS(nsSplittableFrame)
@ -204,130 +203,6 @@ nsSplittableFrame::RemoveFromFlow(nsIFrame* aFrame)
aFrame->SetNextInFlow(nullptr);
}
nscoord
nsSplittableFrame::GetConsumedHeight() const
{
nscoord height = 0;
// Reduce the height by the computed height of prev-in-flows.
for (nsIFrame* prev = GetPrevInFlow(); prev; prev = prev->GetPrevInFlow()) {
height += prev->GetRect().height;
}
return height;
}
nscoord
nsSplittableFrame::GetEffectiveComputedHeight(const nsHTMLReflowState& aReflowState,
nscoord aConsumedHeight) const
{
nscoord height = aReflowState.ComputedHeight();
if (height == NS_INTRINSICSIZE) {
return NS_INTRINSICSIZE;
}
if (aConsumedHeight == NS_INTRINSICSIZE) {
aConsumedHeight = GetConsumedHeight();
}
height -= aConsumedHeight;
if (aConsumedHeight != 0 && aConsumedHeight != NS_INTRINSICSIZE) {
// We just subtracted our top-border padding, since it was included in the
// first frame's height. Add it back to get the content height.
height += aReflowState.mComputedBorderPadding.top;
}
// We may have stretched the frame beyond its computed height. Oh well.
height = std::max(0, height);
return height;
}
void
nsSplittableFrame::ComputeFinalHeight(const nsHTMLReflowState& aReflowState,
nsReflowStatus* aStatus,
nscoord aContentHeight,
const nsMargin& aBorderPadding,
nsHTMLReflowMetrics& aMetrics,
nscoord aConsumed)
{
// Figure out how much of the computed height should be
// applied to this frame.
nscoord computedHeightLeftOver = GetEffectiveComputedHeight(aReflowState,
aConsumed);
NS_ASSERTION(!( IS_TRUE_OVERFLOW_CONTAINER(this)
&& computedHeightLeftOver ),
"overflow container must not have computedHeightLeftOver");
aMetrics.height =
NSCoordSaturatingAdd(NSCoordSaturatingAdd(aBorderPadding.top,
computedHeightLeftOver),
aBorderPadding.bottom);
if (NS_FRAME_IS_NOT_COMPLETE(*aStatus)
&& aMetrics.height < aReflowState.availableHeight) {
// We ran out of height on this page but we're incomplete
// Set status to complete except for overflow
NS_FRAME_SET_OVERFLOW_INCOMPLETE(*aStatus);
}
if (NS_FRAME_IS_COMPLETE(*aStatus)) {
if (computedHeightLeftOver > 0 &&
NS_UNCONSTRAINEDSIZE != aReflowState.availableHeight &&
aMetrics.height > aReflowState.availableHeight) {
// We don't fit and we consumed some of the computed height,
// so we should consume all the available height and then
// break. If our bottom border/padding straddles the break
// point, then this will increase our height and push the
// border/padding to the next page/column.
aMetrics.height = std::max(aReflowState.availableHeight,
aContentHeight);
NS_FRAME_SET_INCOMPLETE(*aStatus);
if (!GetNextInFlow())
*aStatus |= NS_FRAME_REFLOW_NEXTINFLOW;
}
}
}
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)

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

@ -76,54 +76,6 @@ public:
protected:
nsSplittableFrame(nsStyleContext* aContext) : nsFrame(aContext) {}
/**
* Determine the height consumed by our previous-in-flows.
*
* @note (bz) This makes laying out a splittable frame with N in-flows
* O(N^2)! So, use this function with caution and minimize the number
* of calls to this method.
*/
nscoord GetConsumedHeight() const;
/**
* Retrieve the effective computed height of this frame, which is the computed
* height, minus the height consumed by any previous in-flows.
*/
nscoord GetEffectiveComputedHeight(const nsHTMLReflowState& aReflowState,
nscoord aConsumed = NS_INTRINSICSIZE) const;
/**
* Compute the final height of this frame.
*
* @param aReflowState Data structure passed from parent during reflow.
* @param aReflowStatus A pointed to the reflow status for when we're finished
* doing reflow. this will get set appropriately if the height causes
* us to exceed the current available (page) height.
* @param aContentHeight The height of content, precomputed outside of this
* function. The final height that is used in aMetrics will be set to
* either this or the available height, whichever is larger, in the
* case where our available height is constrained, and we overflow that
* available height.
* @param aBorderPadding The margins representing the border padding for block
* frames. Can be 0.
* @param aMetrics Out parameter for final height. Taken as an
* nsHTMLReflowMetrics object so that aMetrics can be passed in
* directly during reflow.
* @param aConsumed The height already consumed by our previous-in-flows.
*/
void ComputeFinalHeight(const nsHTMLReflowState& aReflowState,
nsReflowStatus* aStatus,
nscoord aContentHeight,
const nsMargin& aBorderPadding,
nsHTMLReflowMetrics& aMetrics,
nscoord aConsumed);
/**
* @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

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

@ -2,24 +2,23 @@
<div style="position: absolute;
top: 40px; left: 337px;
width: 6px;
background-color: green;
background-color: red;
height: 100px;">
</div>
<div style="position: absolute;
top: 40px; left: 637px;
width: 6px;
background-color: green;
background-color: red;
height: 100px;">
</div>
<div style="position: absolute;
top: 40px; left: 937px;
width: 6px;
background-color: green;
background-color: red;
height: 100px;">
</div>
<div style="position: absolute;
top: 40px; left: 40px;
height: 100px;
-moz-column-count: 4;
-moz-column-gap: 0px;">
<div style="height:400px;

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

@ -1,11 +1,10 @@
<!doctype html>
<body style="overflow:hidden">
<div style="padding: 20px;
position: absolute;
top: 20px; left: 20px;
-moz-column-count: 4;
-moz-column-gap: 0px;
-moz-column-rule: 6px green solid;">
-moz-column-rule: 6px red solid;">
<div style="height:400px;
width: 300px;
font-size: 16px;">

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

@ -1,44 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head class="reftest-print">
<title>CSS Test: Percentage Computed Height on Multicol Child (Definite Multicol Height)</title>
<link rel="author" title="Elika J. Etemad" href="http://fantasai.inkedblade.net/contact" />
<link rel="help" href="http://www.w3.org/TR/css3-multicol/#the-multi-column-model" />
<link rel="help" href="http://www.w3.org/TR/CSS21/visudet.html#the-height-property"/>
<meta name="flags" content="" />
<meta name="assert" content="Percentage heights with a multi-column element are relative to the computed height of the multicolumn box, and this works even when the multi-column element is paginated." />
<link rel="match" href="reference/multicol-height-001.xht" />
<style type="text/css"><![CDATA[
html, body { height: 100%; }
* { margin: 0; }
div {
border: double blue 12px;
-moz-column-count:2;
-moz-column-gap:0;
-moz-column-fill: balance;
height: 150%;
}
div > p {
border-right: solid orange 12px;
width: 0;
margin: 0 auto;
height: 200%;
}
blockquote {
border: solid thick yellow;
}
]]></style>
</head>
<body>
<p>Test passes if even when printed:</p>
<ul>
<li>Two vertical orange stripes stretch exactly
from the inner top edge to the inner bottom edge of the blue box below.</li>
<li>There is a yellow stripe immediately below the blue box.</li>
</ul>
<div>
<p></p>
</div>
<blockquote></blockquote>
</body>
</html>

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

@ -1,37 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head class="reftest-print">
<title>CSS Reftest Reference</title>
<link rel="author" title="Elika J. Etemad" href="http://fantasai.inkedblade.net/contact" />
<style type="text/css"><![CDATA[
html, body { height: 100%; }
* { margin: 0; }
div {
border: double blue 12px;
height: 150%;
padding: 0 12px;
}
div > p {
border-right: solid orange 12px;
border-left: solid orange 12px;
width: 50%;
margin: 0 auto;
height: 100%;
}
blockquote {
border: solid thick yellow;
} ]]></style>
</head>
<body>
<p>Test passes if even when printed:</p>
<ul>
<li>Two vertical orange stripes stretch exactly
from the inner top edge to the inner bottom edge of the blue box below.</li>
<li>There is a yellow stripe immediately below the blue box.</li>
</ul>
<div>
<p></p>
</div>
<blockquote></blockquote>
</body>
</html>

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

@ -1,2 +1 @@
== moz-multicol3-column-balancing-break-inside-avoid-1.html moz-multicol3-column-balancing-break-inside-avoid-1-ref.html
== multicol-height-001.xht reference/multicol-height-001.xht

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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