LCOV - code coverage report
Current view: top level - layout/generic - nsFlexContainerFrame.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 12 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 4 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=2 et sw=2 tw=80: */
       3             : 
       4             : /* This Source Code is subject to the terms of the Mozilla Public License
       5             :  * version 2.0 (the "License"). You can obtain a copy of the License at
       6             :  * http://mozilla.org/MPL/2.0/. */
       7             : 
       8             : /* rendering object for CSS "display: flex" and "display: -webkit-box" */
       9             : 
      10             : #ifndef nsFlexContainerFrame_h___
      11             : #define nsFlexContainerFrame_h___
      12             : 
      13             : #include "nsContainerFrame.h"
      14             : #include "mozilla/UniquePtr.h"
      15             : 
      16             : namespace mozilla {
      17             : template <class T> class LinkedList;
      18             : class LogicalPoint;
      19             : } // namespace mozilla
      20             : 
      21             : nsContainerFrame* NS_NewFlexContainerFrame(nsIPresShell* aPresShell,
      22             :                                            nsStyleContext* aContext);
      23             : 
      24             : 
      25             : /**
      26             :  * This is the rendering object used for laying out elements with
      27             :  * "display: flex" or "display: inline-flex".
      28             :  *
      29             :  * We also use this class for elements with "display: -webkit-box" or
      30             :  * "display: -webkit-inline-box" (but not "-moz-box" / "-moz-inline-box" --
      31             :  * those are rendered with old-school XUL frame classes).
      32             :  *
      33             :  * Note: we represent the -webkit-box family of properties (-webkit-box-orient,
      34             :  * -webkit-box-flex, etc.) as aliases for their -moz equivalents.  And for
      35             :  * -webkit-{inline-}box containers, nsFlexContainerFrame will honor those
      36             :  * "legacy" properties for alignment/flexibility/etc. *instead of* honoring the
      37             :  * modern flexbox & alignment properties.  For brevity, many comments in
      38             :  * nsFlexContainerFrame.cpp simply refer to these properties using their
      39             :  * "-webkit" versions, since we're mostly expecting to encounter them in that
      40             :  * form. (Technically, the "-moz" versions of these properties *can* influence
      41             :  * layout here as well (since that's what the -webkit versions are aliased to)
      42             :  * -- but only inside of a "display:-webkit-{inline-}box" container.)
      43             :  */
      44             : class nsFlexContainerFrame final : public nsContainerFrame
      45             : {
      46             : public:
      47           0 :   NS_DECL_FRAMEARENA_HELPERS(nsFlexContainerFrame)
      48             :   NS_DECL_QUERYFRAME
      49             : 
      50             :   // Factory method:
      51             :   friend nsContainerFrame* NS_NewFlexContainerFrame(nsIPresShell* aPresShell,
      52             :                                                     nsStyleContext* aContext);
      53             : 
      54             :   // Forward-decls of helper classes
      55             :   class FlexItem;
      56             :   class FlexLine;
      57             :   class FlexboxAxisTracker;
      58             :   struct StrutInfo;
      59             :   class CachedMeasuringReflowResult;
      60             : 
      61             :   // nsIFrame overrides
      62             :   void Init(nsIContent*       aContent,
      63             :             nsContainerFrame* aParent,
      64             :             nsIFrame*         aPrevInFlow) override;
      65             : 
      66             :   void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
      67             :                         const nsRect&           aDirtyRect,
      68             :                         const nsDisplayListSet& aLists) override;
      69             : 
      70             :   void MarkIntrinsicISizesDirty() override;
      71             : 
      72             :   void Reflow(nsPresContext* aPresContext,
      73             :               ReflowOutput& aDesiredSize,
      74             :               const ReflowInput& aReflowInput,
      75             :               nsReflowStatus& aStatus) override;
      76             : 
      77             :   nscoord GetMinISize(gfxContext* aRenderingContext) override;
      78             :   nscoord GetPrefISize(gfxContext* aRenderingContext) override;
      79             : 
      80             : #ifdef DEBUG_FRAME_DUMP
      81             :   nsresult GetFrameName(nsAString& aResult) const override;
      82             : #endif
      83             : 
      84             :   nscoord GetLogicalBaseline(mozilla::WritingMode aWM) const override;
      85             : 
      86           0 :   bool GetVerticalAlignBaseline(mozilla::WritingMode aWM,
      87             :                                 nscoord* aBaseline) const override
      88             :   {
      89           0 :     return GetNaturalBaselineBOffset(aWM, BaselineSharingGroup::eFirst, aBaseline);
      90             :   }
      91             : 
      92           0 :   bool GetNaturalBaselineBOffset(mozilla::WritingMode aWM,
      93             :                                  BaselineSharingGroup aBaselineGroup,
      94             :                                  nscoord*             aBaseline) const override
      95             :   {
      96           0 :     if (HasAnyStateBits(NS_STATE_FLEX_SYNTHESIZE_BASELINE)) {
      97           0 :       return false;
      98             :     }
      99           0 :     *aBaseline = aBaselineGroup == BaselineSharingGroup::eFirst ?
     100             :                    mBaselineFromLastReflow : mLastBaselineFromLastReflow;
     101           0 :     return true;
     102             :   }
     103             : 
     104             :   // nsContainerFrame overrides
     105             :   uint16_t CSSAlignmentForAbsPosChild(
     106             :             const ReflowInput& aChildRI,
     107             :             mozilla::LogicalAxis aLogicalAxis) const override;
     108             : 
     109             :   // Flexbox-specific public methods
     110             :   bool IsHorizontal();
     111             : 
     112             :   /**
     113             :     * Helper function to calculate packing space and initial offset of alignment
     114             :     * subjects in MainAxisPositionTracker() and CrossAxisPositionTracker() for
     115             :     * space-between, space-around, and space-evenly.
     116             :     *
     117             :     * @param aNumThingsToPack             Number of alignment subjects.
     118             :     * @param aAlignVal                    Value for align-self or justify-self.
     119             :     * @param aFirstSubjectOffset          Outparam for first subject offset.
     120             :     * @param aNumPackingSpacesRemaining   Outparam for number of equal-sized
     121             :     *                                     packing spaces to apply between each
     122             :     *                                     alignment subject.
     123             :     * @param aPackingSpaceRemaining       Outparam for total amount of packing
     124             :     *                                     space to be divided up.
     125             :     */
     126             :   static void CalculatePackingSpace(uint32_t aNumThingsToPack,
     127             :                                     uint8_t aAlignVal,
     128             :                                     nscoord* aFirstSubjectOffset,
     129             :                                     uint32_t* aNumPackingSpacesRemaining,
     130             :                                     nscoord* aPackingSpaceRemaining);
     131             : 
     132             : protected:
     133             :   // Protected constructor & destructor
     134           0 :   explicit nsFlexContainerFrame(nsStyleContext* aContext)
     135           0 :     : nsContainerFrame(aContext, kClassID)
     136             :     , mBaselineFromLastReflow(NS_INTRINSIC_WIDTH_UNKNOWN)
     137           0 :     , mLastBaselineFromLastReflow(NS_INTRINSIC_WIDTH_UNKNOWN)
     138           0 :   {}
     139             : 
     140             :   virtual ~nsFlexContainerFrame();
     141             : 
     142             :   /*
     143             :    * This method does the bulk of the flex layout, implementing the algorithm
     144             :    * described at:
     145             :    *   http://dev.w3.org/csswg/css-flexbox/#layout-algorithm
     146             :    * (with a few initialization pieces happening in the caller, Reflow().
     147             :    *
     148             :    * Since this is a helper for Reflow(), this takes all the same parameters
     149             :    * as Reflow(), plus a few more parameters that Reflow() sets up for us.
     150             :    *
     151             :    * (The logic behind the division of work between Reflow and DoFlexLayout is
     152             :    * as follows: DoFlexLayout() begins at the step that we have to jump back
     153             :    * to, if we find any visibility:collapse children, and Reflow() does
     154             :    * everything before that point.)
     155             :    */
     156             :   void DoFlexLayout(nsPresContext*           aPresContext,
     157             :                     ReflowOutput&     aDesiredSize,
     158             :                     const ReflowInput& aReflowInput,
     159             :                     nsReflowStatus&          aStatus,
     160             :                     nscoord aContentBoxMainSize,
     161             :                     nscoord aAvailableBSizeForContent,
     162             :                     nsTArray<StrutInfo>& aStruts,
     163             :                     const FlexboxAxisTracker& aAxisTracker);
     164             : 
     165             :   /**
     166             :    * Checks whether our child-frame list "mFrames" is sorted, using the given
     167             :    * IsLessThanOrEqual function, and sorts it if it's not already sorted.
     168             :    *
     169             :    * XXXdholbert Once we support pagination, we need to make this function
     170             :    * check our continuations as well (or wrap it in a function that does).
     171             :    *
     172             :    * @return true if we had to sort mFrames, false if it was already sorted.
     173             :    */
     174             :   template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
     175             :   bool SortChildrenIfNeeded();
     176             : 
     177             :   // Protected flex-container-specific methods / member-vars
     178             : #ifdef DEBUG
     179             :   void SanityCheckAnonymousFlexItems() const;
     180             : #endif // DEBUG
     181             : 
     182             :   /*
     183             :    * Returns a new FlexItem for the given child frame, allocated on the heap.
     184             :    * Guaranteed to return non-null. Caller is responsible for managing the
     185             :    * FlexItem's lifetime.
     186             :    *
     187             :    * Before returning, this method also processes the FlexItem to resolve its
     188             :    * flex basis (including e.g. auto-height) as well as to resolve
     189             :    * "min-height:auto", via ResolveAutoFlexBasisAndMinSize(). (Basically, the
     190             :    * returned FlexItem will be ready to participate in the "Resolve the
     191             :    * Flexible Lengths" step of the Flex Layout Algorithm.)
     192             :    */
     193             :   mozilla::UniquePtr<FlexItem> GenerateFlexItemForChild(nsPresContext* aPresContext,
     194             :                                      nsIFrame* aChildFrame,
     195             :                                      const ReflowInput& aParentReflowInput,
     196             :                                      const FlexboxAxisTracker& aAxisTracker);
     197             : 
     198             :   /**
     199             :    * This method gets a cached measuring reflow for a flex item, or does it and
     200             :    * caches it.
     201             :    *
     202             :    * This avoids exponential reflows, see the comment on
     203             :    * CachedMeasuringReflowResult.
     204             :    */
     205             :   const CachedMeasuringReflowResult& MeasureAscentAndHeightForFlexItem(
     206             :     FlexItem& aItem,
     207             :     nsPresContext* aPresContext,
     208             :     ReflowInput& aChildReflowInput);
     209             : 
     210             :   /**
     211             :    * This method performs a "measuring" reflow to get the content height of
     212             :    * aFlexItem.Frame() (treating it as if it had auto-height), & returns the
     213             :    * resulting height.
     214             :    * (Helper for ResolveAutoFlexBasisAndMinSize().)
     215             :    */
     216             :   nscoord MeasureFlexItemContentHeight(nsPresContext* aPresContext,
     217             :                                        FlexItem& aFlexItem,
     218             :                                        bool aForceVerticalResizeForMeasuringReflow,
     219             :                                        const ReflowInput& aParentReflowInput);
     220             : 
     221             :   /**
     222             :    * This method resolves an "auto" flex-basis and/or min-main-size value
     223             :    * on aFlexItem, if needed.
     224             :    * (Helper for GenerateFlexItemForChild().)
     225             :    */
     226             :   void ResolveAutoFlexBasisAndMinSize(nsPresContext* aPresContext,
     227             :                                       FlexItem& aFlexItem,
     228             :                                       const ReflowInput& aItemReflowInput,
     229             :                                       const FlexboxAxisTracker& aAxisTracker);
     230             : 
     231             :   /**
     232             :    * This method:
     233             :    *  - Creates FlexItems for all of our child frames (except placeholders).
     234             :    *  - Groups those FlexItems into FlexLines.
     235             :    *  - Returns those FlexLines in the outparam |aLines|.
     236             :    *
     237             :    * For any child frames which are placeholders, this method will instead just
     238             :    * append that child to the outparam |aPlaceholders| for separate handling.
     239             :    * (Absolutely positioned children of a flex container are *not* flex items.)
     240             :    */
     241             :   void GenerateFlexLines(nsPresContext* aPresContext,
     242             :                          const ReflowInput& aReflowInput,
     243             :                          nscoord aContentBoxMainSize,
     244             :                          nscoord aAvailableBSizeForContent,
     245             :                          const nsTArray<StrutInfo>& aStruts,
     246             :                          const FlexboxAxisTracker& aAxisTracker,
     247             :                          nsTArray<nsIFrame*>& aPlaceholders,
     248             :                          mozilla::LinkedList<FlexLine>& aLines);
     249             : 
     250             :   nscoord GetMainSizeFromReflowInput(const ReflowInput& aReflowInput,
     251             :                                      const FlexboxAxisTracker& aAxisTracker);
     252             : 
     253             :   nscoord ComputeCrossSize(const ReflowInput& aReflowInput,
     254             :                            const FlexboxAxisTracker& aAxisTracker,
     255             :                            nscoord aSumLineCrossSizes,
     256             :                            nscoord aAvailableBSizeForContent,
     257             :                            bool* aIsDefinite,
     258             :                            nsReflowStatus& aStatus);
     259             : 
     260             :   void SizeItemInCrossAxis(nsPresContext* aPresContext,
     261             :                            const FlexboxAxisTracker& aAxisTracker,
     262             :                            ReflowInput& aChildReflowInput,
     263             :                            FlexItem& aItem);
     264             : 
     265             :   /**
     266             :    * Moves the given flex item's frame to the given LogicalPosition (modulo any
     267             :    * relative positioning).
     268             :    *
     269             :    * This can be used in cases where we've already done a "measuring reflow"
     270             :    * for the flex item at the correct size, and hence can skip its final reflow
     271             :    * (but still need to move it to the right final position).
     272             :    *
     273             :    * @param aReflowInput    The flex container's reflow state.
     274             :    * @param aItem           The flex item whose frame should be moved.
     275             :    * @param aFramePos       The position where the flex item's frame should
     276             :    *                        be placed. (pre-relative positioning)
     277             :    * @param aContainerSize  The flex container's size (required by some methods
     278             :    *                        that we call, to interpret aFramePos correctly).
     279             :    */
     280             :   void MoveFlexItemToFinalPosition(const ReflowInput& aReflowInput,
     281             :                                    const FlexItem& aItem,
     282             :                                    mozilla::LogicalPoint& aFramePos,
     283             :                                    const nsSize& aContainerSize);
     284             :   /**
     285             :    * Helper-function to reflow a child frame, at its final position determined
     286             :    * by flex layout.
     287             :    *
     288             :    * @param aPresContext    The presentation context being used in reflow.
     289             :    * @param aAxisTracker    A FlexboxAxisTracker with the flex container's axes.
     290             :    * @param aReflowInput    The flex container's reflow state.
     291             :    * @param aItem           The flex item to be reflowed.
     292             :    * @param aFramePos       The position where the flex item's frame should
     293             :    *                        be placed. (pre-relative positioning)
     294             :    * @param aContainerSize  The flex container's size (required by some methods
     295             :    *                        that we call, to interpret aFramePos correctly).
     296             :    */
     297             :   void ReflowFlexItem(nsPresContext* aPresContext,
     298             :                       const FlexboxAxisTracker& aAxisTracker,
     299             :                       const ReflowInput& aReflowInput,
     300             :                       const FlexItem& aItem,
     301             :                       mozilla::LogicalPoint& aFramePos,
     302             :                       const nsSize& aContainerSize);
     303             : 
     304             :   /**
     305             :    * Helper-function to perform a "dummy reflow" on all our nsPlaceholderFrame
     306             :    * children, at the container's content-box origin.
     307             :    *
     308             :    * This doesn't actually represent the static position of the placeholders'
     309             :    * out-of-flow (OOF) frames -- we can't compute that until we've reflowed the
     310             :    * OOF, because (depending on the CSS Align properties) the static position
     311             :    * may be influenced by the OOF's size.  So for now, we just co-opt the
     312             :    * placeholder to store the flex container's logical content-box origin, and
     313             :    * we defer to nsAbsoluteContainingBlock to determine the OOF's actual static
     314             :    * position (using this origin, the OOF's size, and the CSS Align
     315             :    * properties).
     316             :    *
     317             :    * @param aPresContext       The presentation context being used in reflow.
     318             :    * @param aReflowInput       The flex container's reflow input.
     319             :    * @param aPlaceholders      An array of all the flex container's
     320             :    *                           nsPlaceholderFrame children.
     321             :    * @param aContentBoxOrigin  The flex container's logical content-box
     322             :    *                           origin (in its own coordinate space).
     323             :    * @param aContainerSize     The flex container's size (required by some
     324             :    *                           reflow methods to interpret positions correctly).
     325             :    */
     326             :   void ReflowPlaceholders(nsPresContext* aPresContext,
     327             :                           const ReflowInput& aReflowInput,
     328             :                           nsTArray<nsIFrame*>& aPlaceholders,
     329             :                           const mozilla::LogicalPoint& aContentBoxOrigin,
     330             :                           const nsSize& aContainerSize);
     331             : 
     332             :   nscoord mBaselineFromLastReflow;
     333             :   // Note: the last baseline is a distance from our border-box end edge.
     334             :   nscoord mLastBaselineFromLastReflow;
     335             : };
     336             : 
     337             : #endif /* nsFlexContainerFrame_h___ */

Generated by: LCOV version 1.13