Chromium Code Reviews| 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 "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); | |
|
rune
2015/11/11 18:16:51
Why did you need to declare this? Couldn't you jus
| |
| 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 | |
| 23 bool GridResolvedPosition::isValidNamedLineOrArea(const String& lineName, const ComputedStyle& style, GridPositionSide side) | 91 bool GridResolvedPosition::isValidNamedLineOrArea(const String& lineName, const ComputedStyle& style, GridPositionSide side) |
| 24 { | 92 { |
| 25 const NamedGridLinesMap& gridLineNames = gridLinesForSide(style, side); | 93 const NamedGridLinesMap& gridLineNames = gridLinesForSide(style, side); |
| 26 | 94 |
| 27 return gridLineNames.contains(implicitNamedGridLineForSide(lineName, side)) || gridLineNames.contains(lineName); | 95 return gridLineNames.contains(implicitNamedGridLineForSide(lineName, side)) || gridLineNames.contains(lineName); |
| 28 } | 96 } |
| 29 | 97 |
| 30 GridPositionSide GridResolvedPosition::initialPositionSide(GridTrackSizingDirect ion direction) | 98 static void initialAndFinalPositionsFromStyle(const ComputedStyle& gridContainer Style, const LayoutBox& gridItem, GridTrackSizingDirection direction, GridPositi on& initialPosition, GridPosition& finalPosition) |
| 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) | |
| 41 { | 99 { |
| 42 initialPosition = (direction == ForColumns) ? gridItem.style()->gridColumnSt art() : gridItem.style()->gridRowStart(); | 100 initialPosition = (direction == ForColumns) ? gridItem.style()->gridColumnSt art() : gridItem.style()->gridRowStart(); |
| 43 finalPosition = (direction == ForColumns) ? gridItem.style()->gridColumnEnd( ) : gridItem.style()->gridRowEnd(); | 101 finalPosition = (direction == ForColumns) ? gridItem.style()->gridColumnEnd( ) : gridItem.style()->gridRowEnd(); |
| 44 | 102 |
| 45 // We must handle the placement error handling code here instead of in the S tyleAdjuster because we don't want to | 103 // 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. | 104 // overwrite the specified values. |
| 47 if (initialPosition.isSpan() && finalPosition.isSpan()) | 105 if (initialPosition.isSpan() && finalPosition.isSpan()) |
| 48 finalPosition.setAutoPosition(); | 106 finalPosition.setAutoPosition(); |
| 49 | 107 |
| 50 // Try to early detect the case of non existing named grid lines. This way w e could assume later that | 108 // 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. | 109 // GridResolvedPosition::resolveGrisPositionFromStyle() always return a vali d resolved position. |
| 52 if (initialPosition.isNamedGridArea() && !isValidNamedLineOrArea(initialPosi tion.namedGridLine(), gridContainerStyle, initialPositionSide(direction))) | 110 if (initialPosition.isNamedGridArea() && !GridResolvedPosition::isValidNamed LineOrArea(initialPosition.namedGridLine(), gridContainerStyle, initialPositionS ide(direction))) |
| 53 initialPosition.setAutoPosition(); | 111 initialPosition.setAutoPosition(); |
| 54 | 112 |
| 55 if (finalPosition.isNamedGridArea() && !isValidNamedLineOrArea(finalPosition .namedGridLine(), gridContainerStyle, finalPositionSide(direction))) | 113 if (finalPosition.isNamedGridArea() && !GridResolvedPosition::isValidNamedLi neOrArea(finalPosition.namedGridLine(), gridContainerStyle, finalPositionSide(di rection))) |
| 56 finalPosition.setAutoPosition(); | 114 finalPosition.setAutoPosition(); |
| 57 | 115 |
| 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. | 116 // 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()) | 117 if (initialPosition.isAuto() && finalPosition.isSpan() && !finalPosition.nam edGridLine().isNull()) |
| 60 finalPosition.setSpanPosition(1, String()); | 118 finalPosition.setSpanPosition(1, String()); |
| 61 if (finalPosition.isAuto() && initialPosition.isSpan() && !initialPosition.n amedGridLine().isNull()) | 119 if (finalPosition.isAuto() && initialPosition.isSpan() && !initialPosition.n amedGridLine().isNull()) |
| 62 initialPosition.setSpanPosition(1, String()); | 120 initialPosition.setSpanPosition(1, String()); |
| 63 } | 121 } |
| 64 | 122 |
| 123 static GridSpan resolveGridPositionAgainstOppositePosition(const ComputedStyle& gridContainerStyle, const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, GridPositionSide side) | |
| 124 { | |
| 125 if (position.isAuto()) | |
| 126 return GridSpan(resolvedOppositePosition, resolvedOppositePosition); | |
| 127 | |
| 128 ASSERT(position.isSpan()); | |
| 129 ASSERT(position.spanPosition() > 0); | |
| 130 | |
| 131 if (!position.namedGridLine().isNull()) { | |
| 132 // span 2 'c' -> we need to find the appropriate grid line before / afte r our opposite position. | |
| 133 return resolveNamedGridLinePositionAgainstOppositePosition(gridContainer Style, resolvedOppositePosition, position, side); | |
| 134 } | |
| 135 | |
| 136 // 'span 1' is contained inside a single grid track regardless of the direct ion. | |
| 137 // That's why the CSS span value is one more than the offset we apply. | |
| 138 size_t positionOffset = position.spanPosition() - 1; | |
| 139 if (side == ColumnStartSide || side == RowStartSide) { | |
| 140 size_t initialResolvedPosition = std::max<int>(0, resolvedOppositePositi on.toInt() - positionOffset); | |
| 141 return GridSpan(initialResolvedPosition, resolvedOppositePosition); | |
| 142 } | |
| 143 | |
| 144 return GridSpan(resolvedOppositePosition, resolvedOppositePosition.toInt() + positionOffset); | |
| 145 } | |
| 146 | |
| 65 GridSpan GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(con st ComputedStyle& gridContainerStyle, const LayoutBox& gridItem, GridTrackSizing Direction direction, const GridResolvedPosition& resolvedInitialPosition) | 147 GridSpan GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(con st ComputedStyle& gridContainerStyle, const LayoutBox& gridItem, GridTrackSizing Direction direction, const GridResolvedPosition& resolvedInitialPosition) |
| 66 { | 148 { |
| 67 GridPosition initialPosition, finalPosition; | 149 GridPosition initialPosition, finalPosition; |
| 68 initialAndFinalPositionsFromStyle(gridContainerStyle, gridItem, direction, i nitialPosition, finalPosition); | 150 initialAndFinalPositionsFromStyle(gridContainerStyle, gridItem, direction, i nitialPosition, finalPosition); |
| 69 | 151 |
| 70 GridPositionSide finalSide = finalPositionSide(direction); | 152 GridPositionSide finalSide = finalPositionSide(direction); |
| 71 | 153 |
| 72 // This method will only be used when both positions need to be resolved aga inst the opposite one. | 154 // 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()); | 155 ASSERT(initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPos ition.shouldBeResolvedAgainstOppositePosition()); |
| 74 | 156 |
| 75 GridResolvedPosition resolvedFinalPosition = resolvedInitialPosition; | 157 GridResolvedPosition resolvedFinalPosition = resolvedInitialPosition; |
| 76 | 158 |
| 77 if (initialPosition.isSpan()) | 159 if (initialPosition.isSpan()) |
| 78 return *resolveGridPositionAgainstOppositePosition(gridContainerStyle, r esolvedInitialPosition, initialPosition, finalSide); | 160 return resolveGridPositionAgainstOppositePosition(gridContainerStyle, re solvedInitialPosition, initialPosition, finalSide); |
| 79 if (finalPosition.isSpan()) | 161 if (finalPosition.isSpan()) |
| 80 return *resolveGridPositionAgainstOppositePosition(gridContainerStyle, r esolvedInitialPosition, finalPosition, finalSide); | 162 return resolveGridPositionAgainstOppositePosition(gridContainerStyle, re solvedInitialPosition, finalPosition, finalSide); |
| 81 | 163 |
| 82 return GridSpan(resolvedInitialPosition, resolvedFinalPosition); | 164 return GridSpan(resolvedInitialPosition, resolvedFinalPosition); |
| 83 } | 165 } |
| 84 | 166 |
| 85 PassOwnPtr<GridSpan> GridResolvedPosition::resolveGridPositionsFromStyle(const C omputedStyle& gridContainerStyle, const LayoutBox& gridItem, GridTrackSizingDire ction direction) | 167 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 { | 168 { |
| 137 ASSERT(!position.namedGridLine().isNull()); | 169 ASSERT(!position.namedGridLine().isNull()); |
| 138 | 170 |
| 139 const NamedGridLinesMap& gridLinesNames = gridLinesForSide(gridContainerStyl e, side); | 171 const NamedGridLinesMap& gridLinesNames = gridLinesForSide(gridContainerStyl e, side); |
| 140 NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGri dLine()); | 172 NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGri dLine()); |
| 141 if (it == gridLinesNames.end()) { | 173 if (it == gridLinesNames.end()) { |
| 142 if (position.isPositive()) | 174 if (position.isPositive()) |
| 143 return GridResolvedPosition(0); | 175 return GridResolvedPosition(0); |
| 144 const size_t lastLine = explicitGridSizeForSide(gridContainerStyle, side ); | 176 const size_t lastLine = explicitGridSizeForSide(gridContainerStyle, side ); |
| 145 return adjustGridPositionForSide(lastLine, side); | 177 return adjustGridPositionForSide(lastLine, side); |
| 146 } | 178 } |
| 147 | 179 |
| 148 size_t namedGridLineIndex; | 180 size_t namedGridLineIndex; |
| 149 if (position.isPositive()) | 181 if (position.isPositive()) |
| 150 namedGridLineIndex = std::min<size_t>(position.integerPosition(), it->va lue.size()) - 1; | 182 namedGridLineIndex = std::min<size_t>(position.integerPosition(), it->va lue.size()) - 1; |
| 151 else | 183 else |
| 152 namedGridLineIndex = std::max<int>(it->value.size() - abs(position.integ erPosition()), 0); | 184 namedGridLineIndex = std::max<int>(it->value.size() - abs(position.integ erPosition()), 0); |
| 153 return adjustGridPositionForSide(it->value[namedGridLineIndex], side); | 185 return adjustGridPositionForSide(it->value[namedGridLineIndex], side); |
| 154 } | 186 } |
| 155 | 187 |
| 156 GridResolvedPosition GridResolvedPosition::resolveGridPositionFromStyle(const Co mputedStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side) | 188 static GridResolvedPosition resolveGridPositionFromStyle(const ComputedStyle& gr idContainerStyle, const GridPosition& position, GridPositionSide side) |
| 157 { | 189 { |
| 158 switch (position.type()) { | 190 switch (position.type()) { |
| 159 case ExplicitPosition: { | 191 case ExplicitPosition: { |
| 160 ASSERT(position.integerPosition()); | 192 ASSERT(position.integerPosition()); |
| 161 | 193 |
| 162 if (!position.namedGridLine().isNull()) | 194 if (!position.namedGridLine().isNull()) |
| 163 return resolveNamedGridLinePositionFromStyle(gridContainerStyle, pos ition, side); | 195 return resolveNamedGridLinePositionFromStyle(gridContainerStyle, pos ition, side); |
| 164 | 196 |
| 165 // Handle <integer> explicit position. | 197 // Handle <integer> explicit position. |
| 166 if (position.isPositive()) | 198 if (position.isPositive()) |
| 167 return adjustGridPositionForSide(position.integerPosition() - 1, sid e); | 199 return adjustGridPositionForSide(position.integerPosition() - 1, sid e); |
| 168 | 200 |
| 169 size_t resolvedPosition = abs(position.integerPosition()) - 1; | 201 size_t resolvedPosition = abs(position.integerPosition()) - 1; |
| 170 const size_t endOfTrack = explicitGridSizeForSide(gridContainerStyle, si de); | 202 const size_t endOfTrack = explicitGridSizeForSide(gridContainerStyle, si de); |
| 171 | 203 |
| 172 // Per http://lists.w3.org/Archives/Public/www-style/2013Mar/0589.html, we clamp negative value to the first line. | 204 // Per http://lists.w3.org/Archives/Public/www-style/2013Mar/0589.html, we clamp negative value to the first line. |
| 173 if (endOfTrack < resolvedPosition) | 205 if (endOfTrack < resolvedPosition) |
| 174 return GridResolvedPosition(0); | 206 return GridResolvedPosition(0); |
| 175 | 207 |
| 176 return adjustGridPositionForSide(endOfTrack - resolvedPosition, side); | 208 return adjustGridPositionForSide(endOfTrack - resolvedPosition, side); |
| 177 } | 209 } |
| 178 case NamedGridAreaPosition: | 210 case NamedGridAreaPosition: |
| 179 { | 211 { |
| 180 // First attempt to match the grid area's edge to a named grid area: if there is a named line with the name | 212 // 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 | 213 // ''<custom-ident>-start (for grid-*-start) / <custom-ident>-end'' (for grid-*-end), contributes the first such |
| 182 // line to the grid item's placement. | 214 // line to the grid item's placement. |
| 183 String namedGridLine = position.namedGridLine(); | 215 String namedGridLine = position.namedGridLine(); |
| 184 ASSERT(isValidNamedLineOrArea(namedGridLine, gridContainerStyle, side)); | 216 ASSERT(GridResolvedPosition::isValidNamedLineOrArea(namedGridLine, gridC ontainerStyle, side)); |
| 185 | 217 |
| 186 const NamedGridLinesMap& gridLineNames = gridLinesForSide(gridContainerS tyle, side); | 218 const NamedGridLinesMap& gridLineNames = gridLinesForSide(gridContainerS tyle, side); |
| 187 NamedGridLinesMap::const_iterator implicitLineIter = gridLineNames.find( implicitNamedGridLineForSide(namedGridLine, side)); | 219 NamedGridLinesMap::const_iterator implicitLineIter = gridLineNames.find( implicitNamedGridLineForSide(namedGridLine, side)); |
| 188 if (implicitLineIter != gridLineNames.end()) | 220 if (implicitLineIter != gridLineNames.end()) |
| 189 return adjustGridPositionForSide(implicitLineIter->value[0], side); | 221 return adjustGridPositionForSide(implicitLineIter->value[0], side); |
| 190 | 222 |
| 191 // Otherwise, if there is a named line with the specified name, contribu tes the first such line to the grid | 223 // Otherwise, if there is a named line with the specified name, contribu tes the first such line to the grid |
| 192 // item's placement. | 224 // item's placement. |
| 193 NamedGridLinesMap::const_iterator explicitLineIter = gridLineNames.find( namedGridLine); | 225 NamedGridLinesMap::const_iterator explicitLineIter = gridLineNames.find( namedGridLine); |
| 194 if (explicitLineIter != gridLineNames.end()) | 226 if (explicitLineIter != gridLineNames.end()) |
| 195 return adjustGridPositionForSide(explicitLineIter->value[0], side); | 227 return adjustGridPositionForSide(explicitLineIter->value[0], side); |
| 196 | 228 |
| 197 // If none of the above works specs mandate us to treat it as auto BUT w e should have detected it before calling | 229 // 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 | 230 // this function in GridResolvedPosition::resolveGridPositionsFromStyle( ). We should be also covered by the |
| 199 // ASSERT at the beginning of this block. | 231 // ASSERT at the beginning of this block. |
| 200 ASSERT_NOT_REACHED(); | 232 ASSERT_NOT_REACHED(); |
| 201 return GridResolvedPosition(0); | 233 return GridResolvedPosition(0); |
| 202 } | 234 } |
| 203 case AutoPosition: | 235 case AutoPosition: |
| 204 case SpanPosition: | 236 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"). | 237 // '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(); | 238 ASSERT_NOT_REACHED(); |
| 207 return GridResolvedPosition(0); | 239 return GridResolvedPosition(0); |
| 208 } | 240 } |
| 209 ASSERT_NOT_REACHED(); | 241 ASSERT_NOT_REACHED(); |
| 210 return GridResolvedPosition(0); | 242 return GridResolvedPosition(0); |
| 211 } | 243 } |
| 212 | 244 |
| 213 PassOwnPtr<GridSpan> GridResolvedPosition::resolveGridPositionAgainstOppositePos ition(const ComputedStyle& gridContainerStyle, const GridResolvedPosition& resol vedOppositePosition, const GridPosition& position, GridPositionSide side) | 245 GridSpan GridResolvedPosition::resolveGridPositionsFromStyle(const GridUnresolve dSpan& unresolvedSpan, const ComputedStyle& gridContainerStyle) |
| 214 { | 246 { |
| 215 if (position.isAuto()) | 247 ASSERT(!unresolvedSpan.requiresAutoPlacement()); |
| 216 return GridSpan::create(resolvedOppositePosition, resolvedOppositePositi on); | |
| 217 | 248 |
| 218 ASSERT(position.isSpan()); | 249 if (unresolvedSpan.initialPosition().shouldBeResolvedAgainstOppositePosition ()) { |
| 219 ASSERT(position.spanPosition() > 0); | 250 // Infer the position from the final position ('auto / 1' or 'span 2 / 3 ' case). |
| 220 | 251 auto finalResolvedPosition = resolveGridPositionFromStyle(gridContainerS tyle, unresolvedSpan.finalPosition(), unresolvedSpan.finalPositionSide()); |
| 221 if (!position.namedGridLine().isNull()) { | 252 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 } | 253 } |
| 225 | 254 |
| 226 return GridSpan::createWithSpanAgainstOpposite(resolvedOppositePosition, pos ition, side); | 255 if (unresolvedSpan.finalPosition().shouldBeResolvedAgainstOppositePosition() ) { |
| 256 // Infer our position from the initial position ('1 / auto' or '3 / span 2' case). | |
| 257 auto initialResolvedPosition = resolveGridPositionFromStyle(gridContaine rStyle, unresolvedSpan.initialPosition(), unresolvedSpan.initialPositionSide()); | |
| 258 return resolveGridPositionAgainstOppositePosition(gridContainerStyle, in itialResolvedPosition, unresolvedSpan.finalPosition(), unresolvedSpan.finalPosit ionSide()); | |
| 259 } | |
| 260 | |
| 261 auto resolvedInitialPosition = resolveGridPositionFromStyle(gridContainerSty le, unresolvedSpan.initialPosition(), unresolvedSpan.initialPositionSide()); | |
| 262 auto resolvedFinalPosition = resolveGridPositionFromStyle(gridContainerStyle , unresolvedSpan.finalPosition(), unresolvedSpan.finalPositionSide()); | |
| 263 | |
| 264 // If 'grid-row-end' specifies a line at or before that specified by 'grid-r ow-start', it computes to 'span 1'. | |
| 265 return GridSpan(resolvedInitialPosition, std::max(resolvedInitialPosition, r esolvedFinalPosition)); | |
| 227 } | 266 } |
| 228 | 267 |
| 229 PassOwnPtr<GridSpan> GridResolvedPosition::resolveNamedGridLinePositionAgainstOp positePosition(const ComputedStyle& gridContainerStyle, const GridResolvedPositi on& resolvedOppositePosition, const GridPosition& position, GridPositionSide sid e) | 268 size_t GridResolvedPosition::explicitGridColumnCount(const ComputedStyle& gridCo ntainerStyle) |
| 269 { | |
| 270 return std::min(gridContainerStyle.gridTemplateColumns().size(), kGridMaxTra cks); | |
| 271 } | |
| 272 | |
| 273 size_t GridResolvedPosition::explicitGridRowCount(const ComputedStyle& gridConta inerStyle) | |
| 274 { | |
| 275 return std::min(gridContainerStyle.gridTemplateRows().size(), kGridMaxTracks ); | |
| 276 } | |
| 277 | |
| 278 static inline size_t firstNamedGridLineBeforePosition(size_t position, const Vec tor<size_t>& gridLines) | |
| 279 { | |
| 280 // The grid line inequality needs to be strict (which doesn't match the afte r / end case) because |position| is | |
| 281 // already converted to an index in our grid representation (ie one was remo ved from the grid line to account for | |
| 282 // the side). | |
| 283 size_t firstLineBeforePositionIndex = 0; | |
| 284 auto firstLineBeforePosition = std::lower_bound(gridLines.begin(), gridLines .end(), position); | |
| 285 if (firstLineBeforePosition != gridLines.end()) { | |
| 286 if (*firstLineBeforePosition > position && firstLineBeforePosition != gr idLines.begin()) | |
| 287 --firstLineBeforePosition; | |
| 288 | |
| 289 firstLineBeforePositionIndex = firstLineBeforePosition - gridLines.begin (); | |
| 290 } | |
| 291 return firstLineBeforePositionIndex; | |
| 292 } | |
| 293 | |
| 294 static GridSpan resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePo sition(const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, const Vector<size_t>& gridLines) | |
| 295 { | |
| 296 size_t gridLineIndex = std::max<int>(0, firstNamedGridLineBeforePosition(res olvedOppositePosition.toInt(), gridLines) - position.spanPosition() + 1); | |
| 297 GridResolvedPosition resolvedGridLinePosition = GridResolvedPosition(gridLin es[gridLineIndex]); | |
| 298 return GridSpan(std::min(resolvedGridLinePosition, resolvedOppositePosition) , resolvedOppositePosition); | |
| 299 } | |
| 300 | |
| 301 static GridSpan resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePositi on(const GridResolvedPosition& resolvedOppositePosition, const GridPosition& pos ition, const Vector<size_t>& gridLines) | |
| 302 { | |
| 303 ASSERT(gridLines.size()); | |
| 304 size_t firstLineAfterOppositePositionIndex = gridLines.size() - 1; | |
| 305 const auto firstLineAfterOppositePosition = std::upper_bound(gridLines.begin (), gridLines.end(), resolvedOppositePosition); | |
| 306 if (firstLineAfterOppositePosition != gridLines.end()) | |
| 307 firstLineAfterOppositePositionIndex = firstLineAfterOppositePosition - g ridLines.begin(); | |
| 308 | |
| 309 size_t gridLineIndex = std::min<size_t>(gridLines.size() - 1, firstLineAfter OppositePositionIndex + position.spanPosition() - 1); | |
| 310 GridResolvedPosition resolvedGridLinePosition = adjustGridPositionForRowEndC olumnEndSide(gridLines[gridLineIndex]); | |
| 311 if (resolvedGridLinePosition < resolvedOppositePosition) | |
| 312 resolvedGridLinePosition = resolvedOppositePosition; | |
| 313 return GridSpan(resolvedOppositePosition, resolvedGridLinePosition); | |
| 314 } | |
| 315 | |
| 316 static GridSpan resolveNamedGridLinePositionAgainstOppositePosition(const Comput edStyle& gridContainerStyle, const GridResolvedPosition& resolvedOppositePositio n, const GridPosition& position, GridPositionSide side) | |
| 230 { | 317 { |
| 231 ASSERT(position.isSpan()); | 318 ASSERT(position.isSpan()); |
| 232 ASSERT(!position.namedGridLine().isNull()); | 319 ASSERT(!position.namedGridLine().isNull()); |
| 233 // Negative positions are not allowed per the specification and should have been handled during parsing. | 320 // Negative positions are not allowed per the specification and should have been handled during parsing. |
| 234 ASSERT(position.spanPosition() > 0); | 321 ASSERT(position.spanPosition() > 0); |
| 235 | 322 |
| 236 const NamedGridLinesMap& gridLinesNames = gridLinesForSide(gridContainerStyl e, side); | 323 const NamedGridLinesMap& gridLinesNames = gridLinesForSide(gridContainerStyl e, side); |
| 237 NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGri dLine()); | 324 NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGri dLine()); |
| 238 | 325 |
| 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). | 326 // 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. | 327 // See http://lists.w3.org/Archives/Public/www-style/2013Jun/0394.html. |
| 241 if (it == gridLinesNames.end()) | 328 if (it == gridLinesNames.end()) |
| 242 return GridSpan::create(resolvedOppositePosition, resolvedOppositePositi on); | 329 return GridSpan(resolvedOppositePosition, resolvedOppositePosition); |
| 243 | 330 |
| 244 return GridSpan::createWithNamedSpanAgainstOpposite(resolvedOppositePosition , position, side, it->value); | 331 if (side == RowStartSide || side == ColumnStartSide) |
| 332 return resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePos ition(resolvedOppositePosition, position, it->value); | |
| 333 | |
| 334 return resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition(re solvedOppositePosition, position, it->value); | |
| 335 } | |
| 336 | |
| 337 GridUnresolvedSpan GridResolvedPosition::unresolvedSpanFromStyle(const ComputedS tyle& gridContainerStyle, const LayoutBox& gridItem, GridTrackSizingDirection di rection) | |
| 338 { | |
| 339 const ComputedStyle& itemStyle = gridItem.styleRef(); | |
| 340 if (direction == ForColumns) { | |
| 341 GridUnresolvedSpan unresolvedSpan(itemStyle.gridColumnStart(), ColumnSta rtSide, itemStyle.gridColumnEnd(), ColumnEndSide); | |
| 342 return unresolvedSpan.adjustGridPositionsFromStyle(gridContainerStyle); | |
|
rune
2015/11/11 18:16:51
I would make adjustGridPositionsFromStyle return v
| |
| 343 } | |
| 344 | |
| 345 GridUnresolvedSpan unresolvedSpan(itemStyle.gridRowStart(), RowStartSide, it emStyle.gridRowEnd(), RowEndSide); | |
| 346 return unresolvedSpan.adjustGridPositionsFromStyle(gridContainerStyle); | |
| 245 } | 347 } |
| 246 | 348 |
| 247 } // namespace blink | 349 } // namespace blink |
| OLD | NEW |