[CSS Grid Layout] Grid item's auto-margins are not applied correctly
[WebKit-https.git] / Source / WebCore / rendering / RenderGrid.h
1 /*
2  * Copyright (C) 2011 Apple Inc. All rights reserved.
3  * Copyright (C) 2013, 2014 Igalia S.L.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #ifndef RenderGrid_h
28 #define RenderGrid_h
29
30 #if ENABLE(CSS_GRID_LAYOUT)
31
32 #include "GridResolvedPosition.h"
33 #include "OrderIterator.h"
34 #include "RenderBlock.h"
35
36 namespace WebCore {
37
38 class GridCoordinate;
39 class GridSpan;
40 class GridTrack;
41 class GridItemWithSpan;
42
43 enum GridAxisPosition {GridAxisStart, GridAxisEnd, GridAxisCenter};
44
45 class RenderGrid final : public RenderBlock {
46 public:
47     RenderGrid(Element&, Ref<RenderStyle>&&);
48     virtual ~RenderGrid();
49
50     Element& element() const { return downcast<Element>(nodeForNonAnonymous()); }
51
52     virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) override;
53
54     virtual bool avoidsFloats() const override { return true; }
55     virtual bool canCollapseAnonymousBlockChild() const override { return false; }
56
57     const Vector<LayoutUnit>& columnPositions() const { return m_columnPositions; }
58     const Vector<LayoutUnit>& rowPositions() const { return m_rowPositions; }
59
60 private:
61     virtual const char* renderName() const override;
62     virtual bool isRenderGrid() const override { return true; }
63     virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const override;
64     virtual void computePreferredLogicalWidths() override;
65
66     class GridIterator;
67     class GridSizingData;
68     void computeUsedBreadthOfGridTracks(GridTrackSizingDirection, GridSizingData&);
69     void computeUsedBreadthOfGridTracks(GridTrackSizingDirection, GridSizingData&, LayoutUnit& availableLogicalSpace);
70     bool gridElementIsShrinkToFit();
71     LayoutUnit computeUsedBreadthOfMinLength(GridTrackSizingDirection, const GridLength&) const;
72     LayoutUnit computeUsedBreadthOfMaxLength(GridTrackSizingDirection, const GridLength&, LayoutUnit usedBreadth) const;
73     LayoutUnit computeUsedBreadthOfSpecifiedLength(GridTrackSizingDirection, const Length&) const;
74     void resolveContentBasedTrackSizingFunctions(GridTrackSizingDirection, GridSizingData&);
75
76     void ensureGridSize(unsigned maximumRowIndex, unsigned maximumColumnIndex);
77     void insertItemIntoGrid(RenderBox&, const GridCoordinate&);
78     void placeItemsOnGrid();
79     void populateExplicitGridAndOrderIterator();
80     std::unique_ptr<GridCoordinate> createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(const RenderBox&, GridTrackSizingDirection, const GridSpan&) const;
81     void placeSpecifiedMajorAxisItemsOnGrid(const Vector<RenderBox*>&);
82     void placeAutoMajorAxisItemsOnGrid(const Vector<RenderBox*>&);
83     typedef std::pair<unsigned, unsigned> AutoPlacementCursor;
84     void placeAutoMajorAxisItemOnGrid(RenderBox&, AutoPlacementCursor&);
85     GridTrackSizingDirection autoPlacementMajorAxisDirection() const;
86     GridTrackSizingDirection autoPlacementMinorAxisDirection() const;
87
88     void layoutGridItems();
89     void populateGridPositions(const GridSizingData&);
90     void clearGrid();
91
92     enum TrackSizeRestriction {
93         AllowInfinity,
94         ForbidInfinity,
95     };
96     enum TrackSizeComputationPhase {
97         ResolveIntrinsicMinimums,
98         ResolveMaxContentMinimums,
99         ResolveIntrinsicMaximums,
100         ResolveMaxContentMaximums,
101         MaximizeTracks,
102     };
103     static const LayoutUnit& trackSizeForTrackSizeComputationPhase(TrackSizeComputationPhase, GridTrack&, TrackSizeRestriction);
104     static bool shouldProcessTrackForTrackSizeComputationPhase(TrackSizeComputationPhase, const GridTrackSize&);
105     static bool trackShouldGrowBeyondGrowthLimitsForTrackSizeComputationPhase(TrackSizeComputationPhase, const GridTrackSize&);
106     static void markAsInfinitelyGrowableForTrackSizeComputationPhase(TrackSizeComputationPhase, GridTrack&);
107     static void updateTrackSizeForTrackSizeComputationPhase(TrackSizeComputationPhase, GridTrack&);
108     LayoutUnit currentItemSizeForTrackSizeComputationPhase(TrackSizeComputationPhase, RenderBox&, GridTrackSizingDirection, Vector<GridTrack>& columnTracks);
109
110     typedef struct GridItemsSpanGroupRange GridItemsSpanGroupRange;
111     void resolveContentBasedTrackSizingFunctionsForNonSpanningItems(GridTrackSizingDirection, const GridCoordinate&, RenderBox& gridItem, GridTrack&, Vector<GridTrack>& columnTracks);
112     template <TrackSizeComputationPhase> void resolveContentBasedTrackSizingFunctionsForItems(GridTrackSizingDirection, GridSizingData&, const GridItemsSpanGroupRange&);
113     template <TrackSizeComputationPhase> void distributeSpaceToTracks(Vector<GridTrack*>&, const Vector<GridTrack*>* growBeyondGrowthLimitsTracks, LayoutUnit& availableLogicalSpace);
114
115     double computeNormalizedFractionBreadth(Vector<GridTrack>&, const GridSpan& tracksSpan, GridTrackSizingDirection, LayoutUnit availableLogicalSpace) const;
116
117     GridTrackSize gridTrackSize(GridTrackSizingDirection, unsigned) const;
118
119     LayoutUnit logicalContentHeightForChild(RenderBox&, Vector<GridTrack>&);
120     LayoutUnit minContentForChild(RenderBox&, GridTrackSizingDirection, Vector<GridTrack>& columnTracks);
121     LayoutUnit maxContentForChild(RenderBox&, GridTrackSizingDirection, Vector<GridTrack>& columnTracks);
122     GridAxisPosition columnAxisPositionForChild(const RenderBox&) const;
123     GridAxisPosition rowAxisPositionForChild(const RenderBox&) const;
124     LayoutUnit rowPositionForChild(const RenderBox&) const;
125     LayoutUnit columnPositionForChild(const RenderBox&) const;
126     LayoutPoint findChildLogicalPosition(const RenderBox&) const;
127     GridCoordinate cachedGridCoordinate(const RenderBox&) const;
128
129
130     LayoutUnit gridAreaBreadthForChild(const RenderBox& child, GridTrackSizingDirection, const Vector<GridTrack>&) const;
131
132     virtual void paintChildren(PaintInfo& forSelf, const LayoutPoint& paintOffset, PaintInfo& forChild, bool usePrintRect) override;
133     bool allowedToStretchLogicalHeightForChild(const RenderBox&) const;
134     bool needToStretchChildLogicalHeight(const RenderBox&) const;
135     LayoutUnit marginLogicalHeightForChild(const RenderBox&) const;
136     LayoutUnit computeMarginLogicalHeightForChild(const RenderBox&) const;
137     LayoutUnit availableAlignmentSpaceForChildBeforeStretching(LayoutUnit gridAreaBreadthForChild, const RenderBox&) const;
138     void applyStretchAlignmentToChildIfNeeded(RenderBox&, LayoutUnit gridAreaBreadthForChild);
139     bool hasAutoMarginsInColumnAxis(const RenderBox&) const;
140     bool hasAutoMarginsInRowAxis(const RenderBox&) const;
141     void updateAutoMarginsInColumnAxisIfNeeded(RenderBox&, LayoutUnit gridAreaBreadthForChild);
142
143 #ifndef NDEBUG
144     bool tracksAreWiderThanMinTrackBreadth(GridTrackSizingDirection, const Vector<GridTrack>&);
145 #endif
146
147     bool gridWasPopulated() const { return !m_grid.isEmpty() && !m_grid[0].isEmpty(); }
148
149     bool spanningItemCrossesFlexibleSizedTracks(const GridCoordinate&, GridTrackSizingDirection) const;
150
151     unsigned gridColumnCount() const
152     {
153         ASSERT(gridWasPopulated());
154         return m_grid[0].size();
155     }
156     unsigned gridRowCount() const
157     {
158         ASSERT(gridWasPopulated());
159         return m_grid.size();
160     }
161
162     bool hasDefiniteLogicalSize(GridTrackSizingDirection) const;
163
164     Vector<Vector<Vector<RenderBox*, 1>>> m_grid;
165     Vector<LayoutUnit> m_columnPositions;
166     Vector<LayoutUnit> m_rowPositions;
167     HashMap<const RenderBox*, GridCoordinate> m_gridItemCoordinate;
168     OrderIterator m_orderIterator;
169 };
170
171 } // namespace WebCore
172
173 SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderGrid, isRenderGrid())
174
175 #endif /* ENABLE(CSS_GRID_LAYOUT) */
176
177 #endif // RenderGrid_h