1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 /* rendering object for CSS "display: grid | inline-grid" */
8 
9 #ifndef nsGridContainerFrame_h___
10 #define nsGridContainerFrame_h___
11 
12 #include "mozilla/CSSOrderAwareFrameIterator.h"
13 #include "mozilla/Maybe.h"
14 #include "mozilla/HashTable.h"
15 #include "nsContainerFrame.h"
16 
17 namespace mozilla {
18 class PresShell;
19 }  // namespace mozilla
20 
21 /**
22  * Factory function.
23  * @return a newly allocated nsGridContainerFrame (infallible)
24  */
25 nsContainerFrame* NS_NewGridContainerFrame(mozilla::PresShell* aPresShell,
26                                            mozilla::ComputedStyle* aStyle);
27 
28 namespace mozilla {
29 
30 /**
31  * The number of implicit / explicit tracks and their sizes.
32  */
33 struct ComputedGridTrackInfo {
ComputedGridTrackInfoComputedGridTrackInfo34   ComputedGridTrackInfo(
35       uint32_t aNumLeadingImplicitTracks, uint32_t aNumExplicitTracks,
36       uint32_t aStartFragmentTrack, uint32_t aEndFragmentTrack,
37       nsTArray<nscoord>&& aPositions, nsTArray<nscoord>&& aSizes,
38       nsTArray<uint32_t>&& aStates, nsTArray<bool>&& aRemovedRepeatTracks,
39       uint32_t aRepeatFirstTrack,
40       nsTArray<nsTArray<StyleCustomIdent>>&& aResolvedLineNames,
41       bool aIsSubgrid, bool aIsMasonry)
42       : mNumLeadingImplicitTracks(aNumLeadingImplicitTracks),
43         mNumExplicitTracks(aNumExplicitTracks),
44         mStartFragmentTrack(aStartFragmentTrack),
45         mEndFragmentTrack(aEndFragmentTrack),
46         mPositions(std::move(aPositions)),
47         mSizes(std::move(aSizes)),
48         mStates(std::move(aStates)),
49         mRemovedRepeatTracks(std::move(aRemovedRepeatTracks)),
50         mResolvedLineNames(std::move(aResolvedLineNames)),
51         mRepeatFirstTrack(aRepeatFirstTrack),
52         mIsSubgrid(aIsSubgrid),
53         mIsMasonry(aIsMasonry) {}
54   uint32_t mNumLeadingImplicitTracks;
55   uint32_t mNumExplicitTracks;
56   uint32_t mStartFragmentTrack;
57   uint32_t mEndFragmentTrack;
58   nsTArray<nscoord> mPositions;
59   nsTArray<nscoord> mSizes;
60   nsTArray<uint32_t> mStates;
61   // Indicates if a track has been collapsed. This will be populated for each
62   // track in the repeat(auto-fit) and repeat(auto-fill), even if there are no
63   // collapsed tracks.
64   nsTArray<bool> mRemovedRepeatTracks;
65   // Contains lists of all line name lists, including the name lists inside
66   // repeats. When a repeat(auto) track exists, the internal track names will
67   // appear once each in this array.
68   nsTArray<nsTArray<StyleCustomIdent>> mResolvedLineNames;
69   uint32_t mRepeatFirstTrack;
70   bool mIsSubgrid;
71   bool mIsMasonry;
72 };
73 
74 struct ComputedGridLineInfo {
ComputedGridLineInfoComputedGridLineInfo75   explicit ComputedGridLineInfo(
76       nsTArray<nsTArray<RefPtr<nsAtom>>>&& aNames,
77       const nsTArray<RefPtr<nsAtom>>& aNamesBefore,
78       const nsTArray<RefPtr<nsAtom>>& aNamesAfter,
79       nsTArray<RefPtr<nsAtom>>&& aNamesFollowingRepeat)
80       : mNames(std::move(aNames)),
81         mNamesBefore(aNamesBefore.Clone()),
82         mNamesAfter(aNamesAfter.Clone()),
83         mNamesFollowingRepeat(std::move(aNamesFollowingRepeat)) {}
84   nsTArray<nsTArray<RefPtr<nsAtom>>> mNames;
85   nsTArray<RefPtr<nsAtom>> mNamesBefore;
86   nsTArray<RefPtr<nsAtom>> mNamesAfter;
87   nsTArray<RefPtr<nsAtom>> mNamesFollowingRepeat;
88 };
89 }  // namespace mozilla
90 
91 class nsGridContainerFrame final : public nsContainerFrame {
92  public:
93   NS_DECL_FRAMEARENA_HELPERS(nsGridContainerFrame)
94   NS_DECL_QUERYFRAME
95   using ComputedGridTrackInfo = mozilla::ComputedGridTrackInfo;
96   using ComputedGridLineInfo = mozilla::ComputedGridLineInfo;
97   using LogicalAxis = mozilla::LogicalAxis;
98   using BaselineSharingGroup = mozilla::BaselineSharingGroup;
99   using NamedArea = mozilla::StyleNamedArea;
100 
101   template <typename T>
102   using PerBaseline = mozilla::EnumeratedArray<BaselineSharingGroup,
103                                                BaselineSharingGroup(2), T>;
104 
105   template <typename T>
106   using PerLogicalAxis =
107       mozilla::EnumeratedArray<LogicalAxis, LogicalAxis(2), T>;
108 
109   // nsIFrame overrides
110   void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
111               const ReflowInput& aReflowInput,
112               nsReflowStatus& aStatus) override;
113   void Init(nsIContent* aContent, nsContainerFrame* aParent,
114             nsIFrame* aPrevInFlow) override;
115   void DidSetComputedStyle(ComputedStyle* aOldStyle) override;
116   nscoord GetMinISize(gfxContext* aRenderingContext) override;
117   nscoord GetPrefISize(gfxContext* aRenderingContext) override;
118   void MarkIntrinsicISizesDirty() override;
IsFrameOfType(uint32_t aFlags)119   bool IsFrameOfType(uint32_t aFlags) const override {
120     return nsContainerFrame::IsFrameOfType(
121         aFlags & ~nsIFrame::eCanContainOverflowContainers);
122   }
123 
124   void BuildDisplayList(nsDisplayListBuilder* aBuilder,
125                         const nsDisplayListSet& aLists) override;
126 
GetLogicalBaseline(mozilla::WritingMode aWM)127   nscoord GetLogicalBaseline(mozilla::WritingMode aWM) const override {
128     if (HasAnyStateBits(NS_STATE_GRID_SYNTHESIZE_BASELINE)) {
129       // Return a baseline synthesized from our margin-box.
130       return nsContainerFrame::GetLogicalBaseline(aWM);
131     }
132     nscoord b;
133     GetBBaseline(BaselineSharingGroup::First, &b);
134     return b;
135   }
136 
GetVerticalAlignBaseline(mozilla::WritingMode aWM,nscoord * aBaseline)137   bool GetVerticalAlignBaseline(mozilla::WritingMode aWM,
138                                 nscoord* aBaseline) const override {
139     return GetNaturalBaselineBOffset(aWM, BaselineSharingGroup::First,
140                                      aBaseline);
141   }
142 
GetNaturalBaselineBOffset(mozilla::WritingMode aWM,BaselineSharingGroup aBaselineGroup,nscoord * aBaseline)143   bool GetNaturalBaselineBOffset(mozilla::WritingMode aWM,
144                                  BaselineSharingGroup aBaselineGroup,
145                                  nscoord* aBaseline) const override {
146     if (StyleDisplay()->IsContainLayout() ||
147         HasAnyStateBits(NS_STATE_GRID_SYNTHESIZE_BASELINE)) {
148       return false;
149     }
150     return GetBBaseline(aBaselineGroup, aBaseline);
151   }
152 
153 #ifdef DEBUG_FRAME_DUMP
154   nsresult GetFrameName(nsAString& aResult) const override;
155   void ExtraContainerFrameInfo(nsACString& aTo) const override;
156 #endif
157 
158   // nsContainerFrame overrides
159   bool DrainSelfOverflowList() override;
160   void AppendFrames(ChildListID aListID, nsFrameList& aFrameList) override;
161   void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
162                     const nsLineList::iterator* aPrevFrameLine,
163                     nsFrameList& aFrameList) override;
164   void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) override;
165   mozilla::StyleAlignFlags CSSAlignmentForAbsPosChild(
166       const ReflowInput& aChildRI, LogicalAxis aLogicalAxis) const override;
167 
168 #ifdef DEBUG
169   void SetInitialChildList(ChildListID aListID,
170                            nsFrameList& aChildList) override;
171 #endif
172 
173   /**
174    * Return the containing block for aChild which MUST be an abs.pos. child
175    * of a grid container and that container must have been reflowed.
176    */
177   static const nsRect& GridItemCB(nsIFrame* aChild);
178 
NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridItemContainingBlockRect,nsRect)179   NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridItemContainingBlockRect, nsRect)
180 
181   /**
182    * These properties are created by a call to
183    * nsGridContainerFrame::GetGridFrameWithComputedInfo, typically from
184    * Element::GetGridFragments.
185    */
186   NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridColTrackInfo, ComputedGridTrackInfo)
187   const ComputedGridTrackInfo* GetComputedTemplateColumns() {
188     const ComputedGridTrackInfo* info = GetProperty(GridColTrackInfo());
189     MOZ_ASSERT(info, "Property generation wasn't requested.");
190     return info;
191   }
192 
NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridRowTrackInfo,ComputedGridTrackInfo)193   NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridRowTrackInfo, ComputedGridTrackInfo)
194   const ComputedGridTrackInfo* GetComputedTemplateRows() {
195     const ComputedGridTrackInfo* info = GetProperty(GridRowTrackInfo());
196     MOZ_ASSERT(info, "Property generation wasn't requested.");
197     return info;
198   }
199 
NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridColumnLineInfo,ComputedGridLineInfo)200   NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridColumnLineInfo, ComputedGridLineInfo)
201   const ComputedGridLineInfo* GetComputedTemplateColumnLines() {
202     const ComputedGridLineInfo* info = GetProperty(GridColumnLineInfo());
203     MOZ_ASSERT(info, "Property generation wasn't requested.");
204     return info;
205   }
206 
NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridRowLineInfo,ComputedGridLineInfo)207   NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridRowLineInfo, ComputedGridLineInfo)
208   const ComputedGridLineInfo* GetComputedTemplateRowLines() {
209     const ComputedGridLineInfo* info = GetProperty(GridRowLineInfo());
210     MOZ_ASSERT(info, "Property generation wasn't requested.");
211     return info;
212   }
213 
214   struct AtomKey {
215     RefPtr<nsAtom> mKey;
216 
AtomKeyAtomKey217     explicit AtomKey(nsAtom* aAtom) : mKey(aAtom) {}
218 
219     using Lookup = nsAtom*;
220 
hashAtomKey221     static mozilla::HashNumber hash(const Lookup& aKey) { return aKey->hash(); }
222 
matchAtomKey223     static bool match(const AtomKey& aFirst, const Lookup& aSecond) {
224       return aFirst.mKey == aSecond;
225     }
226   };
227 
228   using ImplicitNamedAreas = mozilla::HashMap<AtomKey, NamedArea, AtomKey>;
NS_DECLARE_FRAME_PROPERTY_DELETABLE(ImplicitNamedAreasProperty,ImplicitNamedAreas)229   NS_DECLARE_FRAME_PROPERTY_DELETABLE(ImplicitNamedAreasProperty,
230                                       ImplicitNamedAreas)
231   ImplicitNamedAreas* GetImplicitNamedAreas() const {
232     return GetProperty(ImplicitNamedAreasProperty());
233   }
234 
235   using ExplicitNamedAreas = mozilla::StyleOwnedSlice<NamedArea>;
NS_DECLARE_FRAME_PROPERTY_DELETABLE(ExplicitNamedAreasProperty,ExplicitNamedAreas)236   NS_DECLARE_FRAME_PROPERTY_DELETABLE(ExplicitNamedAreasProperty,
237                                       ExplicitNamedAreas)
238   ExplicitNamedAreas* GetExplicitNamedAreas() const {
239     return GetProperty(ExplicitNamedAreasProperty());
240   }
241 
242   using nsContainerFrame::IsMasonry;
243 
244   /** Return true if this frame has masonry layout in any axis. */
IsMasonry()245   bool IsMasonry() const {
246     return HasAnyStateBits(NS_STATE_GRID_IS_ROW_MASONRY |
247                            NS_STATE_GRID_IS_COL_MASONRY);
248   }
249 
250   /** Return true if this frame is subgridded in its aAxis. */
IsSubgrid(LogicalAxis aAxis)251   bool IsSubgrid(LogicalAxis aAxis) const {
252     return HasAnyStateBits(aAxis == mozilla::eLogicalAxisBlock
253                                ? NS_STATE_GRID_IS_ROW_SUBGRID
254                                : NS_STATE_GRID_IS_COL_SUBGRID);
255   }
IsColSubgrid()256   bool IsColSubgrid() const { return IsSubgrid(mozilla::eLogicalAxisInline); }
IsRowSubgrid()257   bool IsRowSubgrid() const { return IsSubgrid(mozilla::eLogicalAxisBlock); }
258   /** Return true if this frame is subgridded in any axis. */
IsSubgrid()259   bool IsSubgrid() const {
260     return HasAnyStateBits(NS_STATE_GRID_IS_ROW_SUBGRID |
261                            NS_STATE_GRID_IS_COL_SUBGRID);
262   }
263 
264   /** Return true if this frame has an item that is subgridded in our aAxis. */
HasSubgridItems(LogicalAxis aAxis)265   bool HasSubgridItems(LogicalAxis aAxis) const {
266     return HasAnyStateBits(aAxis == mozilla::eLogicalAxisBlock
267                                ? NS_STATE_GRID_HAS_ROW_SUBGRID_ITEM
268                                : NS_STATE_GRID_HAS_COL_SUBGRID_ITEM);
269   }
270   /** Return true if this frame has any subgrid items. */
HasSubgridItems()271   bool HasSubgridItems() const {
272     return HasAnyStateBits(NS_STATE_GRID_HAS_ROW_SUBGRID_ITEM |
273                            NS_STATE_GRID_HAS_COL_SUBGRID_ITEM);
274   }
275 
276   /**
277    * Return a container grid frame for the supplied frame, if available.
278    * @return nullptr if aFrame has no grid container.
279    */
280   static nsGridContainerFrame* GetGridContainerFrame(nsIFrame* aFrame);
281 
282   /**
283    * Return a container grid frame, and ensure it has computed grid info
284    * @return nullptr if aFrame has no grid container, or frame was destroyed
285    * @note this might destroy layout/style data since it may flush layout
286    */
287   MOZ_CAN_RUN_SCRIPT_BOUNDARY
288   static nsGridContainerFrame* GetGridFrameWithComputedInfo(nsIFrame* aFrame);
289 
290   struct Subgrid;
291   struct UsedTrackSizes;
292   struct TrackSize;
293   struct GridItemInfo;
294   struct GridReflowInput;
295   struct FindItemInGridOrderResult {
296     // The first(last) item in (reverse) grid order.
297     const GridItemInfo* mItem;
298     // Does the above item span the first(last) track?
299     bool mIsInEdgeTrack;
300   };
301 
302   /** Return our parent grid container; |this| MUST be a subgrid. */
303   nsGridContainerFrame* ParentGridContainerForSubgrid() const;
304 
305   // https://drafts.csswg.org/css-sizing/#constraints
306   enum class SizingConstraint {
307     MinContent,   // sizing under min-content constraint
308     MaxContent,   // sizing under max-content constraint
309     NoConstraint  // no constraint, used during Reflow
310   };
311 
312  protected:
313   typedef mozilla::LogicalPoint LogicalPoint;
314   typedef mozilla::LogicalRect LogicalRect;
315   typedef mozilla::LogicalSize LogicalSize;
316   typedef mozilla::WritingMode WritingMode;
317   struct Grid;
318   struct GridArea;
319   class LineNameMap;
320   struct LineRange;
321   struct SharedGridData;
322   struct SubgridFallbackTrackSizingFunctions;
323   struct TrackSizingFunctions;
324   struct Tracks;
325   struct TranslatedLineRange;
326   friend nsContainerFrame* NS_NewGridContainerFrame(
327       mozilla::PresShell* aPresShell, ComputedStyle* aStyle);
nsGridContainerFrame(ComputedStyle * aStyle,nsPresContext * aPresContext)328   explicit nsGridContainerFrame(ComputedStyle* aStyle,
329                                 nsPresContext* aPresContext)
330       : nsContainerFrame(aStyle, aPresContext, kClassID),
331         mCachedMinISize(NS_INTRINSIC_ISIZE_UNKNOWN),
332         mCachedPrefISize(NS_INTRINSIC_ISIZE_UNKNOWN) {
333     for (auto& perAxisBaseline : mBaseline) {
334       for (auto& baseline : perAxisBaseline) {
335         baseline = NS_INTRINSIC_ISIZE_UNKNOWN;
336       }
337     }
338   }
339 
340   /**
341    * XXX temporary - move the ImplicitNamedAreas stuff to the style system.
342    * The implicit area names that come from x-start .. x-end lines in
343    * grid-template-columns / grid-template-rows are stored in this frame
344    * property when needed, as a ImplicitNamedAreas* value.
345    */
346   void InitImplicitNamedAreas(const nsStylePosition* aStyle);
347 
348   using LineNameList =
349       const mozilla::StyleOwnedSlice<mozilla::StyleCustomIdent>;
350   void AddImplicitNamedAreas(mozilla::Span<LineNameList>);
351 
352   /**
353    * Reflow and place our children.
354    * @return the consumed size of all of this grid container's continuations
355    *         so far including this frame
356    */
357   nscoord ReflowChildren(GridReflowInput& aState,
358                          const LogicalRect& aContentArea,
359                          const nsSize& aContainerSize,
360                          ReflowOutput& aDesiredSize, nsReflowStatus& aStatus);
361 
362   /**
363    * Helper for GetMinISize / GetPrefISize.
364    */
365   nscoord IntrinsicISize(gfxContext* aRenderingContext,
366                          mozilla::IntrinsicISizeType aConstraint);
367 
GetBBaseline(BaselineSharingGroup aBaselineGroup,nscoord * aResult)368   bool GetBBaseline(BaselineSharingGroup aBaselineGroup,
369                     nscoord* aResult) const {
370     *aResult = mBaseline[mozilla::eLogicalAxisBlock][aBaselineGroup];
371     return true;
372   }
GetIBaseline(BaselineSharingGroup aBaselineGroup,nscoord * aResult)373   bool GetIBaseline(BaselineSharingGroup aBaselineGroup,
374                     nscoord* aResult) const {
375     *aResult = mBaseline[mozilla::eLogicalAxisInline][aBaselineGroup];
376     return true;
377   }
378 
379   /**
380    * Calculate this grid container's baselines.
381    * @param aBaselineSet which baseline(s) to derive from a baseline-group or
382    * items; a baseline not included is synthesized from the border-box instead.
383    * @param aFragmentStartTrack is the first track in this fragment in the same
384    * axis as aMajor.  Pass zero if that's not the axis we're fragmenting in.
385    * @param aFirstExcludedTrack should be the first track in the next fragment
386    * or one beyond the final track in the last fragment, in aMajor's axis.
387    * Pass the number of tracks if that's not the axis we're fragmenting in.
388    */
389   enum BaselineSet : uint32_t {
390     eNone = 0x0,
391     eFirst = 0x1,
392     eLast = 0x2,
393     eBoth = eFirst | eLast,
394   };
395   void CalculateBaselines(BaselineSet aBaselineSet,
396                           mozilla::CSSOrderAwareFrameIterator* aIter,
397                           const nsTArray<GridItemInfo>* aGridItems,
398                           const Tracks& aTracks, uint32_t aFragmentStartTrack,
399                           uint32_t aFirstExcludedTrack, WritingMode aWM,
400                           const nsSize& aCBPhysicalSize,
401                           nscoord aCBBorderPaddingStart,
402                           nscoord aCBBorderPaddingStartEnd, nscoord aCBSize);
403 
404   /**
405    * Synthesize a Grid container baseline for aGroup.
406    */
407   nscoord SynthesizeBaseline(const FindItemInGridOrderResult& aItem,
408                              LogicalAxis aAxis, BaselineSharingGroup aGroup,
409                              const nsSize& aCBPhysicalSize, nscoord aCBSize,
410                              WritingMode aCBWM);
411   /**
412    * Find the first item in Grid Order in this fragment.
413    * https://drafts.csswg.org/css-grid/#grid-order
414    * @param aFragmentStartTrack is the first track in this fragment in the same
415    * axis as aMajor.  Pass zero if that's not the axis we're fragmenting in.
416    */
417   static FindItemInGridOrderResult FindFirstItemInGridOrder(
418       mozilla::CSSOrderAwareFrameIterator& aIter,
419       const nsTArray<GridItemInfo>& aGridItems, LineRange GridArea::*aMajor,
420       LineRange GridArea::*aMinor, uint32_t aFragmentStartTrack);
421   /**
422    * Find the last item in Grid Order in this fragment.
423    * @param aFragmentStartTrack is the first track in this fragment in the same
424    * axis as aMajor.  Pass zero if that's not the axis we're fragmenting in.
425    * @param aFirstExcludedTrack should be the first track in the next fragment
426    * or one beyond the final track in the last fragment, in aMajor's axis.
427    * Pass the number of tracks if that's not the axis we're fragmenting in.
428    */
429   static FindItemInGridOrderResult FindLastItemInGridOrder(
430       mozilla::ReverseCSSOrderAwareFrameIterator& aIter,
431       const nsTArray<GridItemInfo>& aGridItems, LineRange GridArea::*aMajor,
432       LineRange GridArea::*aMinor, uint32_t aFragmentStartTrack,
433       uint32_t aFirstExcludedTrack);
434 
435   /**
436    * Update our NS_STATE_GRID_IS_COL/ROW_SUBGRID bits and related subgrid state
437    * on our entire continuation chain based on the current style.
438    * This is needed because grid-template-columns/rows style changes only
439    * trigger a reflow so we need to update this dynamically.
440    */
441   void UpdateSubgridFrameState();
442 
443   /**
444    * Return the NS_STATE_GRID_IS_COL/ROW_SUBGRID and
445    * NS_STATE_GRID_IS_ROW/COL_MASONRY bits we ought to have.
446    */
447   nsFrameState ComputeSelfSubgridMasonryBits() const;
448 
449   /** Helper for ComputeSelfSubgridMasonryBits(). */
450   bool WillHaveAtLeastOneTrackInAxis(LogicalAxis aAxis) const;
451 
452  private:
453   // Helpers for ReflowChildren
454   struct Fragmentainer {
455     /**
456      * The distance from the first grid container fragment's block-axis content
457      * edge to the fragmentainer end.
458      */
459     nscoord mToFragmentainerEnd;
460     /**
461      * True if the current fragment is at the start of the fragmentainer.
462      */
463     bool mIsTopOfPage;
464     /**
465      * Is there a Class C break opportunity at the start content edge?
466      */
467     bool mCanBreakAtStart;
468     /**
469      * Is there a Class C break opportunity at the end content edge?
470      */
471     bool mCanBreakAtEnd;
472     /**
473      * Is the grid container's block-size unconstrained?
474      */
475     bool mIsAutoBSize;
476   };
477 
478   mozilla::Maybe<nsGridContainerFrame::Fragmentainer> GetNearestFragmentainer(
479       const GridReflowInput& aState) const;
480 
481   // @return the consumed size of all continuations so far including this frame
482   nscoord ReflowInFragmentainer(GridReflowInput& aState,
483                                 const LogicalRect& aContentArea,
484                                 ReflowOutput& aDesiredSize,
485                                 nsReflowStatus& aStatus,
486                                 Fragmentainer& aFragmentainer,
487                                 const nsSize& aContainerSize);
488 
489   // Helper for ReflowInFragmentainer
490   // @return the consumed size of all continuations so far including this frame
491   nscoord ReflowRowsInFragmentainer(
492       GridReflowInput& aState, const LogicalRect& aContentArea,
493       ReflowOutput& aDesiredSize, nsReflowStatus& aStatus,
494       Fragmentainer& aFragmentainer, const nsSize& aContainerSize,
495       const nsTArray<const GridItemInfo*>& aItems, uint32_t aStartRow,
496       uint32_t aEndRow, nscoord aBSize, nscoord aAvailableSize);
497 
498   // Helper for ReflowChildren / ReflowInFragmentainer
499   void ReflowInFlowChild(nsIFrame* aChild, const GridItemInfo* aGridItemInfo,
500                          nsSize aContainerSize,
501                          const mozilla::Maybe<nscoord>& aStretchBSize,
502                          const Fragmentainer* aFragmentainer,
503                          const GridReflowInput& aState,
504                          const LogicalRect& aContentArea,
505                          ReflowOutput& aDesiredSize, nsReflowStatus& aStatus);
506 
507   /**
508    * Places and reflows items when we have masonry layout.
509    * It handles unconstrained reflow and also fragmentation when the row axis
510    * is the masonry axis.  ReflowInFragmentainer handles the case when we're
511    * fragmenting and our row axis is a grid axis and it handles masonry layout
512    * in the column axis in that case.
513    * @return the intrinsic size in the masonry axis
514    */
515   nscoord MasonryLayout(GridReflowInput& aState,
516                         const LogicalRect& aContentArea,
517                         SizingConstraint aConstraint,
518                         ReflowOutput& aDesiredSize, nsReflowStatus& aStatus,
519                         Fragmentainer* aFragmentainer,
520                         const nsSize& aContainerSize);
521 
522   // Return the stored UsedTrackSizes, if any.
523   UsedTrackSizes* GetUsedTrackSizes() const;
524 
525   // Store the given TrackSizes in aAxis on a UsedTrackSizes frame property.
526   void StoreUsedTrackSizes(LogicalAxis aAxis,
527                            const nsTArray<TrackSize>& aSizes);
528 
529   /**
530    * Cached values to optimize GetMinISize/GetPrefISize.
531    */
532   nscoord mCachedMinISize;
533   nscoord mCachedPrefISize;
534 
535   // Our baselines, one per BaselineSharingGroup per axis.
536   PerLogicalAxis<PerBaseline<nscoord>> mBaseline;
537 };
538 
539 #endif /* nsGridContainerFrame_h___ */
540