зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1686603 Part 4 - Use StyleSizeOverrides to revise flex base size resolution. r=dholbert
Differential Revision: https://phabricator.services.mozilla.com/D101795
This commit is contained in:
Родитель
6d16aa20ce
Коммит
902b99ce81
|
@ -567,8 +567,10 @@ LogicalSize nsTextControlFrame::ComputeAutoSize(
|
|||
|
||||
// Note: nsContainerFrame::ComputeAutoSize only computes the inline-size (and
|
||||
// only for 'auto'), the block-size it returns is always NS_UNCONSTRAINEDSIZE.
|
||||
const auto& iSizeCoord = StylePosition()->ISize(aWM);
|
||||
if (iSizeCoord.IsAuto()) {
|
||||
const auto& styleISize = aSizeOverrides.mStyleISize
|
||||
? *aSizeOverrides.mStyleISize
|
||||
: StylePosition()->ISize(aWM);
|
||||
if (styleISize.IsAuto()) {
|
||||
if (aFlags.contains(ComputeSizeFlag::IClampMarginBoxMinSize)) {
|
||||
// CalcIntrinsicSize isn't aware of grid-item margin-box clamping, so we
|
||||
// fall back to nsContainerFrame's ComputeAutoSize to handle that.
|
||||
|
|
|
@ -986,16 +986,10 @@ LogicalSize nsContainerFrame::ComputeAutoSize(
|
|||
if (aFlags.contains(ComputeSizeFlag::ShrinkWrap) ||
|
||||
IsFrameOfType(eReplaced)) {
|
||||
// Only bother computing our 'auto' ISize if the result will be used.
|
||||
// It'll be used under two scenarios:
|
||||
// - If our ISize property is itself 'auto'.
|
||||
// - If we're using flex-basis in place of our ISize property (i.e. we're a
|
||||
// flex item with our inline axis being the main axis), AND we have
|
||||
// flex-basis:content.
|
||||
const nsStylePosition* pos = StylePosition();
|
||||
if (pos->ISize(aWM).IsAuto() ||
|
||||
aFlags.contains(ComputeSizeFlag::UseAutoISize) ||
|
||||
(pos->mFlexBasis.IsContent() && IsFlexItem() &&
|
||||
nsFlexContainerFrame::IsItemInlineAxisMainAxis(this))) {
|
||||
const auto& styleISize = aSizeOverrides.mStyleISize
|
||||
? *aSizeOverrides.mStyleISize
|
||||
: StylePosition()->ISize(aWM);
|
||||
if (styleISize.IsAuto() || aFlags.contains(ComputeSizeFlag::UseAutoISize)) {
|
||||
result.ISize(aWM) =
|
||||
ShrinkWidthToFit(aRenderingContext, availBased, aFlags);
|
||||
}
|
||||
|
@ -2394,8 +2388,12 @@ LogicalSize nsContainerFrame::ComputeSizeWithIntrinsicDimensions(
|
|||
const LogicalSize& aBorderPadding, const StyleSizeOverrides& aSizeOverrides,
|
||||
ComputeSizeFlags aFlags) {
|
||||
const nsStylePosition* stylePos = StylePosition();
|
||||
const auto* inlineStyleCoord = &stylePos->ISize(aWM);
|
||||
const auto* blockStyleCoord = &stylePos->BSize(aWM);
|
||||
const auto* inlineStyleCoord = aSizeOverrides.mStyleISize
|
||||
? aSizeOverrides.mStyleISize.ptr()
|
||||
: &stylePos->ISize(aWM);
|
||||
const auto* blockStyleCoord = aSizeOverrides.mStyleBSize
|
||||
? aSizeOverrides.mStyleBSize.ptr()
|
||||
: &stylePos->BSize(aWM);
|
||||
auto* parentFrame = GetParent();
|
||||
const bool isGridItem = IsGridItem();
|
||||
const bool isFlexItem =
|
||||
|
@ -2432,45 +2430,6 @@ LogicalSize nsContainerFrame::ComputeSizeWithIntrinsicDimensions(
|
|||
} else {
|
||||
blockStyleCoord = imposedMainSizeStyleCoord.ptr();
|
||||
}
|
||||
|
||||
} else {
|
||||
// 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.
|
||||
// NOTE: The logic here should match the similar chunk for updating
|
||||
// mainAxisCoord in nsIFrame::ComputeSize() (aside from using a different
|
||||
// dummy value in the IsUsedFlexBasisContent() case).
|
||||
const auto* flexBasis = &stylePos->mFlexBasis;
|
||||
auto& mainAxisCoord =
|
||||
(flexMainAxis == eLogicalAxisInline ? inlineStyleCoord
|
||||
: blockStyleCoord);
|
||||
|
||||
if (nsFlexContainerFrame::IsUsedFlexBasisContent(*flexBasis,
|
||||
*mainAxisCoord)) {
|
||||
// If we get here, we're resolving the flex base size for a flex item,
|
||||
// and we fall into the flexbox spec section 9.2 step 3, substep C (if
|
||||
// we have a definite cross size) or E (if not). And specifically:
|
||||
//
|
||||
// * If we have a definite cross size, we're supposed to resolve our
|
||||
// main-size based on that and our intrinsic ratio.
|
||||
// * Otherwise, we're supposed to produce our max-content size.
|
||||
//
|
||||
// Conveniently, we can handle both of those scenarios (regardless of
|
||||
// which substep we fall into) by using the 'auto' keyword for our
|
||||
// main-axis coordinate here. (This makes sense, because the spec is
|
||||
// effectively trying to produce the 'auto' sizing behavior).
|
||||
static const StyleSize autoSize(StyleSize::Auto());
|
||||
mainAxisCoord = &autoSize;
|
||||
} else if (flexBasis->IsSize() && !flexBasis->IsAuto()) {
|
||||
// For all other non-'auto' flex-basis values, we just swap in the
|
||||
// flex-basis itself for the main-size property.
|
||||
mainAxisCoord = &flexBasis->AsSize();
|
||||
} else {
|
||||
MOZ_ASSERT(flexBasis->IsAuto());
|
||||
// else: flex-basis is 'auto', which is deferring to some explicit
|
||||
// value in mainAxisCoord. So we proceed w/o touching mainAxisCoord.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1287,12 +1287,61 @@ FlexItem* nsFlexContainerFrame::GenerateFlexItemForChild(
|
|||
FlexLine& aLine, nsIFrame* aChildFrame,
|
||||
const ReflowInput& aParentReflowInput,
|
||||
const FlexboxAxisTracker& aAxisTracker, bool aHasLineClampEllipsis) {
|
||||
const auto flexWM = aAxisTracker.GetWritingMode();
|
||||
const auto childWM = aChildFrame->GetWritingMode();
|
||||
const auto* stylePos = aChildFrame->StylePosition();
|
||||
|
||||
// Construct a StyleSizeOverrides for this flex item so that its ReflowInput
|
||||
// below will use and resolve its flex base size rather than its corresponding
|
||||
// preferred main size property (only for modern CSS flexbox).
|
||||
StyleSizeOverrides sizeOverrides;
|
||||
if (!IsLegacyBox(this)) {
|
||||
Maybe<StyleSize> styleFlexBaseSize;
|
||||
|
||||
// When resolving flex base size, flex items use their 'flex-basis' property
|
||||
// in place of their preferred main size (e.g. 'width') for sizing purposes,
|
||||
// *unless* they have 'flex-basis:auto' in which case they use their
|
||||
// preferred main size after all.
|
||||
const auto& flexBasis = stylePos->mFlexBasis;
|
||||
const auto& styleMainSize = stylePos->Size(aAxisTracker.MainAxis(), flexWM);
|
||||
if (IsUsedFlexBasisContent(flexBasis, styleMainSize)) {
|
||||
// If we get here, we're resolving the flex base size for a flex item, and
|
||||
// we fall into the flexbox spec section 9.2 step 3, substep C (if we have
|
||||
// a definite cross size) or E (if not).
|
||||
if (aChildFrame->GetAspectRatio()) {
|
||||
// FIXME: This is a workaround. Once bug 1670151 is fixed, aspect-ratio
|
||||
// will be considered when resolving flex item's flex base size with the
|
||||
// value 'max-content'.
|
||||
styleFlexBaseSize.emplace(StyleSize::Auto());
|
||||
} else {
|
||||
styleFlexBaseSize.emplace(
|
||||
StyleSize::ExtremumLength(StyleExtremumLength::MaxContent));
|
||||
}
|
||||
} else if (flexBasis.IsSize() && !flexBasis.IsAuto()) {
|
||||
// For all other non-'auto' flex-basis values, we just swap in the
|
||||
// flex-basis itself for the preferred main-size property.
|
||||
styleFlexBaseSize.emplace(flexBasis.AsSize());
|
||||
} else {
|
||||
// else: flex-basis is 'auto', which is deferring to some explicit value
|
||||
// in the preferred main size, so we proceed without emplacing
|
||||
// styleFlexBaseSize.
|
||||
MOZ_ASSERT(flexBasis.IsAuto());
|
||||
}
|
||||
|
||||
// Provide the size override for the preferred main size property.
|
||||
if (aAxisTracker.IsInlineAxisMainAxis(childWM)) {
|
||||
sizeOverrides.mStyleISize = std::move(styleFlexBaseSize);
|
||||
} else {
|
||||
sizeOverrides.mStyleBSize = std::move(styleFlexBaseSize);
|
||||
}
|
||||
}
|
||||
|
||||
// Create temporary reflow input just for sizing -- to get hypothetical
|
||||
// main-size and the computed values of min / max main-size property.
|
||||
// (This reflow input will _not_ be used for reflow.)
|
||||
ReflowInput childRI(
|
||||
PresContext(), aParentReflowInput, aChildFrame,
|
||||
aParentReflowInput.ComputedSize(aChildFrame->GetWritingMode()));
|
||||
ReflowInput childRI(PresContext(), aParentReflowInput, aChildFrame,
|
||||
aParentReflowInput.ComputedSize(childWM), Nothing(), {},
|
||||
sizeOverrides);
|
||||
childRI.mFlags.mInsideLineClamp = GetLineClampValue() != 0;
|
||||
|
||||
// FLEX GROW & SHRINK WEIGHTS
|
||||
|
@ -1306,14 +1355,10 @@ FlexItem* nsFlexContainerFrame::GenerateFlexItemForChild(
|
|||
flexGrow = flexShrink = aChildFrame->StyleXUL()->mBoxFlex;
|
||||
}
|
||||
} else {
|
||||
const nsStylePosition* stylePos = aChildFrame->StylePosition();
|
||||
flexGrow = stylePos->mFlexGrow;
|
||||
flexShrink = stylePos->mFlexShrink;
|
||||
}
|
||||
|
||||
const auto childWM = childRI.GetWritingMode();
|
||||
const auto flexWM = aAxisTracker.GetWritingMode();
|
||||
|
||||
// MAIN SIZES (flex base size, min/max size)
|
||||
// -----------------------------------------
|
||||
nscoord flexBaseSize = GET_MAIN_COMPONENT_LOGICAL(
|
||||
|
|
|
@ -6095,8 +6095,12 @@ nsIFrame::SizeComputationResult nsIFrame::ComputeSize(
|
|||
aBorderPadding.ISize(aWM) -
|
||||
boxSizingAdjust.ISize(aWM);
|
||||
|
||||
const auto* inlineStyleCoord = &stylePos->ISize(aWM);
|
||||
const auto* blockStyleCoord = &stylePos->BSize(aWM);
|
||||
const auto* inlineStyleCoord = aSizeOverrides.mStyleISize
|
||||
? aSizeOverrides.mStyleISize.ptr()
|
||||
: &stylePos->ISize(aWM);
|
||||
const auto* blockStyleCoord = aSizeOverrides.mStyleBSize
|
||||
? aSizeOverrides.mStyleBSize.ptr()
|
||||
: &stylePos->BSize(aWM);
|
||||
|
||||
auto parentFrame = GetParent();
|
||||
auto alignCB = parentFrame;
|
||||
|
@ -6129,22 +6133,10 @@ nsIFrame::SizeComputationResult nsIFrame::ComputeSize(
|
|||
Maybe<StyleSize> imposedMainSizeStyleCoord;
|
||||
|
||||
if (isFlexItem) {
|
||||
// Flex items use their "flex-basis" property in place of their main-size
|
||||
// property for sizing purposes, *unless* they have "flex-basis:auto", in
|
||||
// which case they use their main-size property after all.
|
||||
flexMainAxis = nsFlexContainerFrame::IsItemInlineAxisMainAxis(this)
|
||||
? eLogicalAxisInline
|
||||
: eLogicalAxisBlock;
|
||||
|
||||
// NOTE: The logic here should match the similar chunk for updating
|
||||
// mainAxisCoord in nsContainerFrame::ComputeSizeWithIntrinsicDimensions()
|
||||
// (aside from using a different dummy value in the IsUsedFlexBasisContent()
|
||||
// case).
|
||||
const auto* flexBasis = &stylePos->mFlexBasis;
|
||||
auto& mainAxisCoord =
|
||||
(flexMainAxis == eLogicalAxisInline ? inlineStyleCoord
|
||||
: blockStyleCoord);
|
||||
|
||||
// If FlexItemMainSizeOverride frame-property is set, then that means the
|
||||
// flex container is imposing a main-size on this flex item for it to use
|
||||
// as its size in the container's main axis.
|
||||
|
@ -6159,30 +6151,6 @@ nsIFrame::SizeComputationResult nsIFrame::ComputeSize(
|
|||
} else {
|
||||
blockStyleCoord = imposedMainSizeStyleCoord.ptr();
|
||||
}
|
||||
} else {
|
||||
// NOTE: If we're a table-wrapper frame, we skip this clause and just
|
||||
// stick with 'main-size:auto' behavior (which -- unlike 'content' i.e.
|
||||
// 'max-content' -- will give us the ability to honor percent sizes on our
|
||||
// table-box child when resolving the flex base size). The flexbox spec
|
||||
// doesn't call for this special case, but webcompat &
|
||||
// regression-avoidance seems to require it, for the time being... Tables
|
||||
// sure are special.
|
||||
if (nsFlexContainerFrame::IsUsedFlexBasisContent(*flexBasis,
|
||||
*mainAxisCoord) &&
|
||||
MOZ_LIKELY(!IsTableWrapperFrame())) {
|
||||
static const StyleSize maxContStyleCoord(
|
||||
StyleSize::ExtremumLength(StyleExtremumLength::MaxContent));
|
||||
mainAxisCoord = &maxContStyleCoord;
|
||||
// (Note: if our main axis is the block axis, then this 'max-content'
|
||||
// value will be treated like 'auto', via the IsAutoBSize() call below.)
|
||||
} else if (flexBasis->IsSize() && !flexBasis->IsAuto()) {
|
||||
// For all other non-'auto' flex-basis values, we just swap in the
|
||||
// flex-basis itself for the main-size property.
|
||||
mainAxisCoord = &flexBasis->AsSize();
|
||||
} else {
|
||||
// else: flex-basis is 'auto', or 'content' in a table wrapper frame
|
||||
// which we ignore. So we proceed w/o touching mainAxisCoord.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6438,8 +6406,10 @@ LogicalSize nsIFrame::ComputeAutoSize(
|
|||
LogicalSize result(aWM, 0xdeadbeef, NS_UNCONSTRAINEDSIZE);
|
||||
|
||||
// don't bother setting it if the result won't be used
|
||||
if (StylePosition()->ISize(aWM).IsAuto() ||
|
||||
aFlags.contains(ComputeSizeFlag::UseAutoISize)) {
|
||||
const auto& styleISize = aSizeOverrides.mStyleISize
|
||||
? *aSizeOverrides.mStyleISize
|
||||
: StylePosition()->ISize(aWM);
|
||||
if (styleISize.IsAuto() || aFlags.contains(ComputeSizeFlag::UseAutoISize)) {
|
||||
nscoord availBased =
|
||||
aAvailableISize - aMargin.ISize(aWM) - aBorderPadding.ISize(aWM);
|
||||
result.ISize(aWM) = ShrinkWidthToFit(aRenderingContext, availBased, aFlags);
|
||||
|
|
Загрузка…
Ссылка в новой задаче