author | Daniel Holbert <dholbert@cs.stanford.edu> |
Wed, 05 Sep 2012 14:13:37 -0700 | |
changeset 104336 | e919c8cdb667ef78d9737e0bcae6bfc9ec980cf0 |
parent 104335 | 460d24605a7b04737697f43abf6b8174365c290b |
child 104337 | 4959a10d90aa3be07404aa14ebf2a926a2528bb2 |
push id | 23417 |
push user | ryanvm@gmail.com |
push date | Thu, 06 Sep 2012 02:27:31 +0000 |
treeherder | mozilla-central@501f4e46a88c [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | dbaron |
bugs | 666041 |
milestone | 18.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -2811,27 +2811,58 @@ nsLayoutUtils::ComputeHeightDependentVal /* static */ nsSize nsLayoutUtils::ComputeSizeWithIntrinsicDimensions( nsRenderingContext* aRenderingContext, nsIFrame* aFrame, const nsIFrame::IntrinsicSize& aIntrinsicSize, nsSize aIntrinsicRatio, nsSize aCBSize, nsSize aMargin, nsSize aBorder, nsSize aPadding) { - const nsStylePosition *stylePos = aFrame->GetStylePosition(); + const nsStylePosition* stylePos = aFrame->GetStylePosition(); + + // If we're a flex item, we'll compute our size a bit differently. + const nsStyleCoord* widthStyleCoord = &(stylePos->mWidth); + const nsStyleCoord* heightStyleCoord = &(stylePos->mHeight); + + bool isFlexItem = aFrame->IsFlexItem(); + bool isHorizontalFlexItem = false; + +#ifdef MOZ_FLEXBOX + if (isFlexItem) { + // Flex items use their "flex-basis" property in place of their main-size + // property (e.g. "width") for sizing purposes, *unless* they have + // "flex-basis:auto", in which case they use their main-size property after + // all. + uint32_t flexDirection = + aFrame->GetParent()->GetStylePosition()->mFlexDirection; + isHorizontalFlexItem = + flexDirection == NS_STYLE_FLEX_DIRECTION_ROW || + flexDirection == NS_STYLE_FLEX_DIRECTION_ROW_REVERSE; + + if (stylePos->mFlexBasis.GetUnit() != eStyleUnit_Auto) { + if (isHorizontalFlexItem) { + widthStyleCoord = &(stylePos->mFlexBasis); + } else { + heightStyleCoord = &(stylePos->mFlexBasis); + } + } + } +#endif // MOZ_FLEXBOX + + // Handle intrinsic sizes and their interaction with // {min-,max-,}{width,height} according to the rules in // http://www.w3.org/TR/CSS21/visudet.html#min-max-widths // Note: throughout the following section of the function, I avoid // a * (b / c) because of its reduced accuracy relative to a * b / c // or (a * b) / c (which are equivalent). - const bool isAutoWidth = stylePos->mWidth.GetUnit() == eStyleUnit_Auto; - const bool isAutoHeight = IsAutoHeight(stylePos->mHeight, aCBSize.height); + const bool isAutoWidth = widthStyleCoord->GetUnit() == eStyleUnit_Auto; + const bool isAutoHeight = IsAutoHeight(*heightStyleCoord, aCBSize.height); nsSize boxSizingAdjust(0,0); switch (stylePos->mBoxSizing) { case NS_STYLE_BOX_SIZING_BORDER: boxSizingAdjust += aBorder; // fall through case NS_STYLE_BOX_SIZING_PADDING: boxSizingAdjust += aPadding; @@ -2839,17 +2870,17 @@ nsLayoutUtils::ComputeSizeWithIntrinsicD nscoord boxSizingToMarginEdgeWidth = aMargin.width + aBorder.width + aPadding.width - boxSizingAdjust.width; nscoord width, minWidth, maxWidth, height, minHeight, maxHeight; if (!isAutoWidth) { width = nsLayoutUtils::ComputeWidthValue(aRenderingContext, aFrame, aCBSize.width, boxSizingAdjust.width, - boxSizingToMarginEdgeWidth, stylePos->mWidth); + boxSizingToMarginEdgeWidth, *widthStyleCoord); } if (stylePos->mMaxWidth.GetUnit() != eStyleUnit_None) { maxWidth = nsLayoutUtils::ComputeWidthValue(aRenderingContext, aFrame, aCBSize.width, boxSizingAdjust.width, boxSizingToMarginEdgeWidth, stylePos->mMaxWidth); } else { maxWidth = nscoord_MAX; @@ -2866,17 +2897,17 @@ nsLayoutUtils::ComputeSizeWithIntrinsicD // flex items' min-sizes are intentionally ignored until the flex // container explicitly considers them during space distribution. minWidth = 0; } if (!isAutoHeight) { height = nsLayoutUtils::ComputeHeightValue(aCBSize.height, boxSizingAdjust.height, - stylePos->mHeight); + *heightStyleCoord); } if (!IsAutoHeight(stylePos->mMaxHeight, aCBSize.height)) { maxHeight = nsLayoutUtils::ComputeHeightValue(aCBSize.height, boxSizingAdjust.height, stylePos->mMaxHeight); } else { maxHeight = nscoord_MAX;
--- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -3868,23 +3868,50 @@ nsFrame::ComputeSize(nsRenderingContext case NS_STYLE_BOX_SIZING_BORDER: boxSizingAdjust += aBorder; // fall through case NS_STYLE_BOX_SIZING_PADDING: boxSizingAdjust += aPadding; } nscoord boxSizingToMarginEdgeWidth = aMargin.width + aBorder.width + aPadding.width - boxSizingAdjust.width; + const nsStyleCoord* widthStyleCoord = &(stylePos->mWidth); + const nsStyleCoord* heightStyleCoord = &(stylePos->mHeight); + + bool isFlexItem = IsFlexItem(); + bool isHorizontalFlexItem = false; + +#ifdef MOZ_FLEXBOX + if (isFlexItem) { + // Flex items use their "flex-basis" property in place of their main-size + // property (e.g. "width") for sizing purposes, *unless* they have + // "flex-basis:auto", in which case they use their main-size property after + // all. + uint32_t flexDirection = mParent->GetStylePosition()->mFlexDirection; + isHorizontalFlexItem = + flexDirection == NS_STYLE_FLEX_DIRECTION_ROW || + flexDirection == NS_STYLE_FLEX_DIRECTION_ROW_REVERSE; + + if (stylePos->mFlexBasis.GetUnit() != eStyleUnit_Auto) { + if (isHorizontalFlexItem) { + widthStyleCoord = &(stylePos->mFlexBasis); + } else { + heightStyleCoord = &(stylePos->mFlexBasis); + } + } + } +#endif // MOZ_FLEXBOX + // Compute width - if (stylePos->mWidth.GetUnit() != eStyleUnit_Auto) { + if (widthStyleCoord->GetUnit() != eStyleUnit_Auto) { result.width = nsLayoutUtils::ComputeWidthValue(aRenderingContext, this, aCBSize.width, boxSizingAdjust.width, boxSizingToMarginEdgeWidth, - stylePos->mWidth); + *widthStyleCoord); } if (stylePos->mMaxWidth.GetUnit() != eStyleUnit_None) { nscoord maxWidth = nsLayoutUtils::ComputeWidthValue(aRenderingContext, this, aCBSize.width, boxSizingAdjust.width, boxSizingToMarginEdgeWidth, stylePos->mMaxWidth); result.width = NS_MIN(maxWidth, result.width); @@ -3902,21 +3929,21 @@ nsFrame::ComputeSize(nsRenderingContext // flex items. However, we don't need to worry about that here, because // flex items' min-sizes are intentionally ignored until the flex // container explicitly considers them during space distribution. minWidth = 0; } result.width = NS_MAX(minWidth, result.width); // Compute height - if (!nsLayoutUtils::IsAutoHeight(stylePos->mHeight, aCBSize.height)) { + if (!nsLayoutUtils::IsAutoHeight(*heightStyleCoord, aCBSize.height)) { result.height = nsLayoutUtils::ComputeHeightValue(aCBSize.height, boxSizingAdjust.height, - stylePos->mHeight); + *heightStyleCoord); } if (result.height != NS_UNCONSTRAINEDSIZE) { if (!nsLayoutUtils::IsAutoHeight(stylePos->mMaxHeight, aCBSize.height)) { nscoord maxHeight = nsLayoutUtils::ComputeHeightValue(aCBSize.height, boxSizingAdjust.height, stylePos->mMaxHeight);
--- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -2088,16 +2088,22 @@ public: * have kids. It could still have kids created via * nsIAnonymousContentCreator. Returning true indicates that "normal" * (non-anonymous, XBL-bound, CSS generated content, etc) children should not * be constructed. */ virtual bool IsLeaf() const; /** + * Is this a flex item? (Is the parent a flex container frame?) + */ + bool IsFlexItem() const + { return mParent && mParent->GetType() == nsGkAtoms::flexContainerFrame; } + + /** * This must only be called on frames that are display roots (see * nsLayoutUtils::GetDisplayRootFrame). This causes all invalidates * reaching this frame to be performed asynchronously off an event, * instead of being applied to the widget immediately. Also, * invalidation of areas in aExcludeRegion is ignored completely * for invalidates with INVALIDATE_EXCLUDE_CURRENT_PAINT specified. * These can't be nested; two invocations of * BeginDeferringInvalidatesForDisplayRoot for a frame must have a