Changeset 185059 in webkit
- Timestamp:
- Jun 1, 2015 8:40:43 AM (9 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r185058 r185059 1 2015-06-01 Sergio Villar Senin <svillar@igalia.com> 2 3 [CSS Grid Layout] Simplify the interface of GridResolvedPosition 4 https://bugs.webkit.org/show_bug.cgi?id=139077 5 6 Reviewed by Darin Adler. 7 8 The interface of GridResolvedPosition is full of static methods 9 that are used only internally, we should not expose them. 10 11 Apart from that resolveGridPositionsFromStyle() do always return 12 a valid GridSpan from now on meaning that the caller has to ensure 13 that the resolution does not require running the auto-placement 14 algorithm. A new class called GridUnresolvedSpan was added for 15 that purpose. 16 17 No new tests as this is a refactoring. 18 19 * rendering/RenderGrid.cpp: 20 (WebCore::RenderGrid::placeItemsOnGrid): 21 (WebCore::RenderGrid::populateExplicitGridAndOrderIterator): 22 (WebCore::RenderGrid::placeSpecifiedMajorAxisItemsOnGrid): 23 (WebCore::RenderGrid::placeAutoMajorAxisItemOnGrid): 24 * rendering/style/GridPosition.h: 25 * rendering/style/GridResolvedPosition.cpp: 26 (WebCore::gridLinesForSide): 27 (WebCore::implicitNamedGridLineForSide): 28 (WebCore::isNonExistentNamedLineOrArea): 29 (WebCore::GridUnresolvedSpan::requiresAutoPlacement): 30 (WebCore::GridUnresolvedSpan::adjustGridPositionsFromStyle): 31 (WebCore::adjustGridPositionForRowEndColumnEndSide): 32 (WebCore::adjustGridPositionForSide): 33 (WebCore::resolveNamedGridLinePositionFromStyle): 34 (WebCore::firstNamedGridLineBeforePosition): 35 (WebCore::resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition): 36 (WebCore::resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition): 37 (WebCore::resolveNamedGridLinePositionAgainstOppositePosition): 38 (WebCore::resolveGridPositionAgainstOppositePosition): 39 (WebCore::GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition): 40 (WebCore::resolveGridPositionFromStyle): 41 (WebCore::GridResolvedPosition::GridResolvedPosition): 42 (WebCore::GridResolvedPosition::unresolvedSpanFromStyle): 43 (WebCore::GridResolvedPosition::resolveGridPositionsFromStyle): 44 (WebCore::GridResolvedPosition::adjustGridPositionsFromStyle): Deleted. 45 (WebCore::GridResolvedPosition::resolveNamedGridLinePositionFromStyle): Deleted. 46 (WebCore::GridResolvedPosition::resolveGridPositionFromStyle): Deleted. 47 (WebCore::GridResolvedPosition::resolveGridPositionAgainstOppositePosition): Deleted. 48 (WebCore::GridResolvedPosition::resolveNamedGridLinePositionAgainstOppositePosition): Deleted. 49 (WebCore::GridResolvedPosition::resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition): Deleted. 50 (WebCore::GridResolvedPosition::resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition): Deleted. 51 * rendering/style/GridResolvedPosition.h: 52 (WebCore::GridUnresolvedSpan::GridUnresolvedSpan): New class. 53 (WebCore::GridUnresolvedSpan::initialPosition): 54 (WebCore::GridUnresolvedSpan::finalPosition): 55 (WebCore::GridUnresolvedSpan::initialPositionSide): 56 (WebCore::GridUnresolvedSpan::finalPositionSide): 57 (WebCore::GridResolvedPosition::adjustGridPositionForRowEndColumnEndSide): Deleted. 58 (WebCore::GridResolvedPosition::adjustGridPositionForSide): Deleted. 59 (WebCore::GridResolvedPosition::GridResolvedPosition): Deleted. 60 1 61 2015-06-01 Csaba Osztrogonác <ossy@webkit.org> 2 62 -
trunk/Source/WebCore/rendering/RenderGrid.cpp
r184446 r185059 976 976 Vector<RenderBox*> specifiedMajorAxisAutoGridItems; 977 977 for (RenderBox* child = m_orderIterator.first(); child; child = m_orderIterator.next()) { 978 std::unique_ptr<GridSpan> rowPositions = GridResolvedPosition::resolveGridPositionsFromStyle(style(), *child, ForRows); 979 std::unique_ptr<GridSpan> columnPositions = GridResolvedPosition::resolveGridPositionsFromStyle(style(), *child, ForColumns); 980 if (!rowPositions || !columnPositions) { 981 GridSpan* majorAxisPositions = (autoPlacementMajorAxisDirection() == ForColumns) ? columnPositions.get() : rowPositions.get(); 982 if (!majorAxisPositions) 978 auto unresolvedRowPositions = GridResolvedPosition::unresolvedSpanFromStyle(style(), *child, ForRows); 979 auto unresolvedColumnPositions = GridResolvedPosition::unresolvedSpanFromStyle(style(), *child, ForColumns); 980 981 if (unresolvedRowPositions.requiresAutoPlacement() || unresolvedColumnPositions.requiresAutoPlacement()) { 982 983 bool majorAxisDirectionIsForColumns = autoPlacementMajorAxisDirection() == ForColumns; 984 if ((majorAxisDirectionIsForColumns && unresolvedColumnPositions.requiresAutoPlacement()) 985 || (!majorAxisDirectionIsForColumns && unresolvedRowPositions.requiresAutoPlacement())) 983 986 autoMajorAxisAutoGridItems.append(child); 984 987 else … … 986 989 continue; 987 990 } 988 insertItemIntoGrid(*child, GridCoordinate(*rowPositions, *columnPositions)); 991 GridSpan rowPositions = GridResolvedPosition::resolveGridPositionsFromStyle(unresolvedRowPositions, style()); 992 GridSpan columnPositions = GridResolvedPosition::resolveGridPositionsFromStyle(unresolvedColumnPositions, style()); 993 insertItemIntoGrid(*child, GridCoordinate(rowPositions, columnPositions)); 989 994 } 990 995 … … 1005 1010 populator.collectChild(*child); 1006 1011 1007 // This function bypasses the cache (cachedGridCoordinate()) as it is used to build it. 1008 std::unique_ptr<GridSpan> rowPositions = GridResolvedPosition::resolveGridPositionsFromStyle(style(), *child, ForRows); 1009 std::unique_ptr<GridSpan> columnPositions = GridResolvedPosition::resolveGridPositionsFromStyle(style(), *child, ForColumns); 1010 1011 // |positions| is 0 if we need to run the auto-placement algorithm. 1012 if (rowPositions) 1013 maximumRowIndex = std::max(maximumRowIndex, rowPositions->resolvedFinalPosition.next().toInt()); 1014 else { 1012 auto unresolvedRowPositions = GridResolvedPosition::unresolvedSpanFromStyle(style(), *child, ForRows); 1013 if (!unresolvedRowPositions.requiresAutoPlacement()) { 1014 GridSpan rowPositions = GridResolvedPosition::resolveGridPositionsFromStyle(unresolvedRowPositions, style()); 1015 maximumRowIndex = std::max(maximumRowIndex, rowPositions.resolvedFinalPosition.next().toInt()); 1016 } else { 1015 1017 // Grow the grid for items with a definite row span, getting the largest such span. 1016 1018 GridSpan positions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(style(), *child, ForRows, GridResolvedPosition(0)); … … 1018 1020 } 1019 1021 1020 if (columnPositions) 1021 maximumColumnIndex = std::max(maximumColumnIndex, columnPositions->resolvedFinalPosition.next().toInt()); 1022 else { 1022 auto unresolvedColumnPositions = GridResolvedPosition::unresolvedSpanFromStyle(style(), *child, ForColumns); 1023 if (!unresolvedColumnPositions.requiresAutoPlacement()) { 1024 GridSpan columnPositions = GridResolvedPosition::resolveGridPositionsFromStyle(unresolvedColumnPositions, style()); 1025 maximumColumnIndex = std::max(maximumColumnIndex, columnPositions.resolvedFinalPosition.next().toInt()); 1026 } else { 1023 1027 // Grow the grid for items with a definite column span, getting the largest such span. 1024 1028 GridSpan positions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(style(), *child, ForColumns, GridResolvedPosition(0)); … … 1051 1055 1052 1056 for (auto& autoGridItem : autoGridItems) { 1053 std::unique_ptr<GridSpan> majorAxisPositions = GridResolvedPosition::resolveGridPositionsFromStyle(style(), *autoGridItem, autoPlacementMajorAxisDirection()); 1057 auto unresolvedMajorAxisPositions = GridResolvedPosition::unresolvedSpanFromStyle(style(), *autoGridItem, autoPlacementMajorAxisDirection()); 1058 ASSERT(!unresolvedMajorAxisPositions.requiresAutoPlacement()); 1059 GridSpan majorAxisPositions = GridResolvedPosition::resolveGridPositionsFromStyle(unresolvedMajorAxisPositions, style()); 1054 1060 GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(style(), *autoGridItem, autoPlacementMinorAxisDirection(), GridResolvedPosition(0)); 1055 unsigned majorAxisInitialPosition = majorAxisPositions ->resolvedInitialPosition.toInt();1056 1057 GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), majorAxisPositions ->resolvedInitialPosition.toInt(), isGridAutoFlowDense ? 0 : minorAxisCursors.get(majorAxisInitialPosition));1058 std::unique_ptr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea(majorAxisPositions ->integerSpan(), minorAxisPositions.integerSpan());1061 unsigned majorAxisInitialPosition = majorAxisPositions.resolvedInitialPosition.toInt(); 1062 1063 GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), majorAxisPositions.resolvedInitialPosition.toInt(), isGridAutoFlowDense ? 0 : minorAxisCursors.get(majorAxisInitialPosition)); 1064 std::unique_ptr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea(majorAxisPositions.integerSpan(), minorAxisPositions.integerSpan()); 1059 1065 if (!emptyGridArea) 1060 emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(*autoGridItem, autoPlacementMajorAxisDirection(), *majorAxisPositions);1066 emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(*autoGridItem, autoPlacementMajorAxisDirection(), majorAxisPositions); 1061 1067 insertItemIntoGrid(*autoGridItem, *emptyGridArea); 1062 1068 … … 1083 1089 void RenderGrid::placeAutoMajorAxisItemOnGrid(RenderBox& gridItem, AutoPlacementCursor& autoPlacementCursor) 1084 1090 { 1085 std::unique_ptr<GridSpan> minorAxisPositions = GridResolvedPosition::resolveGridPositionsFromStyle(style(), gridItem, autoPlacementMinorAxisDirection()); 1086 ASSERT(!GridResolvedPosition::resolveGridPositionsFromStyle(style(), gridItem, autoPlacementMajorAxisDirection())); 1091 ASSERT(GridResolvedPosition::unresolvedSpanFromStyle(style(), gridItem, autoPlacementMajorAxisDirection()).requiresAutoPlacement()); 1087 1092 GridSpan majorAxisPositions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(style(), gridItem, autoPlacementMajorAxisDirection(), GridResolvedPosition(0)); 1088 1093 … … 1092 1097 1093 1098 std::unique_ptr<GridCoordinate> emptyGridArea; 1094 if (minorAxisPositions) { 1099 auto unresolvedMinorAxisPositions = GridResolvedPosition::unresolvedSpanFromStyle(style(), gridItem, autoPlacementMinorAxisDirection()); 1100 if (!unresolvedMinorAxisPositions.requiresAutoPlacement()) { 1101 GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPositionsFromStyle(unresolvedMinorAxisPositions, style()); 1102 1095 1103 // Move to the next track in major axis if initial position in minor axis is before auto-placement cursor. 1096 if (minorAxisPositions ->resolvedInitialPosition.toInt() < minorAxisAutoPlacementCursor)1104 if (minorAxisPositions.resolvedInitialPosition.toInt() < minorAxisAutoPlacementCursor) 1097 1105 majorAxisAutoPlacementCursor++; 1098 1106 1099 1107 if (majorAxisAutoPlacementCursor < endOfMajorAxis) { 1100 GridIterator iterator(m_grid, autoPlacementMinorAxisDirection(), minorAxisPositions ->resolvedInitialPosition.toInt(), majorAxisAutoPlacementCursor);1101 emptyGridArea = iterator.nextEmptyGridArea(minorAxisPositions ->integerSpan(), majorAxisPositions.integerSpan());1108 GridIterator iterator(m_grid, autoPlacementMinorAxisDirection(), minorAxisPositions.resolvedInitialPosition.toInt(), majorAxisAutoPlacementCursor); 1109 emptyGridArea = iterator.nextEmptyGridArea(minorAxisPositions.integerSpan(), majorAxisPositions.integerSpan()); 1102 1110 } 1103 1111 1104 1112 if (!emptyGridArea) 1105 emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(gridItem, autoPlacementMinorAxisDirection(), *minorAxisPositions);1113 emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(gridItem, autoPlacementMinorAxisDirection(), minorAxisPositions); 1106 1114 } else { 1107 1115 GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(style(), gridItem, autoPlacementMinorAxisDirection(), GridResolvedPosition(0)); -
trunk/Source/WebCore/rendering/style/GridPosition.h
r169934 r185059 44 44 SpanPosition, // span && [ <integer> || <string> ] 45 45 NamedGridAreaPosition // <ident> 46 }; 47 48 enum GridPositionSide { 49 ColumnStartSide, 50 ColumnEndSide, 51 RowStartSide, 52 RowEndSide 46 53 }; 47 54 -
trunk/Source/WebCore/rendering/style/GridResolvedPosition.cpp
r179826 r185059 49 49 } 50 50 51 unsigned GridResolvedPosition::explicitGridColumnCount(const RenderStyle& gridContainerStyle) 52 { 53 return std::min<unsigned>(gridContainerStyle.gridColumns().size(), kGridMaxTracks); 54 } 55 56 unsigned GridResolvedPosition::explicitGridRowCount(const RenderStyle& gridContainerStyle) 57 { 58 return std::min<unsigned>(gridContainerStyle.gridRows().size(), kGridMaxTracks); 59 } 60 61 static unsigned explicitGridSizeForSide(const RenderStyle& gridContainerStyle, GridPositionSide side) 62 { 63 return isColumnSide(side) ? GridResolvedPosition::explicitGridColumnCount(gridContainerStyle) : GridResolvedPosition::explicitGridRowCount(gridContainerStyle); 64 } 65 66 GridSpan GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction, const GridResolvedPosition& resolvedInitialPosition) 67 { 68 GridPosition initialPosition = (direction == ForColumns) ? gridItem.style().gridItemColumnStart() : gridItem.style().gridItemRowStart(); 69 const GridPositionSide initialPositionSide = (direction == ForColumns) ? ColumnStartSide : RowStartSide; 70 GridPosition finalPosition = (direction == ForColumns) ? gridItem.style().gridItemColumnEnd() : gridItem.style().gridItemRowEnd(); 71 const GridPositionSide finalPositionSide = (direction == ForColumns) ? ColumnEndSide : RowEndSide; 72 73 adjustGridPositionsFromStyle(gridContainerStyle, initialPosition, finalPosition, initialPositionSide, finalPositionSide); 74 75 // This method will only be used when both positions need to be resolved against the opposite one. 76 ASSERT(initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPosition.shouldBeResolvedAgainstOppositePosition()); 77 78 GridResolvedPosition resolvedFinalPosition = resolvedInitialPosition; 79 80 if (initialPosition.isSpan()) 81 return *resolveGridPositionAgainstOppositePosition(gridContainerStyle, resolvedInitialPosition, initialPosition, finalPositionSide); 82 else if (finalPosition.isSpan()) 83 return *resolveGridPositionAgainstOppositePosition(gridContainerStyle, resolvedInitialPosition, finalPosition, finalPositionSide); 84 85 return GridSpan(resolvedInitialPosition, resolvedFinalPosition); 86 } 87 88 static inline const NamedGridLinesMap& gridLinesForSide(const RenderStyle& style, GridPositionSide side) 51 static const NamedGridLinesMap& gridLinesForSide(const RenderStyle& style, GridPositionSide side) 89 52 { 90 53 return isColumnSide(side) ? style.namedGridColumnLines() : style.namedGridRowLines(); 91 54 } 92 55 93 static inlineconst String implicitNamedGridLineForSide(const String& lineName, GridPositionSide side)56 static const String implicitNamedGridLineForSide(const String& lineName, GridPositionSide side) 94 57 { 95 58 return lineName + (isStartSide(side) ? "-start" : "-end"); … … 102 65 } 103 66 104 void GridResolvedPosition::adjustGridPositionsFromStyle(const RenderStyle& gridContainerStyle, GridPosition& initialPosition, GridPosition& finalPosition, GridPositionSide initialPositionSide, GridPositionSide finalPositionSide) 105 { 106 ASSERT(isColumnSide(initialPositionSide) == isColumnSide(finalPositionSide)); 67 bool GridUnresolvedSpan::requiresAutoPlacement() const 68 { 69 return m_initialPosition.shouldBeResolvedAgainstOppositePosition() && m_finalPosition.shouldBeResolvedAgainstOppositePosition(); 70 } 71 72 void GridUnresolvedSpan::adjustGridPositionsFromStyle(const RenderStyle& gridContainerStyle) 73 { 74 ASSERT(isColumnSide(m_initialPositionSide) == isColumnSide(m_finalPositionSide)); 107 75 108 76 // We must handle the placement error handling code here instead of in the StyleAdjuster because we don't want to 109 77 // overwrite the specified values. 110 if ( initialPosition.isSpan() &&finalPosition.isSpan())111 finalPosition.setAutoPosition();78 if (m_initialPosition.isSpan() && m_finalPosition.isSpan()) 79 m_finalPosition.setAutoPosition(); 112 80 113 81 // Try to early detect the case of non existing named grid lines. This way we could assume later that 114 82 // GridResolvedPosition::resolveGrisPositionFromStyle() won't require the autoplacement to run, i.e., it'll always return a 115 83 // valid resolved position. 116 if ( initialPosition.isNamedGridArea() && isNonExistentNamedLineOrArea(initialPosition.namedGridLine(), gridContainerStyle,initialPositionSide))117 initialPosition.setAutoPosition();118 119 if ( finalPosition.isNamedGridArea() && isNonExistentNamedLineOrArea(finalPosition.namedGridLine(), gridContainerStyle,finalPositionSide))120 finalPosition.setAutoPosition();84 if (m_initialPosition.isNamedGridArea() && isNonExistentNamedLineOrArea(m_initialPosition.namedGridLine(), gridContainerStyle, m_initialPositionSide)) 85 m_initialPosition.setAutoPosition(); 86 87 if (m_finalPosition.isNamedGridArea() && isNonExistentNamedLineOrArea(m_finalPosition.namedGridLine(), gridContainerStyle, m_finalPositionSide)) 88 m_finalPosition.setAutoPosition(); 121 89 122 90 // If the grid item has an automatic position and a grid span for a named line in a given dimension, instead treat the grid span as one. 123 if (initialPosition.isAuto() && finalPosition.isSpan() && !finalPosition.namedGridLine().isNull()) 124 finalPosition.setSpanPosition(1, String()); 125 if (finalPosition.isAuto() && initialPosition.isSpan() && !initialPosition.namedGridLine().isNull()) 126 initialPosition.setSpanPosition(1, String()); 127 } 128 129 std::unique_ptr<GridSpan> GridResolvedPosition::resolveGridPositionsFromStyle(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction) 130 { 131 GridPosition initialPosition = (direction == ForColumns) ? gridItem.style().gridItemColumnStart() : gridItem.style().gridItemRowStart(); 132 const GridPositionSide initialPositionSide = (direction == ForColumns) ? ColumnStartSide : RowStartSide; 133 GridPosition finalPosition = (direction == ForColumns) ? gridItem.style().gridItemColumnEnd() : gridItem.style().gridItemRowEnd(); 134 const GridPositionSide finalPositionSide = (direction == ForColumns) ? ColumnEndSide : RowEndSide; 135 136 adjustGridPositionsFromStyle(gridContainerStyle, initialPosition, finalPosition, initialPositionSide, finalPositionSide); 137 138 // We can't get our grid positions without running the auto placement algorithm. 139 if (initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPosition.shouldBeResolvedAgainstOppositePosition()) 140 return nullptr; 141 142 if (initialPosition.shouldBeResolvedAgainstOppositePosition()) { 143 // Infer the position from the final position ('auto / 1' or 'span 2 / 3' case). 144 const GridResolvedPosition finalResolvedPosition = resolveGridPositionFromStyle(gridContainerStyle, finalPosition, finalPositionSide); 145 return resolveGridPositionAgainstOppositePosition(gridContainerStyle, finalResolvedPosition, initialPosition, initialPositionSide); 146 } 147 148 if (finalPosition.shouldBeResolvedAgainstOppositePosition()) { 149 // Infer our position from the initial position ('1 / auto' or '3 / span 2' case). 150 const GridResolvedPosition initialResolvedPosition = resolveGridPositionFromStyle(gridContainerStyle, initialPosition, initialPositionSide); 151 return resolveGridPositionAgainstOppositePosition(gridContainerStyle, initialResolvedPosition, finalPosition, finalPositionSide); 152 } 153 154 GridResolvedPosition resolvedInitialPosition = resolveGridPositionFromStyle(gridContainerStyle, initialPosition, initialPositionSide); 155 GridResolvedPosition resolvedFinalPosition = resolveGridPositionFromStyle(gridContainerStyle, finalPosition, finalPositionSide); 156 157 // If 'grid-row-end' specifies a line at or before that specified by 'grid-row-start', it computes to 'span 1'. 158 if (resolvedFinalPosition < resolvedInitialPosition) 159 resolvedFinalPosition = resolvedInitialPosition; 160 161 return std::make_unique<GridSpan>(resolvedInitialPosition, resolvedFinalPosition); 162 } 163 164 GridResolvedPosition GridResolvedPosition::resolveNamedGridLinePositionFromStyle(const RenderStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side) 91 if (m_initialPosition.isAuto() && m_finalPosition.isSpan() && !m_finalPosition.namedGridLine().isNull()) 92 m_finalPosition.setSpanPosition(1, String()); 93 if (m_finalPosition.isAuto() && m_initialPosition.isSpan() && !m_initialPosition.namedGridLine().isNull()) 94 m_initialPosition.setSpanPosition(1, String()); 95 } 96 97 unsigned GridResolvedPosition::explicitGridColumnCount(const RenderStyle& gridContainerStyle) 98 { 99 return std::min<unsigned>(gridContainerStyle.gridColumns().size(), kGridMaxTracks); 100 } 101 102 unsigned GridResolvedPosition::explicitGridRowCount(const RenderStyle& gridContainerStyle) 103 { 104 return std::min<unsigned>(gridContainerStyle.gridRows().size(), kGridMaxTracks); 105 } 106 107 static unsigned explicitGridSizeForSide(const RenderStyle& gridContainerStyle, GridPositionSide side) 108 { 109 return isColumnSide(side) ? GridResolvedPosition::explicitGridColumnCount(gridContainerStyle) : GridResolvedPosition::explicitGridRowCount(gridContainerStyle); 110 } 111 112 static GridResolvedPosition adjustGridPositionForRowEndColumnEndSide(unsigned resolvedPosition) 113 { 114 return resolvedPosition ? GridResolvedPosition(resolvedPosition - 1) : GridResolvedPosition(0); 115 } 116 117 static GridResolvedPosition adjustGridPositionForSide(unsigned resolvedPosition, GridPositionSide side) 118 { 119 // An item finishing on the N-th line belongs to the N-1-th cell. 120 if (side == ColumnEndSide || side == RowEndSide) 121 return adjustGridPositionForRowEndColumnEndSide(resolvedPosition); 122 123 return GridResolvedPosition(resolvedPosition); 124 } 125 126 static GridResolvedPosition resolveNamedGridLinePositionFromStyle(const RenderStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side) 165 127 { 166 128 ASSERT(!position.namedGridLine().isNull()); … … 172 134 return 0; 173 135 const unsigned lastLine = explicitGridSizeForSide(gridContainerStyle, side); 174 return GridResolvedPosition::adjustGridPositionForSide(lastLine, side);136 return adjustGridPositionForSide(lastLine, side); 175 137 } 176 138 … … 180 142 else 181 143 namedGridLineIndex = std::max<int>(0, it->value.size() - abs(position.integerPosition())); 182 return GridResolvedPosition::adjustGridPositionForSide(it->value[namedGridLineIndex], side); 183 } 184 185 GridResolvedPosition GridResolvedPosition::resolveGridPositionFromStyle(const RenderStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side) 144 return adjustGridPositionForSide(it->value[namedGridLineIndex], side); 145 } 146 147 static inline unsigned firstNamedGridLineBeforePosition(unsigned position, const Vector<unsigned>& gridLines) 148 { 149 // The grid line inequality needs to be strict (which doesn't match the after / end case) because |position| is 150 // already converted to an index in our grid representation (ie one was removed from the grid line to account for 151 // the side). 152 unsigned firstLineBeforePositionIndex = 0; 153 auto firstLineBeforePosition = std::lower_bound(gridLines.begin(), gridLines.end(), position); 154 if (firstLineBeforePosition != gridLines.end()) { 155 if (*firstLineBeforePosition > position && firstLineBeforePosition != gridLines.begin()) 156 --firstLineBeforePosition; 157 158 firstLineBeforePositionIndex = firstLineBeforePosition - gridLines.begin(); 159 } 160 return firstLineBeforePositionIndex; 161 } 162 163 static GridSpan resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition(const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, const Vector<unsigned>& gridLines) 164 { 165 unsigned gridLineIndex = std::max<int>(0, firstNamedGridLineBeforePosition(resolvedOppositePosition.toInt(), gridLines) - position.spanPosition() + 1); 166 GridResolvedPosition resolvedGridLinePosition = GridResolvedPosition(gridLines[gridLineIndex]); 167 return GridSpan(std::min<GridResolvedPosition>(resolvedGridLinePosition, resolvedOppositePosition), resolvedOppositePosition); 168 } 169 170 static GridSpan resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition(const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, const Vector<unsigned>& gridLines) 171 { 172 ASSERT(gridLines.size()); 173 unsigned firstLineAfterOppositePositionIndex = gridLines.size() - 1; 174 const unsigned* firstLineAfterOppositePosition = std::upper_bound(gridLines.begin(), gridLines.end(), resolvedOppositePosition); 175 if (firstLineAfterOppositePosition != gridLines.end()) 176 firstLineAfterOppositePositionIndex = firstLineAfterOppositePosition - gridLines.begin(); 177 178 unsigned gridLineIndex = std::min<unsigned>(gridLines.size() - 1, firstLineAfterOppositePositionIndex + position.spanPosition() - 1); 179 GridResolvedPosition resolvedGridLinePosition = adjustGridPositionForRowEndColumnEndSide(gridLines[gridLineIndex]); 180 if (resolvedGridLinePosition < resolvedOppositePosition) 181 resolvedGridLinePosition = resolvedOppositePosition; 182 return GridSpan(resolvedOppositePosition, resolvedGridLinePosition); 183 } 184 185 static GridSpan resolveNamedGridLinePositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, GridPositionSide side) 186 { 187 ASSERT(position.isSpan()); 188 ASSERT(!position.namedGridLine().isNull()); 189 // Negative positions are not allowed per the specification and should have been handled during parsing. 190 ASSERT(position.spanPosition() > 0); 191 192 const NamedGridLinesMap& gridLinesNames = isColumnSide(side) ? gridContainerStyle.namedGridColumnLines() : gridContainerStyle.namedGridRowLines(); 193 NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGridLine()); 194 195 // 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). 196 // See http://lists.w3.org/Archives/Public/www-style/2013Jun/0394.html. 197 if (it == gridLinesNames.end()) 198 return GridSpan(resolvedOppositePosition, resolvedOppositePosition); 199 200 if (side == RowStartSide || side == ColumnStartSide) 201 return resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition(resolvedOppositePosition, position, it->value); 202 203 return resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition(resolvedOppositePosition, position, it->value); 204 } 205 206 static GridSpan resolveGridPositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, GridPositionSide side) 207 { 208 if (position.isAuto()) 209 return GridSpan(resolvedOppositePosition, resolvedOppositePosition); 210 211 ASSERT(position.isSpan()); 212 ASSERT(position.spanPosition() > 0); 213 214 if (!position.namedGridLine().isNull()) { 215 // span 2 'c' -> we need to find the appropriate grid line before / after our opposite position. 216 return resolveNamedGridLinePositionAgainstOppositePosition(gridContainerStyle, resolvedOppositePosition, position, side); 217 } 218 219 // 'span 1' is contained inside a single grid track regardless of the direction. 220 // That's why the CSS span value is one more than the offset we apply. 221 unsigned positionOffset = position.spanPosition() - 1; 222 if (isStartSide(side)) { 223 unsigned initialResolvedPosition = std::max<int>(0, resolvedOppositePosition.toInt() - positionOffset); 224 return GridSpan(initialResolvedPosition, resolvedOppositePosition); 225 } 226 227 return GridSpan(resolvedOppositePosition, resolvedOppositePosition.toInt() + positionOffset); 228 } 229 230 GridSpan GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction, const GridResolvedPosition& resolvedInitialPosition) 231 { 232 GridUnresolvedSpan unresolvedSpan = unresolvedSpanFromStyle(gridContainerStyle, gridItem, direction); 233 234 // This method will only be used when both positions need to be resolved against the opposite one. 235 ASSERT(unresolvedSpan.requiresAutoPlacement()); 236 237 GridResolvedPosition resolvedFinalPosition = resolvedInitialPosition; 238 239 if (unresolvedSpan.initialPosition().isSpan()) 240 return resolveGridPositionAgainstOppositePosition(gridContainerStyle, resolvedInitialPosition, unresolvedSpan.initialPosition(), unresolvedSpan.finalPositionSide()); 241 if (unresolvedSpan.finalPosition().isSpan()) 242 return resolveGridPositionAgainstOppositePosition(gridContainerStyle, resolvedInitialPosition, unresolvedSpan.finalPosition(), unresolvedSpan.finalPositionSide()); 243 244 return GridSpan(resolvedInitialPosition, resolvedFinalPosition); 245 } 246 247 static GridResolvedPosition resolveGridPositionFromStyle(const RenderStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side) 186 248 { 187 249 switch (position.type()) { … … 194 256 // Handle <integer> explicit position. 195 257 if (position.isPositive()) 196 return GridResolvedPosition::adjustGridPositionForSide(position.integerPosition() - 1, side);258 return adjustGridPositionForSide(position.integerPosition() - 1, side); 197 259 198 260 unsigned resolvedPosition = abs(position.integerPosition()) - 1; … … 203 265 return 0; 204 266 205 return GridResolvedPosition::adjustGridPositionForSide(endOfTrack - resolvedPosition, side);267 return adjustGridPositionForSide(endOfTrack - resolvedPosition, side); 206 268 } 207 269 case NamedGridAreaPosition: … … 216 278 auto implicitLine = gridLineNames.find(implicitNamedGridLineForSide(namedGridLine, side)); 217 279 if (implicitLine != gridLineNames.end()) 218 return GridResolvedPosition::adjustGridPositionForSide(implicitLine->value[0], side);280 return adjustGridPositionForSide(implicitLine->value[0], side); 219 281 220 282 // Otherwise, if there is a named line with the specified name, contributes the first such line to the grid … … 222 284 auto explicitLine = gridLineNames.find(namedGridLine); 223 285 if (explicitLine != gridLineNames.end()) 224 return GridResolvedPosition::adjustGridPositionForSide(explicitLine->value[0], side);286 return adjustGridPositionForSide(explicitLine->value[0], side); 225 287 226 288 // If none of the above works specs mandate us to treat it as auto BUT we should have detected it before calling … … 240 302 } 241 303 242 std::unique_ptr<GridSpan> GridResolvedPosition::resolveGridPositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, GridPositionSide side) 243 { 244 if (position.isAuto()) 245 return std::make_unique<GridSpan>(resolvedOppositePosition, resolvedOppositePosition); 246 247 ASSERT(position.isSpan()); 248 ASSERT(position.spanPosition() > 0); 249 250 if (!position.namedGridLine().isNull()) { 251 // span 2 'c' -> we need to find the appropriate grid line before / after our opposite position. 252 return resolveNamedGridLinePositionAgainstOppositePosition(gridContainerStyle, resolvedOppositePosition, position, side); 253 } 254 255 // 'span 1' is contained inside a single grid track regardless of the direction. 256 // That's why the CSS span value is one more than the offset we apply. 257 unsigned positionOffset = position.spanPosition() - 1; 258 if (isStartSide(side)) { 259 unsigned initialResolvedPosition = std::max<int>(0, resolvedOppositePosition.toInt() - positionOffset); 260 return std::make_unique<GridSpan>(initialResolvedPosition, resolvedOppositePosition); 261 } 262 263 return std::make_unique<GridSpan>(resolvedOppositePosition, resolvedOppositePosition.toInt() + positionOffset); 264 } 265 266 std::unique_ptr<GridSpan> GridResolvedPosition::resolveNamedGridLinePositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, GridPositionSide side) 267 { 268 ASSERT(position.isSpan()); 269 ASSERT(!position.namedGridLine().isNull()); 270 // Negative positions are not allowed per the specification and should have been handled during parsing. 271 ASSERT(position.spanPosition() > 0); 272 273 const NamedGridLinesMap& gridLinesNames = isColumnSide(side) ? gridContainerStyle.namedGridColumnLines() : gridContainerStyle.namedGridRowLines(); 274 NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGridLine()); 275 276 // 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). 277 // See http://lists.w3.org/Archives/Public/www-style/2013Jun/0394.html. 278 if (it == gridLinesNames.end()) 279 return std::make_unique<GridSpan>(resolvedOppositePosition, resolvedOppositePosition); 280 281 if (side == RowStartSide || side == ColumnStartSide) 282 return resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition(resolvedOppositePosition, position, it->value); 283 284 return resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition(resolvedOppositePosition, position, it->value); 285 } 286 287 static inline unsigned firstNamedGridLineBeforePosition(unsigned position, const Vector<unsigned>& gridLines) 288 { 289 // The grid line inequality needs to be strict (which doesn't match the after / end case) because |position| is 290 // already converted to an index in our grid representation (ie one was removed from the grid line to account for 291 // the side). 292 unsigned firstLineBeforePositionIndex = 0; 293 const unsigned* firstLineBeforePosition = std::lower_bound(gridLines.begin(), gridLines.end(), position); 294 if (firstLineBeforePosition != gridLines.end()) { 295 if (*firstLineBeforePosition > position && firstLineBeforePosition != gridLines.begin()) 296 --firstLineBeforePosition; 297 298 firstLineBeforePositionIndex = firstLineBeforePosition - gridLines.begin(); 299 } 300 return firstLineBeforePositionIndex; 301 } 302 303 std::unique_ptr<GridSpan> GridResolvedPosition::resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition(const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, const Vector<unsigned>& gridLines) 304 { 305 unsigned gridLineIndex = std::max<int>(0, firstNamedGridLineBeforePosition(resolvedOppositePosition.toInt(), gridLines) - position.spanPosition() + 1); 306 GridResolvedPosition resolvedGridLinePosition = GridResolvedPosition(gridLines[gridLineIndex]); 307 if (resolvedGridLinePosition > resolvedOppositePosition) 308 resolvedGridLinePosition = resolvedOppositePosition; 309 return std::make_unique<GridSpan>(resolvedGridLinePosition, resolvedOppositePosition); 310 } 311 312 std::unique_ptr<GridSpan> GridResolvedPosition::resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition(const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, const Vector<unsigned>& gridLines) 313 { 314 ASSERT(gridLines.size()); 315 unsigned firstLineAfterOppositePositionIndex = gridLines.size() - 1; 316 const unsigned* firstLineAfterOppositePosition = std::upper_bound(gridLines.begin(), gridLines.end(), resolvedOppositePosition); 317 if (firstLineAfterOppositePosition != gridLines.end()) 318 firstLineAfterOppositePositionIndex = firstLineAfterOppositePosition - gridLines.begin(); 319 320 unsigned gridLineIndex = std::min<unsigned>(gridLines.size() - 1, firstLineAfterOppositePositionIndex + position.spanPosition() - 1); 321 GridResolvedPosition resolvedGridLinePosition = GridResolvedPosition::adjustGridPositionForRowEndColumnEndSide(gridLines[gridLineIndex]); 322 if (resolvedGridLinePosition < resolvedOppositePosition) 323 resolvedGridLinePosition = resolvedOppositePosition; 324 return std::make_unique<GridSpan>(resolvedOppositePosition, resolvedGridLinePosition); 304 GridResolvedPosition::GridResolvedPosition(const GridPosition& position, GridPositionSide side) 305 { 306 ASSERT(position.integerPosition()); 307 unsigned integerPosition = position.integerPosition() - 1; 308 309 m_integerPosition = adjustGridPositionForSide(integerPosition, side).m_integerPosition; 310 } 311 312 GridUnresolvedSpan GridResolvedPosition::unresolvedSpanFromStyle(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction) 313 { 314 GridPosition initialPosition = (direction == ForColumns) ? gridItem.style().gridItemColumnStart() : gridItem.style().gridItemRowStart(); 315 auto initialPositionSide = (direction == ForColumns) ? ColumnStartSide : RowStartSide; 316 GridPosition finalPosition = (direction == ForColumns) ? gridItem.style().gridItemColumnEnd() : gridItem.style().gridItemRowEnd(); 317 auto finalPositionSide = (direction == ForColumns) ? ColumnEndSide : RowEndSide; 318 319 GridUnresolvedSpan unresolvedSpan(initialPosition, initialPositionSide, finalPosition, finalPositionSide); 320 unresolvedSpan.adjustGridPositionsFromStyle(gridContainerStyle); 321 322 return unresolvedSpan; 323 } 324 325 GridSpan GridResolvedPosition::resolveGridPositionsFromStyle(const GridUnresolvedSpan& unresolvedSpan, const RenderStyle& gridContainerStyle) 326 { 327 ASSERT(!unresolvedSpan.requiresAutoPlacement()); 328 329 if (unresolvedSpan.initialPosition().shouldBeResolvedAgainstOppositePosition()) { 330 // Infer the position from the final position ('auto / 1' or 'span 2 / 3' case). 331 auto finalResolvedPosition = resolveGridPositionFromStyle(gridContainerStyle, unresolvedSpan.finalPosition(), unresolvedSpan.finalPositionSide()); 332 return resolveGridPositionAgainstOppositePosition(gridContainerStyle, finalResolvedPosition, unresolvedSpan.initialPosition(), unresolvedSpan.initialPositionSide()); 333 } 334 335 if (unresolvedSpan.finalPosition().shouldBeResolvedAgainstOppositePosition()) { 336 // Infer our position from the initial position ('1 / auto' or '3 / span 2' case). 337 auto initialResolvedPosition = resolveGridPositionFromStyle(gridContainerStyle, unresolvedSpan.initialPosition(), unresolvedSpan.initialPositionSide()); 338 return resolveGridPositionAgainstOppositePosition(gridContainerStyle, initialResolvedPosition, unresolvedSpan.finalPosition(), unresolvedSpan.finalPositionSide()); 339 } 340 341 GridResolvedPosition resolvedInitialPosition = resolveGridPositionFromStyle(gridContainerStyle, unresolvedSpan.initialPosition(), unresolvedSpan.initialPositionSide()); 342 GridResolvedPosition resolvedFinalPosition = resolveGridPositionFromStyle(gridContainerStyle, unresolvedSpan.finalPosition(), unresolvedSpan.finalPositionSide()); 343 344 // If 'grid-row-end' specifies a line at or before that specified by 'grid-row-start', it computes to 'span 1'. 345 return GridSpan(resolvedInitialPosition, std::max<GridResolvedPosition>(resolvedInitialPosition, resolvedFinalPosition)); 325 346 } 326 347 -
trunk/Source/WebCore/rendering/style/GridResolvedPosition.h
r176390 r185059 42 42 class RenderStyle; 43 43 44 enum GridPositionSide {45 ColumnStartSide,46 ColumnEndSide,47 RowStartSide,48 RowEndSide49 };50 51 44 enum GridTrackSizingDirection { 52 45 ForColumns, 53 46 ForRows 47 }; 48 49 class GridUnresolvedSpan { 50 public: 51 GridUnresolvedSpan(GridPosition initialPosition, GridPositionSide initialPositionSide, GridPosition finalPosition, GridPositionSide finalPositionSide) 52 : m_initialPosition(initialPosition) 53 , m_finalPosition(finalPosition) 54 , m_initialPositionSide(initialPositionSide) 55 , m_finalPositionSide(finalPositionSide) 56 { 57 } 58 59 const GridPosition& initialPosition() const { return m_initialPosition; } 60 const GridPosition& finalPosition() const { return m_finalPosition; } 61 GridPositionSide initialPositionSide() const { return m_initialPositionSide; } 62 GridPositionSide finalPositionSide() const { return m_finalPositionSide; } 63 64 bool requiresAutoPlacement() const; 65 void adjustGridPositionsFromStyle(const RenderStyle& gridContainerStyle); 66 67 private: 68 GridPosition m_initialPosition; 69 GridPosition m_finalPosition; 70 GridPositionSide m_initialPositionSide; 71 GridPositionSide m_finalPositionSide; 54 72 }; 55 73 … … 58 76 class GridResolvedPosition { 59 77 public: 60 static GridResolvedPosition adjustGridPositionForRowEndColumnEndSide(unsigned resolvedPosition)61 {62 return resolvedPosition ? GridResolvedPosition(resolvedPosition - 1) : GridResolvedPosition(0);63 }64 65 static GridResolvedPosition adjustGridPositionForSide(unsigned resolvedPosition, GridPositionSide side)66 {67 // An item finishing on the N-th line belongs to the N-1-th cell.68 if (side == ColumnEndSide || side == RowEndSide)69 return adjustGridPositionForRowEndColumnEndSide(resolvedPosition);70 71 return GridResolvedPosition(resolvedPosition);72 }73 74 static GridSpan resolveGridPositionsFromAutoPlacementPosition(const RenderStyle&, const RenderBox&, GridTrackSizingDirection, const GridResolvedPosition&);75 static void adjustNamedGridItemPosition(const RenderStyle&, GridPosition&, GridPositionSide);76 static void adjustGridPositionsFromStyle(const RenderStyle&, GridPosition& initialPosition, GridPosition& finalPosition, GridPositionSide initialPositionSide, GridPositionSide finalPositionSide);77 static std::unique_ptr<GridSpan> resolveGridPositionsFromStyle(const RenderStyle&, const RenderBox&, GridTrackSizingDirection);78 static GridResolvedPosition resolveNamedGridLinePositionFromStyle(const RenderStyle&, const GridPosition&, GridPositionSide);79 static GridResolvedPosition resolveGridPositionFromStyle(const RenderStyle&, const GridPosition&, GridPositionSide);80 static std::unique_ptr<GridSpan> resolveGridPositionAgainstOppositePosition(const RenderStyle&, const GridResolvedPosition&, const GridPosition&, GridPositionSide);81 static std::unique_ptr<GridSpan> resolveNamedGridLinePositionAgainstOppositePosition(const RenderStyle&, const GridResolvedPosition&, const GridPosition&, GridPositionSide);82 static std::unique_ptr<GridSpan> resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition(const GridResolvedPosition&, const GridPosition&, const Vector<unsigned>&);83 static std::unique_ptr<GridSpan> resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition(const GridResolvedPosition&, const GridPosition&, const Vector<unsigned>&);84 85 78 GridResolvedPosition(unsigned position) 86 79 : m_integerPosition(position) … … 88 81 } 89 82 90 GridResolvedPosition(const GridPosition& position, GridPositionSide side) 91 { 92 ASSERT(position.integerPosition()); 93 unsigned integerPosition = position.integerPosition() - 1; 94 95 m_integerPosition = adjustGridPositionForSide(integerPosition, side).m_integerPosition; 96 } 83 GridResolvedPosition(const GridPosition&, GridPositionSide); 97 84 98 85 GridResolvedPosition& operator*() … … 147 134 } 148 135 136 static GridSpan resolveGridPositionsFromAutoPlacementPosition(const RenderStyle&, const RenderBox&, GridTrackSizingDirection, const GridResolvedPosition&); 137 static GridSpan resolveGridPositionsFromStyle(const GridUnresolvedSpan&, const RenderStyle&); 138 static GridUnresolvedSpan unresolvedSpanFromStyle(const RenderStyle&, const RenderBox&, GridTrackSizingDirection); 149 139 static unsigned explicitGridColumnCount(const RenderStyle&); 150 140 static unsigned explicitGridRowCount(const RenderStyle&); 151 141 152 142 private: 153 154 143 unsigned m_integerPosition; 155 144 };
Note: See TracChangeset
for help on using the changeset viewer.