Changeset 201510 in webkit
- Timestamp:
- May 31, 2016 8:17:03 AM (8 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r201501 r201510 1 2016-05-25 Sergio Villar Senin <svillar@igalia.com> 2 3 [css-grid] Empty grid without explicit tracks shouldn't have any size 4 https://bugs.webkit.org/show_bug.cgi?id=155197 5 6 Reviewed by Darin Adler. 7 8 Make sure that empty grids (and grids with one empty axis) are properly handled. Do also 9 verify that removing all the items from a grid also generates an correct empty grid. 10 11 * fast/css-grid-layout/empty-grid-expected.txt: Added. 12 * fast/css-grid-layout/empty-grid.html: Added. 13 1 14 2016-05-30 Per Arne Vollan <pvollan@apple.com> 2 15 -
trunk/Source/WebCore/ChangeLog
r201504 r201510 1 2016-05-25 Sergio Villar Senin <svillar@igalia.com> 2 3 [css-grid] Empty grid without explicit tracks shouldn't have any size 4 https://bugs.webkit.org/show_bug.cgi?id=155197 5 6 Reviewed by Darin Adler. 7 8 The internal representation of the grid is a Vector of Vector representing rows and 9 columns. Because of that it was not possible to have columns without having at least one 10 row. That forced us to have a 1x1 internal representation of the grid even if it was 11 actually empty. That works for most of the cases except when the grid is actually empty. 12 13 By changing the way we compute the sizes we can overcome that implementation 14 restriction. This allowed us also to thighten the conditions under we could use the 15 GridIterator. From now on it won't be possible to use it on empty grids so callers should 16 enforce that restriction. 17 18 A new bool was added to verify that placeItemsOnGrid() has been already called. The previous 19 code was relying on the fact that there were items in the internal representation, which is 20 wrong, as there might be no items in the grid. 21 22 Test: fast/css-grid-layout/empty-grid.html 23 24 * rendering/RenderGrid.cpp: 25 (WebCore::RenderGrid::GridIterator::GridIterator): Added ASSERTs. 26 (WebCore::RenderGrid::GridIterator::nextGridItem): Ditto. 27 (WebCore::RenderGrid::GridIterator::isEmptyAreaEnough): Ditto. 28 (WebCore::RenderGrid::GridIterator::nextEmptyGridArea): Ditto. 29 (WebCore::RenderGrid::gridColumnCount): Use the style to resolve the number of columns if 30 the internal representation is empty. 31 (WebCore::RenderGrid::gridRowCount): 32 (WebCore::RenderGrid::guttersSize): Allow to pass 0 as span, this permits using the return 33 value of gridColumnCount|gridRowCount directly to call this method. 34 (WebCore::RenderGrid::computeIntrinsicLogicalWidths): Use m_gridIsDirty. 35 (WebCore::RenderGrid::computeUsedBreadthOfGridTracks): Do not examine the contents of grid 36 tracks if there are no items in the grid. 37 (WebCore::RenderGrid::resolveContentBasedTrackSizingFunctions): Ditto. 38 (WebCore::RenderGrid::placeItemsOnGrid): Set m_gridIsDirty to false. 39 (WebCore::RenderGrid::populateExplicitGridAndOrderIterator): 40 (WebCore::RenderGrid::clearGrid): 41 (WebCore::RenderGrid::populateGridPositionsForDirection): 42 * rendering/RenderGrid.h: Moved gridColumnCount/gridRowCount to cpp file. 43 1 44 2016-05-30 Brady Eidson <beidson@apple.com> 2 45 -
trunk/Source/WebCore/rendering/RenderGrid.cpp
r201498 r201510 140 140 , m_childIndex(0) 141 141 { 142 ASSERT(!m_grid.isEmpty()); 143 ASSERT(!m_grid[0].isEmpty()); 142 144 ASSERT(m_rowIndex < m_grid.size()); 143 145 ASSERT(m_columnIndex < m_grid[0].size()); … … 146 148 RenderBox* nextGridItem() 147 149 { 148 if (!m_grid.size())149 return 0;150 ASSERT(!m_grid.isEmpty()); 151 ASSERT(!m_grid[0].isEmpty()); 150 152 151 153 unsigned& varyingTrackIndex = (m_direction == ForColumns) ? m_rowIndex : m_columnIndex; … … 163 165 bool isEmptyAreaEnough(unsigned rowSpan, unsigned columnSpan) const 164 166 { 167 ASSERT(!m_grid.isEmpty()); 168 ASSERT(!m_grid[0].isEmpty()); 169 165 170 // Ignore cells outside current grid as we will grow it later if needed. 166 171 unsigned maxRows = std::min<unsigned>(m_rowIndex + rowSpan, m_grid.size()); … … 181 186 std::unique_ptr<GridArea> nextEmptyGridArea(unsigned fixedTrackSpan, unsigned varyingTrackSpan) 182 187 { 183 ASSERT(fixedTrackSpan >= 1 && varyingTrackSpan >= 1); 188 ASSERT(!m_grid.isEmpty()); 189 ASSERT(!m_grid[0].isEmpty()); 190 ASSERT(fixedTrackSpan >= 1); 191 ASSERT(varyingTrackSpan >= 1); 184 192 185 193 if (m_grid.isEmpty()) … … 320 328 } 321 329 330 unsigned RenderGrid::gridColumnCount() const 331 { 332 ASSERT(!m_gridIsDirty); 333 // Due to limitations in our internal representation, we cannot know the number of columns from 334 // m_grid *if* there is no row (because m_grid would be empty). That's why in that case we need 335 // to get it from the style. Note that we know for sure that there are't any implicit tracks, 336 // because not having rows implies that there are no "normal" children (out-of-flow children are 337 // not stored in m_grid). 338 return m_grid.size() ? m_grid[0].size() : GridPositionsResolver::explicitGridColumnCount(style(), m_autoRepeatColumns); 339 } 340 341 unsigned RenderGrid::gridRowCount() const 342 { 343 ASSERT(!m_gridIsDirty); 344 return m_grid.size(); 345 } 346 322 347 LayoutUnit RenderGrid::computeTrackBasedLogicalHeight(const GridSizingData& sizingData) const 323 348 { … … 421 446 LayoutUnit RenderGrid::guttersSize(GridTrackSizingDirection direction, unsigned span) const 422 447 { 423 ASSERT(span >= 1); 424 425 if (span == 1) 448 if (span <= 1) 426 449 return { }; 427 450 … … 437 460 void RenderGrid::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const 438 461 { 439 bool wasPopulated = gridWasPopulated();462 bool wasPopulated = !m_gridIsDirty; 440 463 if (!wasPopulated) 441 464 const_cast<RenderGrid*>(this)->placeItemsOnGrid(); … … 590 613 flexFraction = std::max(flexFraction, normalizedFlexFraction(tracks[trackIndex], gridTrackSize(direction, trackIndex).maxTrackBreadth().flex())); 591 614 592 for (unsigned i = 0; i < flexibleSizedTracksIndex.size(); ++i) { 593 GridIterator iterator(m_grid, direction, flexibleSizedTracksIndex[i]); 594 while (RenderBox* gridItem = iterator.nextGridItem()) { 595 const GridSpan span = cachedGridSpan(*gridItem, direction); 596 597 // Do not include already processed items. 598 if (i > 0 && span.startLine() <= flexibleSizedTracksIndex[i - 1]) 599 continue; 600 601 flexFraction = std::max(flexFraction, findFlexFactorUnitSize(tracks, span, direction, maxContentForChild(*gridItem, direction, sizingData))); 615 if (!m_gridItemArea.isEmpty()) { 616 for (unsigned i = 0; i < flexibleSizedTracksIndex.size(); ++i) { 617 GridIterator iterator(m_grid, direction, flexibleSizedTracksIndex[i]); 618 while (auto* gridItem = iterator.nextGridItem()) { 619 GridSpan& span = cachedGridSpan(*gridItem, direction); 620 621 // Do not include already processed items. 622 if (i > 0 && span.startLine() <= flexibleSizedTracksIndex[i - 1]) 623 continue; 624 625 flexFraction = std::max(flexFraction, findFlexFactorUnitSize(tracks, span, direction, maxContentForChild(*gridItem, direction, sizingData))); 626 } 602 627 } 603 628 } … … 899 924 sizingData.itemsSortedByIncreasingSpan.shrink(0); 900 925 HashSet<RenderBox*> itemsSet; 901 for (auto trackIndex : sizingData.contentSizedTracksIndex) { 902 GridIterator iterator(m_grid, direction, trackIndex); 903 GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[trackIndex] : sizingData.rowTracks[trackIndex]; 904 905 while (RenderBox* gridItem = iterator.nextGridItem()) { 906 if (itemsSet.add(gridItem).isNewEntry) { 907 const GridSpan& span = cachedGridSpan(*gridItem, direction); 908 if (span.integerSpan() == 1) 909 resolveContentBasedTrackSizingFunctionsForNonSpanningItems(direction, span, *gridItem, track, sizingData); 910 else if (!spanningItemCrossesFlexibleSizedTracks(span, direction)) 911 sizingData.itemsSortedByIncreasingSpan.append(GridItemWithSpan(*gridItem, span)); 926 if (!m_gridItemArea.isEmpty()) { 927 for (auto trackIndex : sizingData.contentSizedTracksIndex) { 928 GridIterator iterator(m_grid, direction, trackIndex); 929 GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[trackIndex] : sizingData.rowTracks[trackIndex]; 930 931 while (auto* gridItem = iterator.nextGridItem()) { 932 if (itemsSet.add(gridItem).isNewEntry) { 933 GridSpan& span = cachedGridSpan(*gridItem, direction); 934 if (span.integerSpan() == 1) 935 resolveContentBasedTrackSizingFunctionsForNonSpanningItems(direction, span, *gridItem, track, sizingData); 936 else if (!spanningItemCrossesFlexibleSizedTracks(span, direction)) 937 sizingData.itemsSortedByIncreasingSpan.append(GridItemWithSpan(*gridItem, span)); 938 } 912 939 } 913 940 } 914 }915 std::sort(sizingData.itemsSortedByIncreasingSpan.begin(), sizingData.itemsSortedByIncreasingSpan.end());941 std::sort(sizingData.itemsSortedByIncreasingSpan.begin(), sizingData.itemsSortedByIncreasingSpan.end()); 942 } 916 943 917 944 auto it = sizingData.itemsSortedByIncreasingSpan.begin(); … … 1296 1323 void RenderGrid::placeItemsOnGrid() 1297 1324 { 1298 ASSERT( !gridWasPopulated());1325 ASSERT(m_gridIsDirty); 1299 1326 ASSERT(m_gridItemArea.isEmpty()); 1300 1327 … … 1303 1330 1304 1331 populateExplicitGridAndOrderIterator(); 1332 m_gridIsDirty = false; 1305 1333 1306 1334 Vector<RenderBox*> autoMajorAxisAutoGridItems; … … 1350 1378 OrderIteratorPopulator populator(m_orderIterator); 1351 1379 m_smallestRowStart = m_smallestColumnStart = 0; 1352 unsigned maximumRowIndex = std::max<unsigned>(1, GridPositionsResolver::explicitGridRowCount(style(), m_autoRepeatRows));1353 unsigned maximumColumnIndex = std::max<unsigned>(1, GridPositionsResolver::explicitGridColumnCount(style(), m_autoRepeatColumns));1380 unsigned maximumRowIndex = GridPositionsResolver::explicitGridRowCount(style(), m_autoRepeatRows); 1381 unsigned maximumColumnIndex = GridPositionsResolver::explicitGridColumnCount(style(), m_autoRepeatColumns); 1354 1382 1355 1383 for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) { … … 1511 1539 m_grid.clear(); 1512 1540 m_gridItemArea.clear(); 1541 m_gridIsDirty = true; 1513 1542 } 1514 1543 … … 1768 1797 unsigned numberOfLines = numberOfTracks + 1; 1769 1798 unsigned lastLine = numberOfLines - 1; 1770 unsigned nextToLastLine = numberOfLines - 2; 1799 1771 1800 ContentAlignmentData offset = computeContentPositionAndDistributionOffset(direction, sizingData.freeSpaceForDirection(direction).value(), numberOfTracks); 1772 1801 LayoutUnit trackGap = guttersSize(direction, 2); … … 1775 1804 auto borderAndPadding = isRowAxis ? borderAndPaddingLogicalLeft() : borderAndPaddingBefore(); 1776 1805 positions[0] = borderAndPadding + offset.positionOffset; 1777 for (unsigned i = 0; i < nextToLastLine; ++i) 1778 positions[i + 1] = positions[i] + offset.distributionOffset + tracks[i].baseSize() + trackGap; 1779 positions[lastLine] = positions[nextToLastLine] + tracks[nextToLastLine].baseSize(); 1806 if (numberOfLines > 1) { 1807 unsigned nextToLastLine = numberOfLines - 2; 1808 for (unsigned i = 0; i < nextToLastLine; ++i) 1809 positions[i + 1] = positions[i] + offset.distributionOffset + tracks[i].baseSize() + trackGap; 1810 positions[lastLine] = positions[nextToLastLine] + tracks[nextToLastLine].baseSize(); 1811 } 1780 1812 auto& offsetBetweenTracks = isRowAxis ? m_offsetBetweenColumns : m_offsetBetweenRows; 1781 1813 offsetBetweenTracks = offset.distributionOffset; -
trunk/Source/WebCore/rendering/RenderGrid.h
r201379 r201510 174 174 #endif 175 175 176 bool gridWasPopulated() const { return !m_grid.isEmpty() && !m_grid[0].isEmpty(); }177 178 176 bool spanningItemCrossesFlexibleSizedTracks(const GridSpan&, GridTrackSizingDirection) const; 179 177 180 unsigned gridColumnCount() const 181 { 182 ASSERT(gridWasPopulated()); 183 return m_grid[0].size(); 184 } 185 unsigned gridRowCount() const 186 { 187 ASSERT(gridWasPopulated()); 188 return m_grid.size(); 189 } 178 unsigned gridColumnCount() const; 179 unsigned gridRowCount() const; 190 180 191 181 bool hasDefiniteLogicalSize(GridTrackSizingDirection) const; … … 208 198 unsigned m_autoRepeatColumns { 0 }; 209 199 unsigned m_autoRepeatRows { 0 }; 200 201 bool m_gridIsDirty { true }; 210 202 }; 211 203
Note: See TracChangeset
for help on using the changeset viewer.