OLD | NEW |
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 "core/style/GridResolvedPosition.h" | 5 #include "GridPositionsResolver.h" |
6 | 6 |
7 #include "core/layout/LayoutBox.h" | 7 #include "core/layout/LayoutBox.h" |
8 #include "core/style/GridCoordinate.h" | 8 #include "core/style/GridCoordinate.h" |
9 #include <algorithm> | 9 #include <algorithm> |
10 | 10 |
11 namespace blink { | 11 namespace blink { |
12 | 12 |
13 static const NamedGridLinesMap& gridLinesForSide(const ComputedStyle& style, Gri
dPositionSide side) | 13 static const NamedGridLinesMap& gridLinesForSide(const ComputedStyle& style, Gri
dPositionSide side) |
14 { | 14 { |
15 return (side == ColumnStartSide || side == ColumnEndSide) ? style.namedGridC
olumnLines() : style.namedGridRowLines(); | 15 return (side == ColumnStartSide || side == ColumnEndSide) ? style.namedGridC
olumnLines() : style.namedGridRowLines(); |
16 } | 16 } |
17 | 17 |
18 static inline String implicitNamedGridLineForSide(const String& lineName, GridPo
sitionSide side) | 18 static inline String implicitNamedGridLineForSide(const String& lineName, GridPo
sitionSide side) |
19 { | 19 { |
20 return lineName + ((side == ColumnStartSide || side == RowStartSide) ? "-sta
rt" : "-end"); | 20 return lineName + ((side == ColumnStartSide || side == RowStartSide) ? "-sta
rt" : "-end"); |
21 } | 21 } |
22 | 22 |
23 bool GridResolvedPosition::isValidNamedLineOrArea(const String& lineName, const
ComputedStyle& style, GridPositionSide side) | 23 bool GridPositionsResolver::isValidNamedLineOrArea(const String& lineName, const
ComputedStyle& style, GridPositionSide side) |
24 { | 24 { |
25 const NamedGridLinesMap& gridLineNames = gridLinesForSide(style, side); | 25 const NamedGridLinesMap& gridLineNames = gridLinesForSide(style, side); |
26 | 26 |
27 return gridLineNames.contains(implicitNamedGridLineForSide(lineName, side))
|| gridLineNames.contains(lineName); | 27 return gridLineNames.contains(implicitNamedGridLineForSide(lineName, side))
|| gridLineNames.contains(lineName); |
28 } | 28 } |
29 | 29 |
30 GridPositionSide GridResolvedPosition::initialPositionSide(GridTrackSizingDirect
ion direction) | 30 GridPositionSide GridPositionsResolver::initialPositionSide(GridTrackSizingDirec
tion direction) |
31 { | 31 { |
32 return (direction == ForColumns) ? ColumnStartSide : RowStartSide; | 32 return (direction == ForColumns) ? ColumnStartSide : RowStartSide; |
33 } | 33 } |
34 | 34 |
35 GridPositionSide GridResolvedPosition::finalPositionSide(GridTrackSizingDirectio
n direction) | 35 GridPositionSide GridPositionsResolver::finalPositionSide(GridTrackSizingDirecti
on direction) |
36 { | 36 { |
37 return (direction == ForColumns) ? ColumnEndSide : RowEndSide; | 37 return (direction == ForColumns) ? ColumnEndSide : RowEndSide; |
38 } | 38 } |
39 | 39 |
40 static void initialAndFinalPositionsFromStyle(const ComputedStyle& gridContainer
Style, const LayoutBox& gridItem, GridTrackSizingDirection direction, GridPositi
on& initialPosition, GridPosition& finalPosition) | 40 static void initialAndFinalPositionsFromStyle(const ComputedStyle& gridContainer
Style, const LayoutBox& gridItem, GridTrackSizingDirection direction, GridPositi
on& initialPosition, GridPosition& finalPosition) |
41 { | 41 { |
42 initialPosition = (direction == ForColumns) ? gridItem.style()->gridColumnSt
art() : gridItem.style()->gridRowStart(); | 42 initialPosition = (direction == ForColumns) ? gridItem.style()->gridColumnSt
art() : gridItem.style()->gridRowStart(); |
43 finalPosition = (direction == ForColumns) ? gridItem.style()->gridColumnEnd(
) : gridItem.style()->gridRowEnd(); | 43 finalPosition = (direction == ForColumns) ? gridItem.style()->gridColumnEnd(
) : gridItem.style()->gridRowEnd(); |
44 | 44 |
45 // We must handle the placement error handling code here instead of in the S
tyleAdjuster because we don't want to | 45 // 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. | 46 // overwrite the specified values. |
47 if (initialPosition.isSpan() && finalPosition.isSpan()) | 47 if (initialPosition.isSpan() && finalPosition.isSpan()) |
48 finalPosition.setAutoPosition(); | 48 finalPosition.setAutoPosition(); |
49 | 49 |
50 if (gridItem.isOutOfFlowPositioned()) { | 50 if (gridItem.isOutOfFlowPositioned()) { |
51 // Early detect the case of non existing named grid lines for positioned
items. | 51 // Early detect the case of non existing named grid lines for positioned
items. |
52 if (initialPosition.isNamedGridArea() && !GridResolvedPosition::isValidN
amedLineOrArea(initialPosition.namedGridLine(), gridContainerStyle, GridResolved
Position::initialPositionSide(direction))) | 52 if (initialPosition.isNamedGridArea() && !GridPositionsResolver::isValid
NamedLineOrArea(initialPosition.namedGridLine(), gridContainerStyle, GridPositio
nsResolver::initialPositionSide(direction))) |
53 initialPosition.setAutoPosition(); | 53 initialPosition.setAutoPosition(); |
54 | 54 |
55 if (finalPosition.isNamedGridArea() && !GridResolvedPosition::isValidNam
edLineOrArea(finalPosition.namedGridLine(), gridContainerStyle, GridResolvedPosi
tion::finalPositionSide(direction))) | 55 if (finalPosition.isNamedGridArea() && !GridPositionsResolver::isValidNa
medLineOrArea(finalPosition.namedGridLine(), gridContainerStyle, GridPositionsRe
solver::finalPositionSide(direction))) |
56 finalPosition.setAutoPosition(); | 56 finalPosition.setAutoPosition(); |
57 } | 57 } |
58 | 58 |
59 // 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 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. |
60 if (initialPosition.isAuto() && finalPosition.isSpan() && !finalPosition.nam
edGridLine().isNull()) | 60 if (initialPosition.isAuto() && finalPosition.isSpan() && !finalPosition.nam
edGridLine().isNull()) |
61 finalPosition.setSpanPosition(1, String()); | 61 finalPosition.setSpanPosition(1, String()); |
62 if (finalPosition.isAuto() && initialPosition.isSpan() && !initialPosition.n
amedGridLine().isNull()) | 62 if (finalPosition.isAuto() && initialPosition.isSpan() && !initialPosition.n
amedGridLine().isNull()) |
63 initialPosition.setSpanPosition(1, String()); | 63 initialPosition.setSpanPosition(1, String()); |
64 } | 64 } |
65 | 65 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 start = lookBackForNamedGridLine(resolvedOppositePosition - 1, position.
spanPosition(), gridLines, lastLine); | 114 start = lookBackForNamedGridLine(resolvedOppositePosition - 1, position.
spanPosition(), gridLines, lastLine); |
115 end = resolvedOppositePosition; | 115 end = resolvedOppositePosition; |
116 } else { | 116 } else { |
117 start = resolvedOppositePosition; | 117 start = resolvedOppositePosition; |
118 end = lookAheadForNamedGridLine(resolvedOppositePosition + 1, position.s
panPosition(), gridLines, lastLine); | 118 end = lookAheadForNamedGridLine(resolvedOppositePosition + 1, position.s
panPosition(), gridLines, lastLine); |
119 } | 119 } |
120 | 120 |
121 return GridSpan::untranslatedDefiniteGridSpan(start, end); | 121 return GridSpan::untranslatedDefiniteGridSpan(start, end); |
122 } | 122 } |
123 | 123 |
124 size_t GridResolvedPosition::explicitGridColumnCount(const ComputedStyle& gridCo
ntainerStyle) | 124 size_t GridPositionsResolver::explicitGridColumnCount(const ComputedStyle& gridC
ontainerStyle) |
125 { | 125 { |
126 return std::min<size_t>(gridContainerStyle.gridTemplateColumns().size(), kGr
idMaxTracks); | 126 return std::min<size_t>(gridContainerStyle.gridTemplateColumns().size(), kGr
idMaxTracks); |
127 } | 127 } |
128 | 128 |
129 size_t GridResolvedPosition::explicitGridRowCount(const ComputedStyle& gridConta
inerStyle) | 129 size_t GridPositionsResolver::explicitGridRowCount(const ComputedStyle& gridCont
ainerStyle) |
130 { | 130 { |
131 return std::min<size_t>(gridContainerStyle.gridTemplateRows().size(), kGridM
axTracks); | 131 return std::min<size_t>(gridContainerStyle.gridTemplateRows().size(), kGridM
axTracks); |
132 } | 132 } |
133 | 133 |
134 static size_t explicitGridSizeForSide(const ComputedStyle& gridContainerStyle, G
ridPositionSide side) | 134 static size_t explicitGridSizeForSide(const ComputedStyle& gridContainerStyle, G
ridPositionSide side) |
135 { | 135 { |
136 return (side == ColumnStartSide || side == ColumnEndSide) ? GridResolvedPosi
tion::explicitGridColumnCount(gridContainerStyle) : GridResolvedPosition::explic
itGridRowCount(gridContainerStyle); | 136 return (side == ColumnStartSide || side == ColumnEndSide) ? GridPositionsRes
olver::explicitGridColumnCount(gridContainerStyle) : GridPositionsResolver::expl
icitGridRowCount(gridContainerStyle); |
137 } | 137 } |
138 | 138 |
139 static GridSpan resolveNamedGridLinePositionAgainstOppositePosition(const Comput
edStyle& gridContainerStyle, int resolvedOppositePosition, const GridPosition& p
osition, GridPositionSide side) | 139 static GridSpan resolveNamedGridLinePositionAgainstOppositePosition(const Comput
edStyle& gridContainerStyle, int resolvedOppositePosition, const GridPosition& p
osition, GridPositionSide side) |
140 { | 140 { |
141 ASSERT(position.isSpan()); | 141 ASSERT(position.isSpan()); |
142 ASSERT(!position.namedGridLine().isNull()); | 142 ASSERT(!position.namedGridLine().isNull()); |
143 // Negative positions are not allowed per the specification and should have
been handled during parsing. | 143 // Negative positions are not allowed per the specification and should have
been handled during parsing. |
144 ASSERT(position.spanPosition() > 0); | 144 ASSERT(position.spanPosition() > 0); |
145 | 145 |
146 const NamedGridLinesMap& gridLinesNames = gridLinesForSide(gridContainerStyl
e, side); | 146 const NamedGridLinesMap& gridLinesNames = gridLinesForSide(gridContainerStyl
e, side); |
(...skipping 24 matching lines...) Expand all Loading... |
171 ASSERT(position.spanPosition() > 0); | 171 ASSERT(position.spanPosition() > 0); |
172 | 172 |
173 if (!position.namedGridLine().isNull()) { | 173 if (!position.namedGridLine().isNull()) { |
174 // span 2 'c' -> we need to find the appropriate grid line before / afte
r our opposite position. | 174 // span 2 'c' -> we need to find the appropriate grid line before / afte
r our opposite position. |
175 return resolveNamedGridLinePositionAgainstOppositePosition(gridContainer
Style, resolvedOppositePosition, position, side); | 175 return resolveNamedGridLinePositionAgainstOppositePosition(gridContainer
Style, resolvedOppositePosition, position, side); |
176 } | 176 } |
177 | 177 |
178 return definiteGridSpanWithSpanAgainstOpposite(resolvedOppositePosition, pos
ition, side); | 178 return definiteGridSpanWithSpanAgainstOpposite(resolvedOppositePosition, pos
ition, side); |
179 } | 179 } |
180 | 180 |
181 size_t GridResolvedPosition::spanSizeForAutoPlacedItem(const ComputedStyle& grid
ContainerStyle, const LayoutBox& gridItem, GridTrackSizingDirection direction) | 181 size_t GridPositionsResolver::spanSizeForAutoPlacedItem(const ComputedStyle& gri
dContainerStyle, const LayoutBox& gridItem, GridTrackSizingDirection direction) |
182 { | 182 { |
183 GridPosition initialPosition, finalPosition; | 183 GridPosition initialPosition, finalPosition; |
184 initialAndFinalPositionsFromStyle(gridContainerStyle, gridItem, direction, i
nitialPosition, finalPosition); | 184 initialAndFinalPositionsFromStyle(gridContainerStyle, gridItem, direction, i
nitialPosition, finalPosition); |
185 | 185 |
186 // This method will only be used when both positions need to be resolved aga
inst the opposite one. | 186 // This method will only be used when both positions need to be resolved aga
inst the opposite one. |
187 ASSERT(initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPos
ition.shouldBeResolvedAgainstOppositePosition()); | 187 ASSERT(initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPos
ition.shouldBeResolvedAgainstOppositePosition()); |
188 | 188 |
189 if (initialPosition.isAuto() && finalPosition.isAuto()) | 189 if (initialPosition.isAuto() && finalPosition.isAuto()) |
190 return 1; | 190 return 1; |
191 | 191 |
192 GridPosition position = initialPosition.isSpan() ? initialPosition : finalPo
sition; | 192 GridPosition position = initialPosition.isSpan() ? initialPosition : finalPo
sition; |
193 ASSERT(position.isSpan()); | 193 ASSERT(position.isSpan()); |
194 ASSERT(position.spanPosition()); | 194 ASSERT(position.spanPosition()); |
195 return position.spanPosition(); | 195 return position.spanPosition(); |
196 } | 196 } |
197 | 197 |
198 static int resolveNamedGridLinePositionFromStyle(const ComputedStyle& gridContai
nerStyle, const GridPosition& position, GridPositionSide side) | 198 static int resolveNamedGridLinePositionFromStyle(const ComputedStyle& gridContai
nerStyle, const GridPosition& position, GridPositionSide side) |
199 { | 199 { |
200 ASSERT(!position.namedGridLine().isNull()); | 200 ASSERT(!position.namedGridLine().isNull()); |
201 | 201 |
202 const NamedGridLinesMap& gridLinesNames = gridLinesForSide(gridContainerStyl
e, side); | 202 const NamedGridLinesMap& gridLinesNames = gridLinesForSide(gridContainerStyl
e, side); |
203 NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGri
dLine()); | 203 NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGri
dLine()); |
204 const Vector<size_t>* gridLines = it == gridLinesNames.end() ? nullptr : &it
->value; | 204 const Vector<size_t>* gridLines = it == gridLinesNames.end() ? nullptr : &it
->value; |
205 size_t lastLine = explicitGridSizeForSide(gridContainerStyle, side); | 205 size_t lastLine = explicitGridSizeForSide(gridContainerStyle, side); |
206 if (position.isPositive()) | 206 if (position.isPositive()) |
207 return lookAheadForNamedGridLine(0, abs(position.integerPosition()), gri
dLines, lastLine); | 207 return lookAheadForNamedGridLine(0, abs(position.integerPosition()), gri
dLines, lastLine); |
208 else | 208 |
209 return lookBackForNamedGridLine(lastLine, abs(position.integerPosition()
), gridLines, lastLine); | 209 return lookBackForNamedGridLine(lastLine, abs(position.integerPosition()), g
ridLines, lastLine); |
210 } | 210 } |
211 | 211 |
212 static int resolveGridPositionFromStyle(const ComputedStyle& gridContainerStyle,
const GridPosition& position, GridPositionSide side) | 212 static int resolveGridPositionFromStyle(const ComputedStyle& gridContainerStyle,
const GridPosition& position, GridPositionSide side) |
213 { | 213 { |
214 switch (position.type()) { | 214 switch (position.type()) { |
215 case ExplicitPosition: { | 215 case ExplicitPosition: { |
216 ASSERT(position.integerPosition()); | 216 ASSERT(position.integerPosition()); |
217 | 217 |
218 if (!position.namedGridLine().isNull()) | 218 if (!position.namedGridLine().isNull()) |
219 return resolveNamedGridLinePositionFromStyle(gridContainerStyle, pos
ition, side); | 219 return resolveNamedGridLinePositionFromStyle(gridContainerStyle, pos
ition, side); |
(...skipping 19 matching lines...) Expand all Loading... |
239 NamedGridLinesMap::const_iterator implicitLineIter = gridLineNames.find(
implicitNamedGridLineForSide(namedGridLine, side)); | 239 NamedGridLinesMap::const_iterator implicitLineIter = gridLineNames.find(
implicitNamedGridLineForSide(namedGridLine, side)); |
240 if (implicitLineIter != gridLineNames.end()) | 240 if (implicitLineIter != gridLineNames.end()) |
241 return implicitLineIter->value[0]; | 241 return implicitLineIter->value[0]; |
242 | 242 |
243 // Otherwise, if there is a named line with the specified name, contribu
tes the first such line to the grid | 243 // Otherwise, if there is a named line with the specified name, contribu
tes the first such line to the grid |
244 // item's placement. | 244 // item's placement. |
245 NamedGridLinesMap::const_iterator explicitLineIter = gridLineNames.find(
namedGridLine); | 245 NamedGridLinesMap::const_iterator explicitLineIter = gridLineNames.find(
namedGridLine); |
246 if (explicitLineIter != gridLineNames.end()) | 246 if (explicitLineIter != gridLineNames.end()) |
247 return explicitLineIter->value[0]; | 247 return explicitLineIter->value[0]; |
248 | 248 |
249 ASSERT(!GridResolvedPosition::isValidNamedLineOrArea(namedGridLine, grid
ContainerStyle, side)); | 249 ASSERT(!GridPositionsResolver::isValidNamedLineOrArea(namedGridLine, gri
dContainerStyle, side)); |
250 // If none of the above works specs mandate to assume that all the lines
in the implicit grid have this name. | 250 // If none of the above works specs mandate to assume that all the lines
in the implicit grid have this name. |
251 size_t lastLine = explicitGridSizeForSide(gridContainerStyle, side); | 251 size_t lastLine = explicitGridSizeForSide(gridContainerStyle, side); |
252 return lastLine + 1; | 252 return lastLine + 1; |
253 } | 253 } |
254 case AutoPosition: | 254 case AutoPosition: |
255 case SpanPosition: | 255 case SpanPosition: |
256 // 'auto' and span depend on the opposite position for resolution (e.g.
grid-row: auto / 1 or grid-column: span 3 / "myHeader"). | 256 // 'auto' and span depend on the opposite position for resolution (e.g.
grid-row: auto / 1 or grid-column: span 3 / "myHeader"). |
257 ASSERT_NOT_REACHED(); | 257 ASSERT_NOT_REACHED(); |
258 return 0; | 258 return 0; |
259 } | 259 } |
260 ASSERT_NOT_REACHED(); | 260 ASSERT_NOT_REACHED(); |
261 return 0; | 261 return 0; |
262 } | 262 } |
263 | 263 |
264 GridSpan GridResolvedPosition::resolveGridPositionsFromStyle(const ComputedStyle
& gridContainerStyle, const LayoutBox& gridItem, GridTrackSizingDirection direct
ion) | 264 GridSpan GridPositionsResolver::resolveGridPositionsFromStyle(const ComputedStyl
e& gridContainerStyle, const LayoutBox& gridItem, GridTrackSizingDirection direc
tion) |
265 { | 265 { |
266 GridPosition initialPosition, finalPosition; | 266 GridPosition initialPosition, finalPosition; |
267 initialAndFinalPositionsFromStyle(gridContainerStyle, gridItem, direction, i
nitialPosition, finalPosition); | 267 initialAndFinalPositionsFromStyle(gridContainerStyle, gridItem, direction, i
nitialPosition, finalPosition); |
268 | 268 |
269 GridPositionSide initialSide = initialPositionSide(direction); | 269 GridPositionSide initialSide = initialPositionSide(direction); |
270 GridPositionSide finalSide = finalPositionSide(direction); | 270 GridPositionSide finalSide = finalPositionSide(direction); |
271 | 271 |
272 if (initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPositi
on.shouldBeResolvedAgainstOppositePosition()) { | 272 if (initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPositi
on.shouldBeResolvedAgainstOppositePosition()) { |
273 // We can't get our grid positions without running the auto placement al
gorithm. | 273 // We can't get our grid positions without running the auto placement al
gorithm. |
274 return GridSpan::indefiniteGridSpan(); | 274 return GridSpan::indefiniteGridSpan(); |
(...skipping 16 matching lines...) Expand all Loading... |
291 | 291 |
292 if (resolvedFinalPosition < resolvedInitialPosition) | 292 if (resolvedFinalPosition < resolvedInitialPosition) |
293 std::swap(resolvedFinalPosition, resolvedInitialPosition); | 293 std::swap(resolvedFinalPosition, resolvedInitialPosition); |
294 else if (resolvedFinalPosition == resolvedInitialPosition) | 294 else if (resolvedFinalPosition == resolvedInitialPosition) |
295 resolvedFinalPosition = resolvedInitialPosition + 1; | 295 resolvedFinalPosition = resolvedInitialPosition + 1; |
296 | 296 |
297 return GridSpan::untranslatedDefiniteGridSpan(resolvedInitialPosition, resol
vedFinalPosition); | 297 return GridSpan::untranslatedDefiniteGridSpan(resolvedInitialPosition, resol
vedFinalPosition); |
298 } | 298 } |
299 | 299 |
300 } // namespace blink | 300 } // namespace blink |
OLD | NEW |