OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "config.h" |
| 6 #include "core/rendering/style/GridResolvedPosition.h" |
| 7 |
| 8 #include "core/rendering/RenderBox.h" |
| 9 #include "core/rendering/style/GridCoordinate.h" |
| 10 |
| 11 namespace WebCore { |
| 12 |
| 13 GridSpan GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(con
st RenderBox&, GridTrackSizingDirection, const GridResolvedPosition& initialPosi
tion) |
| 14 { |
| 15 // FIXME: We don't support spanning with auto positions yet. Once we do, thi
s is wrong. Also we should make |
| 16 // sure the grid can accomodate the new item as we only grow 1 position in a
given direction. |
| 17 return GridSpan(initialPosition, initialPosition); |
| 18 } |
| 19 |
| 20 PassOwnPtr<GridSpan> GridResolvedPosition::resolveGridPositionsFromStyle(const R
enderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirect
ion direction) |
| 21 { |
| 22 GridPosition initialPosition = (direction == ForColumns) ? gridItem.style()-
>gridColumnStart() : gridItem.style()->gridRowStart(); |
| 23 const GridPositionSide initialPositionSide = (direction == ForColumns) ? Col
umnStartSide : RowStartSide; |
| 24 GridPosition finalPosition = (direction == ForColumns) ? gridItem.style()->g
ridColumnEnd() : gridItem.style()->gridRowEnd(); |
| 25 const GridPositionSide finalPositionSide = (direction == ForColumns) ? Colum
nEndSide : RowEndSide; |
| 26 |
| 27 // We must handle the placement error handling code here instead of in the S
tyleAdjuster because we don't want to |
| 28 // overwrite the specified values. |
| 29 if (initialPosition.isSpan() && finalPosition.isSpan()) |
| 30 finalPosition.setAutoPosition(); |
| 31 |
| 32 if (initialPosition.isNamedGridArea() && !gridContainerStyle.namedGridArea()
.contains(initialPosition.namedGridLine())) |
| 33 initialPosition.setAutoPosition(); |
| 34 |
| 35 if (finalPosition.isNamedGridArea() && !gridContainerStyle.namedGridArea().c
ontains(finalPosition.namedGridLine())) |
| 36 finalPosition.setAutoPosition(); |
| 37 |
| 38 if (initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPositi
on.shouldBeResolvedAgainstOppositePosition()) { |
| 39 if (gridContainerStyle.gridAutoFlow() == AutoFlowNone) |
| 40 return adoptPtr(new GridSpan(0, 0)); |
| 41 |
| 42 // We can't get our grid positions without running the auto placement al
gorithm. |
| 43 return nullptr; |
| 44 } |
| 45 |
| 46 if (initialPosition.shouldBeResolvedAgainstOppositePosition()) { |
| 47 // Infer the position from the final position ('auto / 1' or 'span 2 / 3
' case). |
| 48 GridResolvedPosition finalResolvedPosition = resolveGridPositionFromStyl
e(gridContainerStyle, finalPosition, finalPositionSide); |
| 49 return resolveGridPositionAgainstOppositePosition(gridContainerStyle, fi
nalResolvedPosition, initialPosition, initialPositionSide); |
| 50 } |
| 51 |
| 52 if (finalPosition.shouldBeResolvedAgainstOppositePosition()) { |
| 53 // Infer our position from the initial position ('1 / auto' or '3 / span
2' case). |
| 54 GridResolvedPosition initialResolvedPosition = resolveGridPositionFromSt
yle(gridContainerStyle, initialPosition, initialPositionSide); |
| 55 return resolveGridPositionAgainstOppositePosition(gridContainerStyle, in
itialResolvedPosition, finalPosition, finalPositionSide); |
| 56 } |
| 57 |
| 58 GridResolvedPosition resolvedInitialPosition = resolveGridPositionFromStyle(
gridContainerStyle, initialPosition, initialPositionSide); |
| 59 GridResolvedPosition resolvedFinalPosition = resolveGridPositionFromStyle(gr
idContainerStyle, finalPosition, finalPositionSide); |
| 60 |
| 61 // If 'grid-after' specifies a line at or before that specified by 'grid-bef
ore', it computes to 'span 1'. |
| 62 if (resolvedFinalPosition < resolvedInitialPosition) |
| 63 resolvedFinalPosition = resolvedInitialPosition; |
| 64 |
| 65 return adoptPtr(new GridSpan(resolvedInitialPosition, resolvedFinalPosition)
); |
| 66 } |
| 67 |
| 68 size_t GridResolvedPosition::explicitGridColumnCount(const RenderStyle& gridCont
ainerStyle) |
| 69 { |
| 70 return gridContainerStyle.gridTemplateColumns().size(); |
| 71 } |
| 72 |
| 73 size_t GridResolvedPosition::explicitGridRowCount(const RenderStyle& gridContain
erStyle) |
| 74 { |
| 75 return gridContainerStyle.gridTemplateRows().size(); |
| 76 } |
| 77 |
| 78 size_t GridResolvedPosition::explicitGridSizeForSide(const RenderStyle& gridCont
ainerStyle, GridPositionSide side) |
| 79 { |
| 80 return (side == ColumnStartSide || side == ColumnEndSide) ? explicitGridColu
mnCount(gridContainerStyle) : explicitGridRowCount(gridContainerStyle); |
| 81 } |
| 82 |
| 83 GridResolvedPosition GridResolvedPosition::resolveNamedGridLinePositionFromStyle
(const RenderStyle& gridContainerStyle, const GridPosition& position, GridPositi
onSide side) |
| 84 { |
| 85 ASSERT(!position.namedGridLine().isNull()); |
| 86 |
| 87 const NamedGridLinesMap& gridLinesNames = (side == ColumnStartSide || side =
= ColumnEndSide) ? gridContainerStyle.namedGridColumnLines() : gridContainerStyl
e.namedGridRowLines(); |
| 88 NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGri
dLine()); |
| 89 if (it == gridLinesNames.end()) { |
| 90 if (position.isPositive()) |
| 91 return GridResolvedPosition(0); |
| 92 const size_t lastLine = explicitGridSizeForSide(gridContainerStyle, side
); |
| 93 return adjustGridPositionForSide(lastLine, side); |
| 94 } |
| 95 |
| 96 size_t namedGridLineIndex; |
| 97 if (position.isPositive()) |
| 98 namedGridLineIndex = std::min<size_t>(position.integerPosition(), it->va
lue.size()) - 1; |
| 99 else |
| 100 namedGridLineIndex = std::max<int>(it->value.size() - abs(position.integ
erPosition()), 0); |
| 101 return adjustGridPositionForSide(it->value[namedGridLineIndex], side); |
| 102 } |
| 103 |
| 104 GridResolvedPosition GridResolvedPosition::resolveGridPositionFromStyle(const Re
nderStyle& gridContainerStyle, const GridPosition& position, GridPositionSide si
de) |
| 105 { |
| 106 switch (position.type()) { |
| 107 case ExplicitPosition: { |
| 108 ASSERT(position.integerPosition()); |
| 109 |
| 110 if (!position.namedGridLine().isNull()) |
| 111 return resolveNamedGridLinePositionFromStyle(gridContainerStyle, pos
ition, side); |
| 112 |
| 113 // Handle <integer> explicit position. |
| 114 if (position.isPositive()) |
| 115 return adjustGridPositionForSide(position.integerPosition() - 1, sid
e); |
| 116 |
| 117 size_t resolvedPosition = abs(position.integerPosition()) - 1; |
| 118 const size_t endOfTrack = explicitGridSizeForSide(gridContainerStyle, si
de); |
| 119 |
| 120 // Per http://lists.w3.org/Archives/Public/www-style/2013Mar/0589.html,
we clamp negative value to the first line. |
| 121 if (endOfTrack < resolvedPosition) |
| 122 return GridResolvedPosition(0); |
| 123 |
| 124 return adjustGridPositionForSide(endOfTrack - resolvedPosition, side); |
| 125 } |
| 126 case NamedGridAreaPosition: |
| 127 { |
| 128 NamedGridAreaMap::const_iterator it = gridContainerStyle.namedGridArea()
.find(position.namedGridLine()); |
| 129 // Unknown grid area should have been computed to 'auto' by now. |
| 130 ASSERT_WITH_SECURITY_IMPLICATION(it != gridContainerStyle.namedGridArea(
).end()); |
| 131 const GridCoordinate& gridAreaCoordinate = it->value; |
| 132 switch (side) { |
| 133 case ColumnStartSide: |
| 134 return gridAreaCoordinate.columns.resolvedInitialPosition; |
| 135 case ColumnEndSide: |
| 136 return gridAreaCoordinate.columns.resolvedFinalPosition; |
| 137 case RowStartSide: |
| 138 return gridAreaCoordinate.rows.resolvedInitialPosition; |
| 139 case RowEndSide: |
| 140 return GridResolvedPosition(gridAreaCoordinate.rows.resolvedFinalPos
ition); |
| 141 } |
| 142 ASSERT_NOT_REACHED(); |
| 143 return GridResolvedPosition(0); |
| 144 } |
| 145 case AutoPosition: |
| 146 case SpanPosition: |
| 147 // 'auto' and span depend on the opposite position for resolution (e.g.
grid-row: auto / 1 or grid-column: span 3 / "myHeader"). |
| 148 ASSERT_NOT_REACHED(); |
| 149 return GridResolvedPosition(0); |
| 150 } |
| 151 ASSERT_NOT_REACHED(); |
| 152 return GridResolvedPosition(0); |
| 153 } |
| 154 |
| 155 PassOwnPtr<GridSpan> GridResolvedPosition::resolveGridPositionAgainstOppositePos
ition(const RenderStyle& gridContainerStyle, const GridResolvedPosition& resolve
dOppositePosition, const GridPosition& position, GridPositionSide side) |
| 156 { |
| 157 if (position.isAuto()) |
| 158 return GridSpan::create(resolvedOppositePosition, resolvedOppositePositi
on); |
| 159 |
| 160 ASSERT(position.isSpan()); |
| 161 ASSERT(position.spanPosition() > 0); |
| 162 |
| 163 if (!position.namedGridLine().isNull()) { |
| 164 // span 2 'c' -> we need to find the appropriate grid line before / afte
r our opposite position. |
| 165 return resolveNamedGridLinePositionAgainstOppositePosition(gridContainer
Style, resolvedOppositePosition, position, side); |
| 166 } |
| 167 |
| 168 return GridSpan::createWithSpanAgainstOpposite(resolvedOppositePosition, pos
ition, side); |
| 169 } |
| 170 |
| 171 PassOwnPtr<GridSpan> GridResolvedPosition::resolveNamedGridLinePositionAgainstOp
positePosition(const RenderStyle& gridContainerStyle, const GridResolvedPosition
& resolvedOppositePosition, const GridPosition& position, GridPositionSide side) |
| 172 { |
| 173 ASSERT(position.isSpan()); |
| 174 ASSERT(!position.namedGridLine().isNull()); |
| 175 // Negative positions are not allowed per the specification and should have
been handled during parsing. |
| 176 ASSERT(position.spanPosition() > 0); |
| 177 |
| 178 const NamedGridLinesMap& gridLinesNames = (side == ColumnStartSide || side =
= ColumnEndSide) ? gridContainerStyle.namedGridColumnLines() : gridContainerStyl
e.namedGridRowLines(); |
| 179 NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGri
dLine()); |
| 180 |
| 181 // 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). |
| 182 // See http://lists.w3.org/Archives/Public/www-style/2013Jun/0394.html. |
| 183 if (it == gridLinesNames.end()) |
| 184 return GridSpan::create(resolvedOppositePosition, resolvedOppositePositi
on); |
| 185 |
| 186 return GridSpan::createWithNamedSpanAgainstOpposite(resolvedOppositePosition
, position, side, it->value); |
| 187 } |
| 188 |
| 189 } // namespace WebCore |
OLD | NEW |