Bug 783470 part 3: Use the strut metadata we've saved to actually build special "strut" FlexItems on our second pass through reflow. r=mats

This commit is contained in:
Daniel Holbert 2014-01-21 14:52:27 -08:00
Родитель 2781ee2855
Коммит 23a7b2bd07
2 изменённых файлов: 76 добавлений и 10 удалений

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

@ -279,6 +279,7 @@ private:
// to resolve a flexible width.
class FlexItem {
public:
// Normal constructor:
FlexItem(nsIFrame* aChildFrame,
float aFlexGrow, float aFlexShrink, nscoord aMainBaseSize,
nscoord aMainMinSize, nscoord aMainMaxSize,
@ -286,6 +287,9 @@ public:
nsMargin aMargin, nsMargin aBorderPadding,
const FlexboxAxisTracker& aAxisTracker);
// Simplified constructor, to be used only for generating "struts":
FlexItem(nsIFrame* aChildFrame, nscoord aCrossSize);
// Accessors
nsIFrame* Frame() const { return mFrame; }
nscoord GetFlexBaseSize() const { return mFlexBaseSize; }
@ -327,6 +331,10 @@ public:
// cross axis).
bool IsStretched() const { return mIsStretched; }
// Indicates whether this item is a "strut" left behind by an element with
// visibility:collapse.
bool IsStrut() const { return mIsStrut; }
uint8_t GetAlignSelf() const { return mAlignSelf; }
// Returns the flex weight that we should use in the "resolving flexible
@ -544,6 +552,8 @@ protected:
bool mHadMeasuringReflow; // Did this item get a preliminary reflow,
// to measure its desired height?
bool mIsStretched; // See IsStretched() documentation
bool mIsStrut; // Is this item a "strut" left behind by an element
// with visibility:collapse?
uint8_t mAlignSelf; // My "align-self" computed value (with "auto"
// swapped out for parent"s "align-items" value,
// in our constructor).
@ -1036,6 +1046,7 @@ FlexItem::FlexItem(nsIFrame* aChildFrame,
mHadMaxViolation(false),
mHadMeasuringReflow(false),
mIsStretched(false),
mIsStrut(false),
mAlignSelf(aChildFrame->StylePosition()->mAlignSelf)
{
MOZ_ASSERT(aChildFrame, "expecting a non-null child frame");
@ -1078,6 +1089,39 @@ FlexItem::FlexItem(nsIFrame* aChildFrame,
}
}
// Simplified constructor for creating a special "strut" FlexItem, for a child
// with visibility:collapse. The strut has 0 main-size, and it only exists to
// impose a minimum cross size on whichever FlexLine it ends up in.
FlexItem::FlexItem(nsIFrame* aChildFrame, nscoord aCrossSize)
: mFrame(aChildFrame),
mFlexGrow(0.0f),
mFlexShrink(0.0f),
// mBorderPadding uses default constructor,
// mMargin uses default constructor,
mFlexBaseSize(0),
mMainMinSize(0),
mMainMaxSize(0),
mCrossMinSize(0),
mCrossMaxSize(0),
mMainSize(0),
mMainPosn(0),
mCrossSize(aCrossSize),
mCrossPosn(0),
mAscent(0),
mShareOfFlexWeightSoFar(0.0f),
mIsFrozen(true),
mHadMinViolation(false),
mHadMaxViolation(false),
mHadMeasuringReflow(false),
mIsStretched(false),
mIsStrut(true), // (this is the constructor for making struts, after all)
mAlignSelf(NS_STYLE_ALIGN_ITEMS_FLEX_START)
{
MOZ_ASSERT(NS_STYLE_VISIBILITY_COLLAPSE ==
mFrame->StyleVisibility()->mVisible,
"Should only make struts for children with 'visibility:collapse'");
}
nscoord
FlexItem::GetBaselineOffsetFromOuterCrossStart(
AxisOrientationType aCrossAxis) const
@ -2216,6 +2260,7 @@ nsFlexContainerFrame::GenerateFlexLines(
const nsHTMLReflowState& aReflowState,
nscoord aContentBoxMainSize,
nscoord aAvailableHeightForContent,
const nsTArray<StrutInfo>& aStruts,
const FlexboxAxisTracker& aAxisTracker,
nsTArray<FlexLine>& aLines)
{
@ -2260,6 +2305,14 @@ nsFlexContainerFrame::GenerateFlexLines(
}
}
// Tracks the index of the next strut, in aStruts (and when this hits
// aStruts.Length(), that means there are no more struts):
uint32_t nextStrutIdx = 0;
// Overall index of the current flex item in the flex container. (This gets
// checked against entries in aStruts.)
uint32_t itemIdxInContainer = 0;
for (nsFrameList::Enumerator e(mFrames); !e.AtEnd(); e.Next()) {
nsIFrame* childFrame = e.get();
@ -2269,13 +2322,24 @@ nsFlexContainerFrame::GenerateFlexLines(
curLine = aLines.AppendElement();
}
FlexItem* item = curLine->mItems.AppendElement(
GenerateFlexItemForChild(aPresContext, childFrame,
aReflowState, aAxisTracker));
FlexItem* item;
if (nextStrutIdx < aStruts.Length() &&
aStruts[nextStrutIdx].mItemIdx == itemIdxInContainer) {
// Use the simplified "strut" FlexItem constructor:
item = curLine->mItems.AppendElement(
FlexItem(childFrame, aStruts[nextStrutIdx].mStrutCrossSize));
nextStrutIdx++;
} else {
item = curLine->mItems.AppendElement(
GenerateFlexItemForChild(aPresContext, childFrame,
aReflowState, aAxisTracker));
nsresult rv = ResolveFlexItemMaxContentSizing(aPresContext, *item,
aReflowState, aAxisTracker);
NS_ENSURE_SUCCESS(rv,rv);
}
nsresult rv = ResolveFlexItemMaxContentSizing(aPresContext, *item,
aReflowState, aAxisTracker);
NS_ENSURE_SUCCESS(rv,rv);
nscoord itemInnerHypotheticalMainSize = item->GetMainSize();
nscoord itemOuterHypotheticalMainSize = item->GetMainSize() +
item->GetMarginBorderPaddingSizeInAxis(aAxisTracker.GetMainAxis());
@ -2313,6 +2377,7 @@ nsFlexContainerFrame::GenerateFlexLines(
childFrame->StyleDisplay()->mBreakAfter) {
curLine = aLines.AppendElement();
}
itemIdxInContainer++;
}
return NS_OK;
@ -2732,7 +2797,7 @@ nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext,
nsresult rv = GenerateFlexLines(aPresContext, aReflowState,
aContentBoxMainSize,
aAvailableHeightForContent,
aAxisTracker, lines);
aStruts, aAxisTracker, lines);
NS_ENSURE_SUCCESS(rv, rv);
aContentBoxMainSize =
@ -2752,9 +2817,9 @@ nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext,
for (uint32_t i = 0; i < line.mItems.Length(); ++i) {
FlexItem& curItem = line.mItems[i];
// (If the item's already been stretched, then it already knows its
// cross size. Don't bother trying to recalculate it.)
if (!curItem.IsStretched()) {
// (If the item's already been stretched, or it's a strut, then it
// already knows its cross size. Don't bother trying to recalculate it.)
if (!curItem.IsStretched() && !curItem.IsStrut()) {
nsHTMLReflowState childReflowState(aPresContext, aReflowState,
curItem.Frame(),
nsSize(aReflowState.ComputedWidth(),

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

@ -124,6 +124,7 @@ protected:
const nsHTMLReflowState& aReflowState,
nscoord aContentBoxMainSize,
nscoord aAvailableHeightForContent,
const nsTArray<StrutInfo>& aStruts,
const FlexboxAxisTracker& aAxisTracker,
nsTArray<FlexLine>& aLines);