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