diff options
-rw-r--r-- | layout/generic/nsFlexContainerFrame.cpp | 39 | ||||
-rw-r--r-- | layout/generic/nsFlexContainerFrame.h | 15 | ||||
-rw-r--r-- | layout/generic/nsFrame.cpp | 11 |
3 files changed, 58 insertions, 7 deletions
diff --git a/layout/generic/nsFlexContainerFrame.cpp b/layout/generic/nsFlexContainerFrame.cpp index 02d15b5907..b4907a4862 100644 --- a/layout/generic/nsFlexContainerFrame.cpp +++ b/layout/generic/nsFlexContainerFrame.cpp @@ -1990,6 +1990,10 @@ FlexItem::FlexItem(ReflowInput& aFlexItemReflowInput, "placeholder frames should not be treated as flex items"); MOZ_ASSERT(!(mFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW), "out-of-flow frames should not be treated as flex items"); + MOZ_ASSERT(mIsInlineAxisMainAxis == + nsFlexContainerFrame::IsItemInlineAxisMainAxis(mFrame), + "public API should be consistent with internal state (about " + "whether flex item's inline axis is flex container's main axis)"); const ReflowInput* containerRS = aFlexItemReflowInput.mParentReflowInput; if (IsLegacyBox(containerRS->mFrame)) { @@ -4421,6 +4425,41 @@ nsFlexContainerFrame::CalculatePackingSpace(uint32_t aNumThingsToPack, *aPackingSpaceRemaining -= totalEdgePackingSpace; } +/* static */ +bool +nsFlexContainerFrame::IsItemInlineAxisMainAxis(nsIFrame* aFrame) +{ + MOZ_ASSERT(aFrame && aFrame->IsFlexItem(), "expecting arg to be a flex item"); + const WritingMode flexItemWM = aFrame->GetWritingMode(); + const nsIFrame* flexContainer = aFrame->GetParent(); + + if (IsLegacyBox(flexContainer)) { + // For legacy boxes, the main axis is determined by "box-orient", and we can + // just directly check if that's vertical, and compare that to whether the + // item's WM is also vertical: + bool boxOrientIsVertical = + (flexContainer->StyleXUL()->mBoxOrient == StyleBoxOrient::Vertical); + return flexItemWM.IsVertical() == boxOrientIsVertical; + } + + // For modern CSS flexbox, we get our return value by asking two questions + // and comparing their answers. + // Question 1: does aFrame have the same inline axis as its flex container? + bool itemInlineAxisIsParallelToParent = + !flexItemWM.IsOrthogonalTo(flexContainer->GetWritingMode()); + + // Question 2: is aFrame's flex container row-oriented? (This tells us + // whether the flex container's main axis is its inline axis.) + auto flexDirection = flexContainer->StylePosition()->mFlexDirection; + bool flexContainerIsRowOriented = + flexDirection == NS_STYLE_FLEX_DIRECTION_ROW || + flexDirection == NS_STYLE_FLEX_DIRECTION_ROW_REVERSE; + + // aFrame's inline axis is its flex container's main axis IFF the above + // questions have the same answer. + return flexContainerIsRowOriented == itemInlineAxisIsParallelToParent; +} + void nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, diff --git a/layout/generic/nsFlexContainerFrame.h b/layout/generic/nsFlexContainerFrame.h index 42ccdfeb85..e349709876 100644 --- a/layout/generic/nsFlexContainerFrame.h +++ b/layout/generic/nsFlexContainerFrame.h @@ -133,6 +133,21 @@ public: uint32_t* aNumPackingSpacesRemaining, nscoord* aPackingSpaceRemaining); + /** + * Given a frame for a flex item, this method returns true IFF that flex + * item's inline axis is the same as (i.e. not orthogonal to) its flex + * container's main axis. + * + * (This method is only intended to be used from external + * callers. Inside of flex reflow code, FlexItem::IsInlineAxisMainAxis() is + * equivalent & more optimal.) + * + * @param aFrame a flex item (must return true from IsFlexItem) + * @return true iff aFrame's inline axis is the same as (i.e. not orthogonal + * to) its flex container's main axis. Otherwise, false. + */ + static bool IsItemInlineAxisMainAxis(nsIFrame* aFrame); + protected: // Protected constructor & destructor explicit nsFlexContainerFrame(nsStyleContext* aContext) diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 43ad970890..9bc4941e0b 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -39,6 +39,7 @@ #include "mozilla/Logging.h" #include "mozilla/Sprintf.h" #include "nsFrameManager.h" +#include "nsFlexContainerFrame.h" #include "nsLayoutUtils.h" #include "LayoutLogging.h" #include "mozilla/RestyleManager.h" @@ -4752,12 +4753,11 @@ nsFrame::ComputeSize(nsRenderingContext* aRenderingContext, } bool isFlexItem = (parentFrameType == nsGkAtoms::flexContainerFrame && !(GetStateBits() & NS_FRAME_OUT_OF_FLOW)); + bool isInlineFlexItem = false; if (isFlexItem) { - uint32_t flexDirection = GetParent()->StylePosition()->mFlexDirection; isInlineFlexItem = - flexDirection == NS_STYLE_FLEX_DIRECTION_ROW || - flexDirection == NS_STYLE_FLEX_DIRECTION_ROW_REVERSE; + nsFlexContainerFrame::IsItemInlineAxisMainAxis(this); const nsStyleCoord* flexBasis = &(stylePos->mFlexBasis); SetCoordToFlexBasis(isInlineFlexItem, false, flexBasis, @@ -4973,11 +4973,8 @@ nsFrame::ComputeSizeWithIntrinsicDimensions(nsRenderingContext* aRenderingConte // from our style struct. (Otherwise, we'll be using an irrelevant value in // the aspect-ratio calculations below.) if (isFlexItem) { - uint32_t flexDirection = - GetParent()->StylePosition()->mFlexDirection; isInlineFlexItem = - flexDirection == NS_STYLE_FLEX_DIRECTION_ROW || - flexDirection == NS_STYLE_FLEX_DIRECTION_ROW_REVERSE; + nsFlexContainerFrame::IsItemInlineAxisMainAxis(this); // 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 |