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

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

Issue 1424913009: [css-grid] Simplify the interface of GridResolvedPosition (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Patch for landing v2 Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/core/style/GridResolvedPosition.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 #include "core/style/GridResolvedPosition.h" 6 #include "core/style/GridResolvedPosition.h"
7 7
8 #include "core/layout/LayoutBox.h" 8 #include "core/layout/LayoutBox.h"
9 #include "core/style/GridCoordinate.h" 9 #include "core/style/GridCoordinate.h"
10 10
11 namespace blink { 11 namespace blink {
12 12
13 static GridSpan resolveNamedGridLinePositionAgainstOppositePosition(const Comput edStyle& gridContainerStyle, const GridResolvedPosition& resolvedOppositePositio n, const GridPosition&, GridPositionSide);
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
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/style/GridResolvedPosition.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698