| 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 |