Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(626)

Side by Side Diff: third_party/WebKit/Source/core/style/GridResolvedPosition.cpp

Issue 1424913009: [css-grid] Simplify the interface of GridResolvedPosition (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 #include "core/style/GridResolvedPosition.h" 6 #include "core/style/GridResolvedPosition.h"
7 7
8 #include "core/layout/LayoutBox.h" 8 #include "core/layout/LayoutBox.h"
9 #include "core/style/GridCoordinate.h" 9 #include "core/style/GridCoordinate.h"
10 10
11 namespace blink { 11 namespace blink {
12 12
13 static GridSpan resolveNamedGridLinePositionAgainstOppositePosition(const Comput edStyle& gridContainerStyle, const GridResolvedPosition& resolvedOppositePositio n, const GridPosition&, GridPositionSide);
14
15 static bool isColumnSide(GridPositionSide side)
16 {
17 return side == ColumnStartSide || side == ColumnEndSide;
18 }
19
13 static const NamedGridLinesMap& gridLinesForSide(const ComputedStyle& style, Gri dPositionSide side) 20 static const NamedGridLinesMap& gridLinesForSide(const ComputedStyle& style, Gri dPositionSide side)
14 { 21 {
15 return (side == ColumnStartSide || side == ColumnEndSide) ? style.namedGridC olumnLines() : style.namedGridRowLines(); 22 return isColumnSide(side) ? style.namedGridColumnLines() : style.namedGridRo wLines();
16 } 23 }
17 24
18 static inline String implicitNamedGridLineForSide(const String& lineName, GridPo sitionSide side) 25 static inline String implicitNamedGridLineForSide(const String& lineName, GridPo sitionSide side)
19 { 26 {
20 return lineName + ((side == ColumnStartSide || side == RowStartSide) ? "-sta rt" : "-end"); 27 return lineName + ((side == ColumnStartSide || side == RowStartSide) ? "-sta rt" : "-end");
21 } 28 }
22 29
30 static GridPositionSide initialPositionSide(GridTrackSizingDirection direction)
31 {
32 return direction == ForColumns ? ColumnStartSide : RowStartSide;
33 }
34
35 static GridPositionSide finalPositionSide(GridTrackSizingDirection direction)
36 {
37 return direction == ForColumns ? ColumnEndSide : RowEndSide;
38 }
39
40 static size_t explicitGridSizeForSide(const ComputedStyle& gridContainerStyle, G ridPositionSide side)
41 {
42 return isColumnSide(side) ? GridResolvedPosition::explicitGridColumnCount(gr idContainerStyle) : GridResolvedPosition::explicitGridRowCount(gridContainerStyl e);
43 }
44
45 bool GridUnresolvedSpan::requiresAutoPlacement() const
46 {
47 return m_initialPosition.shouldBeResolvedAgainstOppositePosition() && m_fina lPosition.shouldBeResolvedAgainstOppositePosition();
48 }
49
50 GridUnresolvedSpan& GridUnresolvedSpan::adjustGridPositionsFromStyle(const Compu tedStyle& gridContainerStyle)
51 {
52 ASSERT(isColumnSide(m_initialPositionSide) == isColumnSide(m_finalPositionSi de));
53
54 // We must handle the placement error handling code here instead of in the S tyleAdjuster because we don't want to
55 // overwrite the specified values.
56 if (m_initialPosition.isSpan() && m_finalPosition.isSpan())
57 m_finalPosition.setAutoPosition();
58
59 // Try to early detect the case of non existing named grid lines. This way w e could assume later that
60 // GridResolvedPosition::resolveGrisPositionFromStyle() won't require the au toplacement to run, i.e., it'll always return a
61 // valid resolved position.
62 if (m_initialPosition.isNamedGridArea() && !GridResolvedPosition::isValidNam edLineOrArea(m_initialPosition.namedGridLine(), gridContainerStyle, m_initialPos itionSide))
63 m_initialPosition.setAutoPosition();
64
65 if (m_finalPosition.isNamedGridArea() && !GridResolvedPosition::isValidNamed LineOrArea(m_finalPosition.namedGridLine(), gridContainerStyle, m_finalPositionS ide))
66 m_finalPosition.setAutoPosition();
67
68 // If the grid item has an automatic position and a grid span for a named li ne in a given dimension, instead treat the grid span as one.
69 if (m_initialPosition.isAuto() && m_finalPosition.isSpan() && !m_finalPositi on.namedGridLine().isNull())
70 m_finalPosition.setSpanPosition(1, String());
71 if (m_finalPosition.isAuto() && m_initialPosition.isSpan() && !m_initialPosi tion.namedGridLine().isNull())
72 m_initialPosition.setSpanPosition(1, String());
73
74 return *this;
75 }
76
77 static GridResolvedPosition adjustGridPositionForRowEndColumnEndSide(size_t reso lvedPosition)
78 {
79 return resolvedPosition ? GridResolvedPosition(resolvedPosition - 1) : GridR esolvedPosition(0);
80 }
81
82 static GridResolvedPosition adjustGridPositionForSide(size_t resolvedPosition, G ridPositionSide side)
83 {
84 // An item finishing on the N-th line belongs to the N-1-th cell.
85 if (side == ColumnEndSide || side == RowEndSide)
86 return adjustGridPositionForRowEndColumnEndSide(resolvedPosition);
87
88 return GridResolvedPosition(resolvedPosition);
89 }
90
91 GridResolvedPosition::GridResolvedPosition(const GridPosition& position, GridPos itionSide side)
92 {
93 ASSERT(position.integerPosition());
94 size_t integerPosition = position.integerPosition() - 1;
95
96 m_integerPosition = adjustGridPositionForSide(integerPosition, side).toInt() ;
97 }
98
23 bool GridResolvedPosition::isValidNamedLineOrArea(const String& lineName, const ComputedStyle& style, GridPositionSide side) 99 bool GridResolvedPosition::isValidNamedLineOrArea(const String& lineName, const ComputedStyle& style, GridPositionSide side)
24 { 100 {
25 const NamedGridLinesMap& gridLineNames = gridLinesForSide(style, side); 101 const NamedGridLinesMap& gridLineNames = gridLinesForSide(style, side);
26 102
27 return gridLineNames.contains(implicitNamedGridLineForSide(lineName, side)) || gridLineNames.contains(lineName); 103 return gridLineNames.contains(implicitNamedGridLineForSide(lineName, side)) || gridLineNames.contains(lineName);
28 } 104 }
29 105
30 GridPositionSide GridResolvedPosition::initialPositionSide(GridTrackSizingDirect ion direction)
31 {
32 return (direction == ForColumns) ? ColumnStartSide : RowStartSide;
33 }
34
35 GridPositionSide GridResolvedPosition::finalPositionSide(GridTrackSizingDirectio n direction)
36 {
37 return (direction == ForColumns) ? ColumnEndSide : RowEndSide;
38 }
39
40 void GridResolvedPosition::initialAndFinalPositionsFromStyle(const ComputedStyle & gridContainerStyle, const LayoutBox& gridItem, GridTrackSizingDirection direct ion, GridPosition& initialPosition, GridPosition& finalPosition) 106 void GridResolvedPosition::initialAndFinalPositionsFromStyle(const ComputedStyle & gridContainerStyle, const LayoutBox& gridItem, GridTrackSizingDirection direct ion, GridPosition& initialPosition, GridPosition& finalPosition)
41 { 107 {
42 initialPosition = (direction == ForColumns) ? gridItem.style()->gridColumnSt art() : gridItem.style()->gridRowStart(); 108 initialPosition = (direction == ForColumns) ? gridItem.style()->gridColumnSt art() : gridItem.style()->gridRowStart();
43 finalPosition = (direction == ForColumns) ? gridItem.style()->gridColumnEnd( ) : gridItem.style()->gridRowEnd(); 109 finalPosition = (direction == ForColumns) ? gridItem.style()->gridColumnEnd( ) : gridItem.style()->gridRowEnd();
44 110
45 // We must handle the placement error handling code here instead of in the S tyleAdjuster because we don't want to 111 // We must handle the placement error handling code here instead of in the S tyleAdjuster because we don't want to
46 // overwrite the specified values. 112 // overwrite the specified values.
47 if (initialPosition.isSpan() && finalPosition.isSpan()) 113 if (initialPosition.isSpan() && finalPosition.isSpan())
48 finalPosition.setAutoPosition(); 114 finalPosition.setAutoPosition();
49 115
50 // Try to early detect the case of non existing named grid lines. This way w e could assume later that 116 // Try to early detect the case of non existing named grid lines. This way w e could assume later that
51 // GridResolvedPosition::resolveGrisPositionFromStyle() always return a vali d resolved position. 117 // GridResolvedPosition::resolveGrisPositionFromStyle() always return a vali d resolved position.
52 if (initialPosition.isNamedGridArea() && !isValidNamedLineOrArea(initialPosi tion.namedGridLine(), gridContainerStyle, initialPositionSide(direction))) 118 if (initialPosition.isNamedGridArea() && !isValidNamedLineOrArea(initialPosi tion.namedGridLine(), gridContainerStyle, initialPositionSide(direction)))
53 initialPosition.setAutoPosition(); 119 initialPosition.setAutoPosition();
54 120
55 if (finalPosition.isNamedGridArea() && !isValidNamedLineOrArea(finalPosition .namedGridLine(), gridContainerStyle, finalPositionSide(direction))) 121 if (finalPosition.isNamedGridArea() && !isValidNamedLineOrArea(finalPosition .namedGridLine(), gridContainerStyle, finalPositionSide(direction)))
56 finalPosition.setAutoPosition(); 122 finalPosition.setAutoPosition();
57 123
58 // If the grid item has an automatic position and a grid span for a named li ne in a given dimension, instead treat the grid span as one. 124 // If the grid item has an automatic position and a grid span for a named li ne in a given dimension, instead treat the grid span as one.
59 if (initialPosition.isAuto() && finalPosition.isSpan() && !finalPosition.nam edGridLine().isNull()) 125 if (initialPosition.isAuto() && finalPosition.isSpan() && !finalPosition.nam edGridLine().isNull())
60 finalPosition.setSpanPosition(1, String()); 126 finalPosition.setSpanPosition(1, String());
61 if (finalPosition.isAuto() && initialPosition.isSpan() && !initialPosition.n amedGridLine().isNull()) 127 if (finalPosition.isAuto() && initialPosition.isSpan() && !initialPosition.n amedGridLine().isNull())
62 initialPosition.setSpanPosition(1, String()); 128 initialPosition.setSpanPosition(1, String());
63 } 129 }
64 130
131 static GridSpan resolveGridPositionAgainstOppositePosition(const ComputedStyle& gridContainerStyle, const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, GridPositionSide side)
132 {
133 if (position.isAuto())
134 return GridSpan(resolvedOppositePosition, resolvedOppositePosition);
135
136 ASSERT(position.isSpan());
137 ASSERT(position.spanPosition() > 0);
138
139 if (!position.namedGridLine().isNull()) {
140 // span 2 'c' -> we need to find the appropriate grid line before / afte r our opposite position.
141 return resolveNamedGridLinePositionAgainstOppositePosition(gridContainer Style, resolvedOppositePosition, position, side);
142 }
143
144 // 'span 1' is contained inside a single grid track regardless of the direct ion.
145 // That's why the CSS span value is one more than the offset we apply.
146 size_t positionOffset = position.spanPosition() - 1;
147 if (side == ColumnStartSide || side == RowStartSide) {
148 size_t initialResolvedPosition = std::max<int>(0, resolvedOppositePositi on.toInt() - positionOffset);
149 return GridSpan(initialResolvedPosition, resolvedOppositePosition);
150 }
151
152 return GridSpan(resolvedOppositePosition, resolvedOppositePosition.toInt() + positionOffset);
153 }
154
65 GridSpan GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(con st ComputedStyle& gridContainerStyle, const LayoutBox& gridItem, GridTrackSizing Direction direction, const GridResolvedPosition& resolvedInitialPosition) 155 GridSpan GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(con st ComputedStyle& gridContainerStyle, const LayoutBox& gridItem, GridTrackSizing Direction direction, const GridResolvedPosition& resolvedInitialPosition)
66 { 156 {
67 GridPosition initialPosition, finalPosition; 157 GridPosition initialPosition, finalPosition;
68 initialAndFinalPositionsFromStyle(gridContainerStyle, gridItem, direction, i nitialPosition, finalPosition); 158 initialAndFinalPositionsFromStyle(gridContainerStyle, gridItem, direction, i nitialPosition, finalPosition);
69 159
70 GridPositionSide finalSide = finalPositionSide(direction); 160 GridPositionSide finalSide = finalPositionSide(direction);
71 161
72 // This method will only be used when both positions need to be resolved aga inst the opposite one. 162 // This method will only be used when both positions need to be resolved aga inst the opposite one.
73 ASSERT(initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPos ition.shouldBeResolvedAgainstOppositePosition()); 163 ASSERT(initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPos ition.shouldBeResolvedAgainstOppositePosition());
74 164
75 GridResolvedPosition resolvedFinalPosition = resolvedInitialPosition; 165 GridResolvedPosition resolvedFinalPosition = resolvedInitialPosition;
76 166
77 if (initialPosition.isSpan()) 167 if (initialPosition.isSpan())
78 return *resolveGridPositionAgainstOppositePosition(gridContainerStyle, r esolvedInitialPosition, initialPosition, finalSide); 168 return resolveGridPositionAgainstOppositePosition(gridContainerStyle, re solvedInitialPosition, initialPosition, finalSide);
79 if (finalPosition.isSpan()) 169 if (finalPosition.isSpan())
80 return *resolveGridPositionAgainstOppositePosition(gridContainerStyle, r esolvedInitialPosition, finalPosition, finalSide); 170 return resolveGridPositionAgainstOppositePosition(gridContainerStyle, re solvedInitialPosition, finalPosition, finalSide);
81 171
82 return GridSpan(resolvedInitialPosition, resolvedFinalPosition); 172 return GridSpan(resolvedInitialPosition, resolvedFinalPosition);
83 } 173 }
84 174
85 PassOwnPtr<GridSpan> GridResolvedPosition::resolveGridPositionsFromStyle(const C omputedStyle& gridContainerStyle, const LayoutBox& gridItem, GridTrackSizingDire ction direction) 175 static GridResolvedPosition resolveNamedGridLinePositionFromStyle(const Computed Style& gridContainerStyle, const GridPosition& position, GridPositionSide side)
86 {
87 GridPosition initialPosition, finalPosition;
88 initialAndFinalPositionsFromStyle(gridContainerStyle, gridItem, direction, i nitialPosition, finalPosition);
89
90 GridPositionSide initialSide = initialPositionSide(direction);
91 GridPositionSide finalSide = finalPositionSide(direction);
92
93 if (initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPositi on.shouldBeResolvedAgainstOppositePosition()) {
94 // We can't get our grid positions without running the auto placement al gorithm.
95 return nullptr;
96 }
97
98 if (initialPosition.shouldBeResolvedAgainstOppositePosition()) {
99 // Infer the position from the final position ('auto / 1' or 'span 2 / 3 ' case).
100 GridResolvedPosition finalResolvedPosition = resolveGridPositionFromStyl e(gridContainerStyle, finalPosition, finalSide);
101 return resolveGridPositionAgainstOppositePosition(gridContainerStyle, fi nalResolvedPosition, initialPosition, initialSide);
102 }
103
104 if (finalPosition.shouldBeResolvedAgainstOppositePosition()) {
105 // Infer our position from the initial position ('1 / auto' or '3 / span 2' case).
106 GridResolvedPosition initialResolvedPosition = resolveGridPositionFromSt yle(gridContainerStyle, initialPosition, initialSide);
107 return resolveGridPositionAgainstOppositePosition(gridContainerStyle, in itialResolvedPosition, finalPosition, finalSide);
108 }
109
110 GridResolvedPosition resolvedInitialPosition = resolveGridPositionFromStyle( gridContainerStyle, initialPosition, initialSide);
111 GridResolvedPosition resolvedFinalPosition = resolveGridPositionFromStyle(gr idContainerStyle, finalPosition, finalSide);
112
113 // If 'grid-after' specifies a line at or before that specified by 'grid-bef ore', it computes to 'span 1'.
114 if (resolvedFinalPosition < resolvedInitialPosition)
115 resolvedFinalPosition = resolvedInitialPosition;
116
117 return adoptPtr(new GridSpan(resolvedInitialPosition, resolvedFinalPosition) );
118 }
119
120 size_t GridResolvedPosition::explicitGridColumnCount(const ComputedStyle& gridCo ntainerStyle)
121 {
122 return std::min(gridContainerStyle.gridTemplateColumns().size(), kGridMaxTra cks);
123 }
124
125 size_t GridResolvedPosition::explicitGridRowCount(const ComputedStyle& gridConta inerStyle)
126 {
127 return std::min(gridContainerStyle.gridTemplateRows().size(), kGridMaxTracks );
128 }
129
130 size_t GridResolvedPosition::explicitGridSizeForSide(const ComputedStyle& gridCo ntainerStyle, GridPositionSide side)
131 {
132 return (side == ColumnStartSide || side == ColumnEndSide) ? explicitGridColu mnCount(gridContainerStyle) : explicitGridRowCount(gridContainerStyle);
133 }
134
135 GridResolvedPosition GridResolvedPosition::resolveNamedGridLinePositionFromStyle (const ComputedStyle& gridContainerStyle, const GridPosition& position, GridPosi tionSide side)
136 { 176 {
137 ASSERT(!position.namedGridLine().isNull()); 177 ASSERT(!position.namedGridLine().isNull());
138 178
139 const NamedGridLinesMap& gridLinesNames = gridLinesForSide(gridContainerStyl e, side); 179 const NamedGridLinesMap& gridLinesNames = gridLinesForSide(gridContainerStyl e, side);
140 NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGri dLine()); 180 NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGri dLine());
141 if (it == gridLinesNames.end()) { 181 if (it == gridLinesNames.end()) {
142 if (position.isPositive()) 182 if (position.isPositive())
143 return GridResolvedPosition(0); 183 return GridResolvedPosition(0);
144 const size_t lastLine = explicitGridSizeForSide(gridContainerStyle, side ); 184 const size_t lastLine = explicitGridSizeForSide(gridContainerStyle, side );
145 return adjustGridPositionForSide(lastLine, side); 185 return adjustGridPositionForSide(lastLine, side);
146 } 186 }
147 187
148 size_t namedGridLineIndex; 188 size_t namedGridLineIndex;
149 if (position.isPositive()) 189 if (position.isPositive())
150 namedGridLineIndex = std::min<size_t>(position.integerPosition(), it->va lue.size()) - 1; 190 namedGridLineIndex = std::min<size_t>(position.integerPosition(), it->va lue.size()) - 1;
151 else 191 else
152 namedGridLineIndex = std::max<int>(it->value.size() - abs(position.integ erPosition()), 0); 192 namedGridLineIndex = std::max<int>(it->value.size() - abs(position.integ erPosition()), 0);
153 return adjustGridPositionForSide(it->value[namedGridLineIndex], side); 193 return adjustGridPositionForSide(it->value[namedGridLineIndex], side);
154 } 194 }
155 195
156 GridResolvedPosition GridResolvedPosition::resolveGridPositionFromStyle(const Co mputedStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side) 196 static GridResolvedPosition resolveGridPositionFromStyle(const ComputedStyle& gr idContainerStyle, const GridPosition& position, GridPositionSide side)
157 { 197 {
158 switch (position.type()) { 198 switch (position.type()) {
159 case ExplicitPosition: { 199 case ExplicitPosition: {
160 ASSERT(position.integerPosition()); 200 ASSERT(position.integerPosition());
161 201
162 if (!position.namedGridLine().isNull()) 202 if (!position.namedGridLine().isNull())
163 return resolveNamedGridLinePositionFromStyle(gridContainerStyle, pos ition, side); 203 return resolveNamedGridLinePositionFromStyle(gridContainerStyle, pos ition, side);
164 204
165 // Handle <integer> explicit position. 205 // Handle <integer> explicit position.
166 if (position.isPositive()) 206 if (position.isPositive())
167 return adjustGridPositionForSide(position.integerPosition() - 1, sid e); 207 return adjustGridPositionForSide(position.integerPosition() - 1, sid e);
168 208
169 size_t resolvedPosition = abs(position.integerPosition()) - 1; 209 size_t resolvedPosition = abs(position.integerPosition()) - 1;
170 const size_t endOfTrack = explicitGridSizeForSide(gridContainerStyle, si de); 210 const size_t endOfTrack = explicitGridSizeForSide(gridContainerStyle, si de);
171 211
172 // Per http://lists.w3.org/Archives/Public/www-style/2013Mar/0589.html, we clamp negative value to the first line. 212 // Per http://lists.w3.org/Archives/Public/www-style/2013Mar/0589.html, we clamp negative value to the first line.
173 if (endOfTrack < resolvedPosition) 213 if (endOfTrack < resolvedPosition)
174 return GridResolvedPosition(0); 214 return GridResolvedPosition(0);
175 215
176 return adjustGridPositionForSide(endOfTrack - resolvedPosition, side); 216 return adjustGridPositionForSide(endOfTrack - resolvedPosition, side);
177 } 217 }
178 case NamedGridAreaPosition: 218 case NamedGridAreaPosition:
179 { 219 {
180 // First attempt to match the grid area's edge to a named grid area: if there is a named line with the name 220 // First attempt to match the grid area's edge to a named grid area: if there is a named line with the name
181 // ''<custom-ident>-start (for grid-*-start) / <custom-ident>-end'' (for grid-*-end), contributes the first such 221 // ''<custom-ident>-start (for grid-*-start) / <custom-ident>-end'' (for grid-*-end), contributes the first such
182 // line to the grid item's placement. 222 // line to the grid item's placement.
183 String namedGridLine = position.namedGridLine(); 223 String namedGridLine = position.namedGridLine();
184 ASSERT(isValidNamedLineOrArea(namedGridLine, gridContainerStyle, side)); 224 ASSERT(GridResolvedPosition::isValidNamedLineOrArea(namedGridLine, gridC ontainerStyle, side));
185 225
186 const NamedGridLinesMap& gridLineNames = gridLinesForSide(gridContainerS tyle, side); 226 const NamedGridLinesMap& gridLineNames = gridLinesForSide(gridContainerS tyle, side);
187 NamedGridLinesMap::const_iterator implicitLineIter = gridLineNames.find( implicitNamedGridLineForSide(namedGridLine, side)); 227 NamedGridLinesMap::const_iterator implicitLineIter = gridLineNames.find( implicitNamedGridLineForSide(namedGridLine, side));
188 if (implicitLineIter != gridLineNames.end()) 228 if (implicitLineIter != gridLineNames.end())
189 return adjustGridPositionForSide(implicitLineIter->value[0], side); 229 return adjustGridPositionForSide(implicitLineIter->value[0], side);
190 230
191 // Otherwise, if there is a named line with the specified name, contribu tes the first such line to the grid 231 // Otherwise, if there is a named line with the specified name, contribu tes the first such line to the grid
192 // item's placement. 232 // item's placement.
193 NamedGridLinesMap::const_iterator explicitLineIter = gridLineNames.find( namedGridLine); 233 NamedGridLinesMap::const_iterator explicitLineIter = gridLineNames.find( namedGridLine);
194 if (explicitLineIter != gridLineNames.end()) 234 if (explicitLineIter != gridLineNames.end())
195 return adjustGridPositionForSide(explicitLineIter->value[0], side); 235 return adjustGridPositionForSide(explicitLineIter->value[0], side);
196 236
197 // If none of the above works specs mandate us to treat it as auto BUT w e should have detected it before calling 237 // If none of the above works specs mandate us to treat it as auto BUT w e should have detected it before calling
198 // this function in GridResolvedPosition::resolveGridPositionsFromStyle( ). We should be also covered by the 238 // this function in GridResolvedPosition::resolveGridPositionsFromStyle( ). We should be also covered by the
199 // ASSERT at the beginning of this block. 239 // ASSERT at the beginning of this block.
200 ASSERT_NOT_REACHED(); 240 ASSERT_NOT_REACHED();
201 return GridResolvedPosition(0); 241 return GridResolvedPosition(0);
202 } 242 }
203 case AutoPosition: 243 case AutoPosition:
204 case SpanPosition: 244 case SpanPosition:
205 // 'auto' and span depend on the opposite position for resolution (e.g. grid-row: auto / 1 or grid-column: span 3 / "myHeader"). 245 // 'auto' and span depend on the opposite position for resolution (e.g. grid-row: auto / 1 or grid-column: span 3 / "myHeader").
206 ASSERT_NOT_REACHED(); 246 ASSERT_NOT_REACHED();
207 return GridResolvedPosition(0); 247 return GridResolvedPosition(0);
208 } 248 }
209 ASSERT_NOT_REACHED(); 249 ASSERT_NOT_REACHED();
210 return GridResolvedPosition(0); 250 return GridResolvedPosition(0);
211 } 251 }
212 252
213 PassOwnPtr<GridSpan> GridResolvedPosition::resolveGridPositionAgainstOppositePos ition(const ComputedStyle& gridContainerStyle, const GridResolvedPosition& resol vedOppositePosition, const GridPosition& position, GridPositionSide side) 253 GridSpan GridResolvedPosition::resolveGridPositionsFromStyle(const GridUnresolve dSpan& unresolvedSpan, const ComputedStyle& gridContainerStyle)
214 { 254 {
215 if (position.isAuto()) 255 ASSERT(!unresolvedSpan.requiresAutoPlacement());
216 return GridSpan::create(resolvedOppositePosition, resolvedOppositePositi on);
217 256
218 ASSERT(position.isSpan()); 257 if (unresolvedSpan.initialPosition().shouldBeResolvedAgainstOppositePosition ()) {
219 ASSERT(position.spanPosition() > 0); 258 // Infer the position from the final position ('auto / 1' or 'span 2 / 3 ' case).
220 259 auto finalResolvedPosition = resolveGridPositionFromStyle(gridContainerS tyle, unresolvedSpan.finalPosition(), unresolvedSpan.finalPositionSide());
221 if (!position.namedGridLine().isNull()) { 260 return resolveGridPositionAgainstOppositePosition(gridContainerStyle, fi nalResolvedPosition, unresolvedSpan.initialPosition(), unresolvedSpan.initialPos itionSide());
222 // span 2 'c' -> we need to find the appropriate grid line before / afte r our opposite position.
223 return resolveNamedGridLinePositionAgainstOppositePosition(gridContainer Style, resolvedOppositePosition, position, side);
224 } 261 }
225 262
226 return GridSpan::createWithSpanAgainstOpposite(resolvedOppositePosition, pos ition, side); 263 if (unresolvedSpan.finalPosition().shouldBeResolvedAgainstOppositePosition() ) {
264 // Infer our position from the initial position ('1 / auto' or '3 / span 2' case).
265 auto initialResolvedPosition = resolveGridPositionFromStyle(gridContaine rStyle, unresolvedSpan.initialPosition(), unresolvedSpan.initialPositionSide());
266 return resolveGridPositionAgainstOppositePosition(gridContainerStyle, in itialResolvedPosition, unresolvedSpan.finalPosition(), unresolvedSpan.finalPosit ionSide());
267 }
268
269 auto resolvedInitialPosition = resolveGridPositionFromStyle(gridContainerSty le, unresolvedSpan.initialPosition(), unresolvedSpan.initialPositionSide());
270 auto resolvedFinalPosition = resolveGridPositionFromStyle(gridContainerStyle , unresolvedSpan.finalPosition(), unresolvedSpan.finalPositionSide());
271
272 // If 'grid-row-end' specifies a line at or before that specified by 'grid-r ow-start', it computes to 'span 1'.
273 return GridSpan(resolvedInitialPosition, std::max(resolvedInitialPosition, r esolvedFinalPosition));
227 } 274 }
228 275
229 PassOwnPtr<GridSpan> GridResolvedPosition::resolveNamedGridLinePositionAgainstOp positePosition(const ComputedStyle& gridContainerStyle, const GridResolvedPositi on& resolvedOppositePosition, const GridPosition& position, GridPositionSide sid e) 276 size_t GridResolvedPosition::explicitGridColumnCount(const ComputedStyle& gridCo ntainerStyle)
277 {
278 return std::min(gridContainerStyle.gridTemplateColumns().size(), kGridMaxTra cks);
279 }
280
281 size_t GridResolvedPosition::explicitGridRowCount(const ComputedStyle& gridConta inerStyle)
282 {
283 return std::min(gridContainerStyle.gridTemplateRows().size(), kGridMaxTracks );
284 }
285
286 static inline size_t firstNamedGridLineBeforePosition(size_t position, const Vec tor<size_t>& gridLines)
287 {
288 // The grid line inequality needs to be strict (which doesn't match the afte r / end case) because |position| is
289 // already converted to an index in our grid representation (ie one was remo ved from the grid line to account for
290 // the side).
291 size_t firstLineBeforePositionIndex = 0;
292 auto firstLineBeforePosition = std::lower_bound(gridLines.begin(), gridLines .end(), position);
293 if (firstLineBeforePosition != gridLines.end()) {
294 if (*firstLineBeforePosition > position && firstLineBeforePosition != gr idLines.begin())
295 --firstLineBeforePosition;
296
297 firstLineBeforePositionIndex = firstLineBeforePosition - gridLines.begin ();
298 }
299 return firstLineBeforePositionIndex;
300 }
301
302 static GridSpan resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePo sition(const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, const Vector<size_t>& gridLines)
303 {
304 size_t gridLineIndex = std::max<int>(0, firstNamedGridLineBeforePosition(res olvedOppositePosition.toInt(), gridLines) - position.spanPosition() + 1);
305 GridResolvedPosition resolvedGridLinePosition = GridResolvedPosition(gridLin es[gridLineIndex]);
306 return GridSpan(std::min(resolvedGridLinePosition, resolvedOppositePosition) , resolvedOppositePosition);
307 }
308
309 static GridSpan resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePositi on(const GridResolvedPosition& resolvedOppositePosition, const GridPosition& pos ition, const Vector<size_t>& gridLines)
310 {
311 ASSERT(gridLines.size());
312 size_t firstLineAfterOppositePositionIndex = gridLines.size() - 1;
313 const auto firstLineAfterOppositePosition = std::upper_bound(gridLines.begin (), gridLines.end(), resolvedOppositePosition);
314 if (firstLineAfterOppositePosition != gridLines.end())
315 firstLineAfterOppositePositionIndex = firstLineAfterOppositePosition - g ridLines.begin();
316
317 size_t gridLineIndex = std::min<size_t>(gridLines.size() - 1, firstLineAfter OppositePositionIndex + position.spanPosition() - 1);
318 GridResolvedPosition resolvedGridLinePosition = adjustGridPositionForRowEndC olumnEndSide(gridLines[gridLineIndex]);
319 if (resolvedGridLinePosition < resolvedOppositePosition)
320 resolvedGridLinePosition = resolvedOppositePosition;
321 return GridSpan(resolvedOppositePosition, resolvedGridLinePosition);
322 }
323
324 static GridSpan resolveNamedGridLinePositionAgainstOppositePosition(const Comput edStyle& gridContainerStyle, const GridResolvedPosition& resolvedOppositePositio n, const GridPosition& position, GridPositionSide side)
230 { 325 {
231 ASSERT(position.isSpan()); 326 ASSERT(position.isSpan());
232 ASSERT(!position.namedGridLine().isNull()); 327 ASSERT(!position.namedGridLine().isNull());
233 // Negative positions are not allowed per the specification and should have been handled during parsing. 328 // Negative positions are not allowed per the specification and should have been handled during parsing.
234 ASSERT(position.spanPosition() > 0); 329 ASSERT(position.spanPosition() > 0);
235 330
236 const NamedGridLinesMap& gridLinesNames = gridLinesForSide(gridContainerStyl e, side); 331 const NamedGridLinesMap& gridLinesNames = gridLinesForSide(gridContainerStyl e, side);
237 NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGri dLine()); 332 NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGri dLine());
238 333
239 // If there is no named grid line of that name, we resolve the position to ' auto' (which is equivalent to 'span 1' in this case). 334 // If there is no named grid line of that name, we resolve the position to ' auto' (which is equivalent to 'span 1' in this case).
240 // See http://lists.w3.org/Archives/Public/www-style/2013Jun/0394.html. 335 // See http://lists.w3.org/Archives/Public/www-style/2013Jun/0394.html.
241 if (it == gridLinesNames.end()) 336 if (it == gridLinesNames.end())
242 return GridSpan::create(resolvedOppositePosition, resolvedOppositePositi on); 337 return GridSpan(resolvedOppositePosition, resolvedOppositePosition);
243 338
244 return GridSpan::createWithNamedSpanAgainstOpposite(resolvedOppositePosition , position, side, it->value); 339 if (side == RowStartSide || side == ColumnStartSide)
340 return resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePos ition(resolvedOppositePosition, position, it->value);
341
342 return resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition(re solvedOppositePosition, position, it->value);
343 }
344
345 GridUnresolvedSpan GridResolvedPosition::unresolvedSpanFromStyle(const ComputedS tyle& gridContainerStyle, const LayoutBox& gridItem, GridTrackSizingDirection di rection)
346 {
347 const ComputedStyle& itemStyle = gridItem.styleRef();
348 if (direction == ForColumns) {
349 GridUnresolvedSpan unresolvedSpan(itemStyle.gridColumnStart(), ColumnSta rtSide, itemStyle.gridColumnEnd(), ColumnEndSide);
350 return unresolvedSpan.adjustGridPositionsFromStyle(gridContainerStyle);
351 }
352
353 GridUnresolvedSpan unresolvedSpan(itemStyle.gridRowStart(), RowStartSide, it emStyle.gridRowEnd(), RowEndSide);
354 return unresolvedSpan.adjustGridPositionsFromStyle(gridContainerStyle);
245 } 355 }
246 356
247 } // namespace blink 357 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698