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 |