OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2011 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
191 return; | 191 return; |
192 } | 192 } |
193 | 193 |
194 if (style()->gridAutoFlow() != AutoFlowNone) { | 194 if (style()->gridAutoFlow() != AutoFlowNone) { |
195 // The grid needs to be recomputed as it might contain auto-placed items that will change their position. | 195 // The grid needs to be recomputed as it might contain auto-placed items that will change their position. |
196 dirtyGrid(); | 196 dirtyGrid(); |
197 return; | 197 return; |
198 } | 198 } |
199 | 199 |
200 RenderBox* newChildBox = toRenderBox(newChild); | 200 RenderBox* newChildBox = toRenderBox(newChild); |
201 OwnPtr<GridSpan> rowPositions = resolveGridPositionsFromStyle(newChildBox, F orRows); | 201 OwnPtr<GridSpan> rowPositions = GridResolvedPosition::resolveGridPositionsFr omStyle(*style(), *newChildBox, ForRows); |
202 OwnPtr<GridSpan> columnPositions = resolveGridPositionsFromStyle(newChildBox , ForColumns); | 202 OwnPtr<GridSpan> columnPositions = GridResolvedPosition::resolveGridPosition sFromStyle(*style(), *newChildBox, ForColumns); |
203 if (!rowPositions || !columnPositions) { | 203 if (!rowPositions || !columnPositions) { |
204 // The new child requires the auto-placement algorithm to run so we need to recompute the grid fully. | 204 // The new child requires the auto-placement algorithm to run so we need to recompute the grid fully. |
205 dirtyGrid(); | 205 dirtyGrid(); |
206 return; | 206 return; |
207 } else { | 207 } else { |
208 // Ensure that the grid is big enough to contain new grid item. | 208 // Ensure that the grid is big enough to contain new grid item. |
209 if (gridRowCount() <= rowPositions->finalPositionIndex) | 209 if (gridRowCount() <= rowPositions->resolvedFinalPosition) |
210 growGrid(ForRows, rowPositions->finalPositionIndex); | 210 growGrid(ForRows, rowPositions->resolvedFinalPosition); |
211 if (gridColumnCount() <= columnPositions->finalPositionIndex) | 211 if (gridColumnCount() <= columnPositions->resolvedFinalPosition) |
212 growGrid(ForColumns, columnPositions->finalPositionIndex); | 212 growGrid(ForColumns, columnPositions->resolvedFinalPosition); |
213 | 213 |
214 insertItemIntoGrid(newChildBox, GridCoordinate(*rowPositions, *columnPos itions)); | 214 insertItemIntoGrid(newChildBox, GridCoordinate(*rowPositions, *columnPos itions)); |
215 } | 215 } |
216 } | 216 } |
217 | 217 |
218 void RenderGrid::removeChild(RenderObject* child) | 218 void RenderGrid::removeChild(RenderObject* child) |
219 { | 219 { |
220 RenderBlock::removeChild(child); | 220 RenderBlock::removeChild(child); |
221 | 221 |
222 if (gridIsDirty()) | 222 if (gridIsDirty()) |
223 return; | 223 return; |
224 | 224 |
225 ASSERT(child->isBox()); | 225 ASSERT(child->isBox()); |
226 | 226 |
227 if (style()->gridAutoFlow() != AutoFlowNone) { | 227 if (style()->gridAutoFlow() != AutoFlowNone) { |
228 // The grid needs to be recomputed as it might contain auto-placed items that will change their position. | 228 // The grid needs to be recomputed as it might contain auto-placed items that will change their position. |
229 dirtyGrid(); | 229 dirtyGrid(); |
230 return; | 230 return; |
231 } | 231 } |
232 | 232 |
233 const RenderBox* childBox = toRenderBox(child); | 233 const RenderBox* childBox = toRenderBox(child); |
234 GridCoordinate coordinate = m_gridItemCoordinate.take(childBox); | 234 GridCoordinate coordinate = m_gridItemCoordinate.take(childBox); |
235 | 235 |
236 for (size_t row = coordinate.rows.initialPositionIndex; row <= coordinate.ro ws.finalPositionIndex; ++row) { | 236 for (size_t row = coordinate.rows.resolvedInitialPosition; row <= coordinate .rows.resolvedFinalPosition; ++row) { |
237 for (size_t column = coordinate.columns.initialPositionIndex; column <= coordinate.columns.finalPositionIndex; ++column) { | 237 for (size_t column = coordinate.columns.resolvedInitialPosition; column <= coordinate.columns.resolvedFinalPosition; ++column) { |
238 GridCell& cell = m_grid[row][column]; | 238 GridCell& cell = m_grid[row][column]; |
239 cell.remove(cell.find(childBox)); | 239 cell.remove(cell.find(childBox)); |
240 } | 240 } |
241 } | 241 } |
242 } | 242 } |
243 | 243 |
244 void RenderGrid::styleDidChange(StyleDifference diff, const RenderStyle* oldStyl e) | 244 void RenderGrid::styleDidChange(StyleDifference diff, const RenderStyle* oldStyl e) |
245 { | 245 { |
246 RenderBlock::styleDidChange(diff, oldStyle); | 246 RenderBlock::styleDidChange(diff, oldStyle); |
247 if (!oldStyle) | 247 if (!oldStyle) |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
429 normalizedFractionBreadth = std::max(normalizedFractionBreadth, trac ks[trackIndex].m_usedBreadth / trackSize.maxTrackBreadth().flex()); | 429 normalizedFractionBreadth = std::max(normalizedFractionBreadth, trac ks[trackIndex].m_usedBreadth / trackSize.maxTrackBreadth().flex()); |
430 } | 430 } |
431 | 431 |
432 for (size_t i = 0; i < flexibleSizedTracksIndex.size(); ++i) { | 432 for (size_t i = 0; i < flexibleSizedTracksIndex.size(); ++i) { |
433 GridIterator iterator(m_grid, direction, flexibleSizedTracksIndex[i] ); | 433 GridIterator iterator(m_grid, direction, flexibleSizedTracksIndex[i] ); |
434 while (RenderBox* gridItem = iterator.nextGridItem()) { | 434 while (RenderBox* gridItem = iterator.nextGridItem()) { |
435 const GridCoordinate coordinate = cachedGridCoordinate(gridItem) ; | 435 const GridCoordinate coordinate = cachedGridCoordinate(gridItem) ; |
436 const GridSpan span = (direction == ForColumns) ? coordinate.col umns : coordinate.rows; | 436 const GridSpan span = (direction == ForColumns) ? coordinate.col umns : coordinate.rows; |
437 | 437 |
438 // Do not include already processed items. | 438 // Do not include already processed items. |
439 if (i > 0 && span.initialPositionIndex <= flexibleSizedTracksInd ex[i - 1]) | 439 if (i > 0 && span.resolvedInitialPosition <= flexibleSizedTracks Index[i - 1]) |
440 continue; | 440 continue; |
441 | 441 |
442 double itemNormalizedFlexBreadth = computeNormalizedFractionBrea dth(tracks, span, direction, maxContentForChild(gridItem, direction, sizingData. columnTracks)); | 442 double itemNormalizedFlexBreadth = computeNormalizedFractionBrea dth(tracks, span, direction, maxContentForChild(gridItem, direction, sizingData. columnTracks)); |
443 normalizedFractionBreadth = std::max(normalizedFractionBreadth, itemNormalizedFlexBreadth); | 443 normalizedFractionBreadth = std::max(normalizedFractionBreadth, itemNormalizedFlexBreadth); |
444 } | 444 } |
445 } | 445 } |
446 } | 446 } |
447 | 447 |
448 for (size_t i = 0; i < flexibleSizedTracksIndex.size(); ++i) { | 448 for (size_t i = 0; i < flexibleSizedTracksIndex.size(); ++i) { |
449 const size_t trackIndex = flexibleSizedTracksIndex[i]; | 449 const size_t trackIndex = flexibleSizedTracksIndex[i]; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
494 static bool sortByGridNormalizedFlexValue(const GridTrackForNormalization& track 1, const GridTrackForNormalization& track2) | 494 static bool sortByGridNormalizedFlexValue(const GridTrackForNormalization& track 1, const GridTrackForNormalization& track2) |
495 { | 495 { |
496 return track1.m_normalizedFlexValue < track2.m_normalizedFlexValue; | 496 return track1.m_normalizedFlexValue < track2.m_normalizedFlexValue; |
497 } | 497 } |
498 | 498 |
499 double RenderGrid::computeNormalizedFractionBreadth(Vector<GridTrack>& tracks, c onst GridSpan& tracksSpan, GridTrackSizingDirection direction, LayoutUnit availa bleLogicalSpace) const | 499 double RenderGrid::computeNormalizedFractionBreadth(Vector<GridTrack>& tracks, c onst GridSpan& tracksSpan, GridTrackSizingDirection direction, LayoutUnit availa bleLogicalSpace) const |
500 { | 500 { |
501 // |availableLogicalSpace| already accounts for the used breadths so no need to remove it here. | 501 // |availableLogicalSpace| already accounts for the used breadths so no need to remove it here. |
502 | 502 |
503 Vector<GridTrackForNormalization> tracksForNormalization; | 503 Vector<GridTrackForNormalization> tracksForNormalization; |
504 for (size_t i = tracksSpan.initialPositionIndex; i <= tracksSpan.finalPositi onIndex; ++i) { | 504 for (GridResolvedPosition resolvedPosition = tracksSpan.resolvedInitialPosit ion; resolvedPosition <= tracksSpan.resolvedFinalPosition; ++resolvedPosition) { |
505 const GridTrackSize& trackSize = gridTrackSize(direction, i); | 505 const GridTrackSize& trackSize = gridTrackSize(direction, resolvedPositi on); |
506 if (!trackSize.maxTrackBreadth().isFlex()) | 506 if (!trackSize.maxTrackBreadth().isFlex()) |
507 continue; | 507 continue; |
508 | 508 |
509 tracksForNormalization.append(GridTrackForNormalization(tracks[i], track Size.maxTrackBreadth().flex())); | 509 tracksForNormalization.append(GridTrackForNormalization(tracks[resolvedP osition], trackSize.maxTrackBreadth().flex())); |
510 } | 510 } |
511 | 511 |
512 // The function is not called if we don't have <flex> grid tracks | 512 // The function is not called if we don't have <flex> grid tracks |
513 ASSERT(!tracksForNormalization.isEmpty()); | 513 ASSERT(!tracksForNormalization.isEmpty()); |
514 | 514 |
515 std::sort(tracksForNormalization.begin(), tracksForNormalization.end(), sort ByGridNormalizedFlexValue); | 515 std::sort(tracksForNormalization.begin(), tracksForNormalization.end(), sort ByGridNormalizedFlexValue); |
516 | 516 |
517 // These values work together: as we walk over our grid tracks, we increase fractionValueBasedOnGridItemsRatio | 517 // These values work together: as we walk over our grid tracks, we increase fractionValueBasedOnGridItemsRatio |
518 // to match a grid track's usedBreadth to <flex> ratio until the total fract ions sized grid tracks wouldn't | 518 // to match a grid track's usedBreadth to <flex> ratio until the total fract ions sized grid tracks wouldn't |
519 // fit into availableLogicalSpaceIgnoringFractionTracks. | 519 // fit into availableLogicalSpaceIgnoringFractionTracks. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
552 Length logicalSize = direction == ForColumns ? style()->logicalWidth() : style()->logicalHeight(); | 552 Length logicalSize = direction == ForColumns ? style()->logicalWidth() : style()->logicalHeight(); |
553 if (logicalSize.isIntrinsicOrAuto()) { | 553 if (logicalSize.isIntrinsicOrAuto()) { |
554 DEFINE_STATIC_LOCAL(GridTrackSize, autoTrackSize, (Length(Auto))); | 554 DEFINE_STATIC_LOCAL(GridTrackSize, autoTrackSize, (Length(Auto))); |
555 return autoTrackSize; | 555 return autoTrackSize; |
556 } | 556 } |
557 } | 557 } |
558 | 558 |
559 return trackSize; | 559 return trackSize; |
560 } | 560 } |
561 | 561 |
562 size_t RenderGrid::explicitGridColumnCount() const | |
563 { | |
564 return style()->gridTemplateColumns().size(); | |
565 } | |
566 | |
567 size_t RenderGrid::explicitGridRowCount() const | |
568 { | |
569 return style()->gridTemplateRows().size(); | |
570 } | |
571 | |
572 size_t RenderGrid::explicitGridSizeForSide(GridPositionSide side) const | |
573 { | |
574 return (side == ColumnStartSide || side == ColumnEndSide) ? explicitGridColu mnCount() : explicitGridRowCount(); | |
575 } | |
576 | |
577 LayoutUnit RenderGrid::logicalContentHeightForChild(RenderBox* child, Vector<Gri dTrack>& columnTracks) | 562 LayoutUnit RenderGrid::logicalContentHeightForChild(RenderBox* child, Vector<Gri dTrack>& columnTracks) |
578 { | 563 { |
579 SubtreeLayoutScope layoutScope(child); | 564 SubtreeLayoutScope layoutScope(child); |
580 LayoutUnit oldOverrideContainingBlockContentLogicalWidth = child->hasOverrid eContainingBlockLogicalWidth() ? child->overrideContainingBlockContentLogicalWid th() : LayoutUnit(); | 565 LayoutUnit oldOverrideContainingBlockContentLogicalWidth = child->hasOverrid eContainingBlockLogicalWidth() ? child->overrideContainingBlockContentLogicalWid th() : LayoutUnit(); |
581 LayoutUnit overrideContainingBlockContentLogicalWidth = gridAreaBreadthForCh ild(child, ForColumns, columnTracks); | 566 LayoutUnit overrideContainingBlockContentLogicalWidth = gridAreaBreadthForCh ild(child, ForColumns, columnTracks); |
582 if (child->style()->logicalHeight().isPercent() || oldOverrideContainingBloc kContentLogicalWidth != overrideContainingBlockContentLogicalWidth) | 567 if (child->style()->logicalHeight().isPercent() || oldOverrideContainingBloc kContentLogicalWidth != overrideContainingBlockContentLogicalWidth) |
583 layoutScope.setNeedsLayout(child); | 568 layoutScope.setNeedsLayout(child); |
584 | 569 |
585 child->setOverrideContainingBlockContentLogicalWidth(overrideContainingBlock ContentLogicalWidth); | 570 child->setOverrideContainingBlockContentLogicalWidth(overrideContainingBlock ContentLogicalWidth); |
586 // If |child| has a percentage logical height, we shouldn't let it override its intrinsic height, which is | 571 // If |child| has a percentage logical height, we shouldn't let it override its intrinsic height, which is |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
639 | 624 |
640 GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[i ] : sizingData.rowTracks[i]; | 625 GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[i ] : sizingData.rowTracks[i]; |
641 if (track.m_maxBreadth == infinity) | 626 if (track.m_maxBreadth == infinity) |
642 track.m_maxBreadth = track.m_usedBreadth; | 627 track.m_maxBreadth = track.m_usedBreadth; |
643 } | 628 } |
644 } | 629 } |
645 | 630 |
646 void RenderGrid::resolveContentBasedTrackSizingFunctionsForItems(GridTrackSizing Direction direction, GridSizingData& sizingData, RenderBox* gridItem, FilterFunc tion filterFunction, SizingFunction sizingFunction, AccumulatorGetter trackGette r, AccumulatorGrowFunction trackGrowthFunction) | 631 void RenderGrid::resolveContentBasedTrackSizingFunctionsForItems(GridTrackSizing Direction direction, GridSizingData& sizingData, RenderBox* gridItem, FilterFunc tion filterFunction, SizingFunction sizingFunction, AccumulatorGetter trackGette r, AccumulatorGrowFunction trackGrowthFunction) |
647 { | 632 { |
648 const GridCoordinate coordinate = cachedGridCoordinate(gridItem); | 633 const GridCoordinate coordinate = cachedGridCoordinate(gridItem); |
649 const size_t initialTrackIndex = (direction == ForColumns) ? coordinate.colu mns.initialPositionIndex : coordinate.rows.initialPositionIndex; | 634 const GridResolvedPosition initialTrackPosition = (direction == ForColumns) ? coordinate.columns.resolvedInitialPosition : coordinate.rows.resolvedInitialPo sition; |
650 const size_t finalTrackIndex = (direction == ForColumns) ? coordinate.column s.finalPositionIndex : coordinate.rows.finalPositionIndex; | 635 const GridResolvedPosition finalTrackPosition = (direction == ForColumns) ? coordinate.columns.resolvedFinalPosition : coordinate.rows.resolvedFinalPosition ; |
651 | 636 |
652 sizingData.filteredTracks.shrink(0); | 637 sizingData.filteredTracks.shrink(0); |
653 for (size_t trackIndex = initialTrackIndex; trackIndex <= finalTrackIndex; + +trackIndex) { | 638 for (GridResolvedPosition trackPosition = initialTrackPosition; trackPositio n <= finalTrackPosition; ++trackPosition) { |
654 const GridTrackSize& trackSize = gridTrackSize(direction, trackIndex); | 639 const GridTrackSize& trackSize = gridTrackSize(direction, trackPosition) ; |
655 if (!(trackSize.*filterFunction)()) | 640 if (!(trackSize.*filterFunction)()) |
656 continue; | 641 continue; |
657 | 642 |
658 GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[t rackIndex] : sizingData.rowTracks[trackIndex]; | 643 GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[t rackPosition] : sizingData.rowTracks[trackPosition]; |
659 sizingData.filteredTracks.append(&track); | 644 sizingData.filteredTracks.append(&track); |
660 } | 645 } |
661 | 646 |
662 if (sizingData.filteredTracks.isEmpty()) | 647 if (sizingData.filteredTracks.isEmpty()) |
663 return; | 648 return; |
664 | 649 |
665 LayoutUnit additionalBreadthSpace = (this->*sizingFunction)(gridItem, direct ion, sizingData.columnTracks); | 650 LayoutUnit additionalBreadthSpace = (this->*sizingFunction)(gridItem, direct ion, sizingData.columnTracks); |
666 for (size_t trackIndexForSpace = initialTrackIndex; trackIndexForSpace <= fi nalTrackIndex; ++trackIndexForSpace) { | 651 for (size_t trackIndexForSpace = initialTrackPosition; trackIndexForSpace <= finalTrackPosition; ++trackIndexForSpace) { |
667 GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[t rackIndexForSpace] : sizingData.rowTracks[trackIndexForSpace]; | 652 GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[t rackIndexForSpace] : sizingData.rowTracks[trackIndexForSpace]; |
668 additionalBreadthSpace -= (track.*trackGetter)(); | 653 additionalBreadthSpace -= (track.*trackGetter)(); |
669 } | 654 } |
670 | 655 |
671 // FIXME: We should pass different values for |tracksForGrowthAboveMaxBreadt h|. | 656 // FIXME: We should pass different values for |tracksForGrowthAboveMaxBreadt h|. |
672 distributeSpaceToTracks(sizingData.filteredTracks, &sizingData.filteredTrack s, trackGetter, trackGrowthFunction, sizingData, additionalBreadthSpace); | 657 distributeSpaceToTracks(sizingData.filteredTracks, &sizingData.filteredTrack s, trackGetter, trackGrowthFunction, sizingData, additionalBreadthSpace); |
673 } | 658 } |
674 | 659 |
675 static bool sortByGridTrackGrowthPotential(const GridTrack* track1, const GridTr ack* track2) | 660 static bool sortByGridTrackGrowthPotential(const GridTrack* track1, const GridTr ack* track2) |
676 { | 661 { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
736 ASSERT(maximumPositionIndex >= m_grid.size()); | 721 ASSERT(maximumPositionIndex >= m_grid.size()); |
737 const size_t oldRowSize = m_grid.size(); | 722 const size_t oldRowSize = m_grid.size(); |
738 m_grid.grow(maximumPositionIndex + 1); | 723 m_grid.grow(maximumPositionIndex + 1); |
739 for (size_t row = oldRowSize; row < m_grid.size(); ++row) | 724 for (size_t row = oldRowSize; row < m_grid.size(); ++row) |
740 m_grid[row].grow(m_grid[0].size()); | 725 m_grid[row].grow(m_grid[0].size()); |
741 } | 726 } |
742 } | 727 } |
743 | 728 |
744 void RenderGrid::insertItemIntoGrid(RenderBox* child, const GridCoordinate& coor dinate) | 729 void RenderGrid::insertItemIntoGrid(RenderBox* child, const GridCoordinate& coor dinate) |
745 { | 730 { |
746 for (size_t row = coordinate.rows.initialPositionIndex; row <= coordinate.ro ws.finalPositionIndex; ++row) { | 731 for (GridResolvedPosition row = coordinate.rows.resolvedInitialPosition; row <= coordinate.rows.resolvedFinalPosition; ++row) { |
747 for (size_t column = coordinate.columns.initialPositionIndex; column <= coordinate.columns.finalPositionIndex; ++column) | 732 for (GridResolvedPosition column = coordinate.columns.resolvedInitialPos ition; column <= coordinate.columns.resolvedFinalPosition; ++column) |
748 m_grid[row][column].append(child); | 733 m_grid[row][column].append(child); |
749 } | 734 } |
750 | 735 |
751 m_gridItemCoordinate.set(child, coordinate); | 736 m_gridItemCoordinate.set(child, coordinate); |
752 } | 737 } |
753 | 738 |
754 void RenderGrid::insertItemIntoGrid(RenderBox* child, size_t rowTrack, size_t co lumnTrack) | 739 void RenderGrid::insertItemIntoGrid(RenderBox* child, const GridResolvedPosition & rowTrack, const GridResolvedPosition& columnTrack) |
755 { | 740 { |
756 const GridSpan& rowSpan = resolveGridPositionsFromAutoPlacementPosition(chil d, ForRows, rowTrack); | 741 const GridSpan& rowSpan = GridResolvedPosition::resolveGridPositionsFromAuto PlacementPosition(*child, ForRows, rowTrack); |
757 const GridSpan& columnSpan = resolveGridPositionsFromAutoPlacementPosition(c hild, ForColumns, columnTrack); | 742 const GridSpan& columnSpan = GridResolvedPosition::resolveGridPositionsFromA utoPlacementPosition(*child, ForColumns, columnTrack); |
758 insertItemIntoGrid(child, GridCoordinate(rowSpan, columnSpan)); | 743 insertItemIntoGrid(child, GridCoordinate(rowSpan, columnSpan)); |
759 } | 744 } |
760 | 745 |
761 void RenderGrid::placeItemsOnGrid() | 746 void RenderGrid::placeItemsOnGrid() |
762 { | 747 { |
763 if (!gridIsDirty()) | 748 if (!gridIsDirty()) |
764 return; | 749 return; |
765 | 750 |
766 ASSERT(m_gridItemCoordinate.isEmpty()); | 751 ASSERT(m_gridItemCoordinate.isEmpty()); |
767 | 752 |
768 populateExplicitGridAndOrderIterator(); | 753 populateExplicitGridAndOrderIterator(); |
769 | 754 |
770 // We clear the dirty bit here as the grid sizes have been updated, this mea ns | 755 // We clear the dirty bit here as the grid sizes have been updated, this mea ns |
771 // that we can safely call gridRowCount() / gridColumnCount(). | 756 // that we can safely call gridRowCount() / gridColumnCount(). |
772 m_gridIsDirty = false; | 757 m_gridIsDirty = false; |
773 | 758 |
774 Vector<RenderBox*> autoMajorAxisAutoGridItems; | 759 Vector<RenderBox*> autoMajorAxisAutoGridItems; |
775 Vector<RenderBox*> specifiedMajorAxisAutoGridItems; | 760 Vector<RenderBox*> specifiedMajorAxisAutoGridItems; |
776 GridAutoFlow autoFlow = style()->gridAutoFlow(); | 761 GridAutoFlow autoFlow = style()->gridAutoFlow(); |
777 for (RenderBox* child = m_orderIterator.first(); child; child = m_orderItera tor.next()) { | 762 for (RenderBox* child = m_orderIterator.first(); child; child = m_orderItera tor.next()) { |
778 // FIXME: We never re-resolve positions if the grid is grown during auto -placement which may lead auto / <integer> | 763 // FIXME: We never re-resolve positions if the grid is grown during auto -placement which may lead auto / <integer> |
779 // positions to not match the author's intent. The specification is uncl ear on what should be done in this case. | 764 // positions to not match the author's intent. The specification is uncl ear on what should be done in this case. |
780 OwnPtr<GridSpan> rowPositions = resolveGridPositionsFromStyle(child, For Rows); | 765 OwnPtr<GridSpan> rowPositions = GridResolvedPosition::resolveGridPositio nsFromStyle(*style(), *child, ForRows); |
esprehn
2014/04/08 22:14:58
It's kind of weird that the method that creates Gr
| |
781 OwnPtr<GridSpan> columnPositions = resolveGridPositionsFromStyle(child, ForColumns); | 766 OwnPtr<GridSpan> columnPositions = GridResolvedPosition::resolveGridPosi tionsFromStyle(*style(), *child, ForColumns); |
782 if (!rowPositions || !columnPositions) { | 767 if (!rowPositions || !columnPositions) { |
783 GridSpan* majorAxisPositions = (autoPlacementMajorAxisDirection() == ForColumns) ? columnPositions.get() : rowPositions.get(); | 768 GridSpan* majorAxisPositions = (autoPlacementMajorAxisDirection() == ForColumns) ? columnPositions.get() : rowPositions.get(); |
784 if (!majorAxisPositions) | 769 if (!majorAxisPositions) |
785 autoMajorAxisAutoGridItems.append(child); | 770 autoMajorAxisAutoGridItems.append(child); |
786 else | 771 else |
787 specifiedMajorAxisAutoGridItems.append(child); | 772 specifiedMajorAxisAutoGridItems.append(child); |
788 continue; | 773 continue; |
789 } | 774 } |
790 insertItemIntoGrid(child, GridCoordinate(*rowPositions, *columnPositions )); | 775 insertItemIntoGrid(child, GridCoordinate(*rowPositions, *columnPositions )); |
791 } | 776 } |
(...skipping 11 matching lines...) Expand all Loading... | |
803 placeSpecifiedMajorAxisItemsOnGrid(specifiedMajorAxisAutoGridItems); | 788 placeSpecifiedMajorAxisItemsOnGrid(specifiedMajorAxisAutoGridItems); |
804 placeAutoMajorAxisItemsOnGrid(autoMajorAxisAutoGridItems); | 789 placeAutoMajorAxisItemsOnGrid(autoMajorAxisAutoGridItems); |
805 | 790 |
806 m_grid.shrinkToFit(); | 791 m_grid.shrinkToFit(); |
807 } | 792 } |
808 | 793 |
809 void RenderGrid::populateExplicitGridAndOrderIterator() | 794 void RenderGrid::populateExplicitGridAndOrderIterator() |
810 { | 795 { |
811 OrderIteratorPopulator populator(m_orderIterator); | 796 OrderIteratorPopulator populator(m_orderIterator); |
812 | 797 |
813 size_t maximumRowIndex = std::max<size_t>(1, explicitGridRowCount()); | 798 size_t maximumRowIndex = std::max<size_t>(1, GridResolvedPosition::explicitG ridRowCount(*style())); |
814 size_t maximumColumnIndex = std::max<size_t>(1, explicitGridColumnCount()); | 799 size_t maximumColumnIndex = std::max<size_t>(1, GridResolvedPosition::explic itGridColumnCount(*style())); |
815 | 800 |
816 for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBo x()) { | 801 for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBo x()) { |
817 populator.collectChild(child); | 802 populator.collectChild(child); |
818 | 803 |
819 // This function bypasses the cache (cachedGridCoordinate()) as it is us ed to build it. | 804 // This function bypasses the cache (cachedGridCoordinate()) as it is us ed to build it. |
820 OwnPtr<GridSpan> rowPositions = resolveGridPositionsFromStyle(child, For Rows); | 805 OwnPtr<GridSpan> rowPositions = GridResolvedPosition::resolveGridPositio nsFromStyle(*style(), *child, ForRows); |
821 OwnPtr<GridSpan> columnPositions = resolveGridPositionsFromStyle(child, ForColumns); | 806 OwnPtr<GridSpan> columnPositions = GridResolvedPosition::resolveGridPosi tionsFromStyle(*style(), *child, ForColumns); |
822 | 807 |
823 // |positions| is 0 if we need to run the auto-placement algorithm. Our estimation ignores | 808 // |positions| is 0 if we need to run the auto-placement algorithm. Our estimation ignores |
824 // this case as the auto-placement algorithm will grow the grid as neede d. | 809 // this case as the auto-placement algorithm will grow the grid as neede d. |
825 if (rowPositions) | 810 if (rowPositions) |
826 maximumRowIndex = std::max(maximumRowIndex, rowPositions->finalPosit ionIndex + 1); | 811 maximumRowIndex = std::max<size_t>(maximumRowIndex, rowPositions->re solvedFinalPosition + 1); |
827 if (columnPositions) | 812 if (columnPositions) |
828 maximumColumnIndex = std::max(maximumColumnIndex, columnPositions->f inalPositionIndex + 1); | 813 maximumColumnIndex = std::max<size_t>(maximumColumnIndex, columnPosi tions->resolvedFinalPosition + 1); |
829 } | 814 } |
830 | 815 |
831 m_grid.grow(maximumRowIndex); | 816 m_grid.grow(maximumRowIndex); |
832 for (size_t i = 0; i < m_grid.size(); ++i) | 817 for (size_t i = 0; i < m_grid.size(); ++i) |
833 m_grid[i].grow(maximumColumnIndex); | 818 m_grid[i].grow(maximumColumnIndex); |
834 } | 819 } |
835 | 820 |
836 void RenderGrid::placeSpecifiedMajorAxisItemsOnGrid(const Vector<RenderBox*>& au toGridItems) | 821 void RenderGrid::placeSpecifiedMajorAxisItemsOnGrid(const Vector<RenderBox*>& au toGridItems) |
837 { | 822 { |
838 for (size_t i = 0; i < autoGridItems.size(); ++i) { | 823 for (size_t i = 0; i < autoGridItems.size(); ++i) { |
839 OwnPtr<GridSpan> majorAxisPositions = resolveGridPositionsFromStyle(auto GridItems[i], autoPlacementMajorAxisDirection()); | 824 OwnPtr<GridSpan> majorAxisPositions = GridResolvedPosition::resolveGridP ositionsFromStyle(*style(), *autoGridItems[i], autoPlacementMajorAxisDirection() ); |
840 GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), majorAx isPositions->initialPositionIndex); | 825 GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), majorAx isPositions->resolvedInitialPosition); |
841 if (OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea()) { | 826 if (OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea()) { |
842 insertItemIntoGrid(autoGridItems[i], emptyGridArea->rows.initialPosi tionIndex, emptyGridArea->columns.initialPositionIndex); | 827 insertItemIntoGrid(autoGridItems[i], emptyGridArea->rows.resolvedIni tialPosition, emptyGridArea->columns.resolvedInitialPosition); |
843 continue; | 828 continue; |
844 } | 829 } |
845 | 830 |
846 growGrid(autoPlacementMinorAxisDirection(), autoPlacementMinorAxisDirect ion() == ForColumns ? m_grid[0].size() : m_grid.size()); | 831 growGrid(autoPlacementMinorAxisDirection(), autoPlacementMinorAxisDirect ion() == ForColumns ? m_grid[0].size() : m_grid.size()); |
847 OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea(); | 832 OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea(); |
848 ASSERT(emptyGridArea); | 833 ASSERT(emptyGridArea); |
849 insertItemIntoGrid(autoGridItems[i], emptyGridArea->rows.initialPosition Index, emptyGridArea->columns.initialPositionIndex); | 834 insertItemIntoGrid(autoGridItems[i], emptyGridArea->rows.resolvedInitial Position, emptyGridArea->columns.resolvedInitialPosition); |
850 } | 835 } |
851 } | 836 } |
852 | 837 |
853 void RenderGrid::placeAutoMajorAxisItemsOnGrid(const Vector<RenderBox*>& autoGri dItems) | 838 void RenderGrid::placeAutoMajorAxisItemsOnGrid(const Vector<RenderBox*>& autoGri dItems) |
854 { | 839 { |
855 for (size_t i = 0; i < autoGridItems.size(); ++i) | 840 for (size_t i = 0; i < autoGridItems.size(); ++i) |
856 placeAutoMajorAxisItemOnGrid(autoGridItems[i]); | 841 placeAutoMajorAxisItemOnGrid(autoGridItems[i]); |
857 } | 842 } |
858 | 843 |
859 void RenderGrid::placeAutoMajorAxisItemOnGrid(RenderBox* gridItem) | 844 void RenderGrid::placeAutoMajorAxisItemOnGrid(RenderBox* gridItem) |
860 { | 845 { |
861 OwnPtr<GridSpan> minorAxisPositions = resolveGridPositionsFromStyle(gridItem , autoPlacementMinorAxisDirection()); | 846 OwnPtr<GridSpan> minorAxisPositions = GridResolvedPosition::resolveGridPosit ionsFromStyle(*style(), *gridItem, autoPlacementMinorAxisDirection()); |
862 ASSERT(!resolveGridPositionsFromStyle(gridItem, autoPlacementMajorAxisDirect ion())); | 847 ASSERT(!GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *gridI tem, autoPlacementMajorAxisDirection())); |
863 size_t minorAxisIndex = 0; | 848 size_t minorAxisIndex = 0; |
864 if (minorAxisPositions) { | 849 if (minorAxisPositions) { |
865 minorAxisIndex = minorAxisPositions->initialPositionIndex; | 850 minorAxisIndex = minorAxisPositions->resolvedInitialPosition; |
866 GridIterator iterator(m_grid, autoPlacementMinorAxisDirection(), minorAx isIndex); | 851 GridIterator iterator(m_grid, autoPlacementMinorAxisDirection(), minorAx isIndex); |
867 if (OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea()) { | 852 if (OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea()) { |
868 insertItemIntoGrid(gridItem, emptyGridArea->rows.initialPositionInde x, emptyGridArea->columns.initialPositionIndex); | 853 insertItemIntoGrid(gridItem, emptyGridArea->rows.resolvedInitialPosi tion, emptyGridArea->columns.resolvedInitialPosition); |
869 return; | 854 return; |
870 } | 855 } |
871 } else { | 856 } else { |
872 const size_t endOfMajorAxis = (autoPlacementMajorAxisDirection() == ForC olumns) ? gridColumnCount() : gridRowCount(); | 857 const size_t endOfMajorAxis = (autoPlacementMajorAxisDirection() == ForC olumns) ? gridColumnCount() : gridRowCount(); |
873 for (size_t majorAxisIndex = 0; majorAxisIndex < endOfMajorAxis; ++major AxisIndex) { | 858 for (size_t majorAxisIndex = 0; majorAxisIndex < endOfMajorAxis; ++major AxisIndex) { |
874 GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), maj orAxisIndex); | 859 GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), maj orAxisIndex); |
875 if (OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridAre a()) { | 860 if (OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridAre a()) { |
876 insertItemIntoGrid(gridItem, emptyGridArea->rows.initialPosition Index, emptyGridArea->columns.initialPositionIndex); | 861 insertItemIntoGrid(gridItem, emptyGridArea->rows.resolvedInitial Position, emptyGridArea->columns.resolvedInitialPosition); |
877 return; | 862 return; |
878 } | 863 } |
879 } | 864 } |
880 } | 865 } |
881 | 866 |
882 // We didn't find an empty grid area so we need to create an extra major axi s line and insert our gridItem in it. | 867 // We didn't find an empty grid area so we need to create an extra major axi s line and insert our gridItem in it. |
883 const size_t columnIndex = (autoPlacementMajorAxisDirection() == ForColumns) ? m_grid[0].size() : minorAxisIndex; | 868 const size_t columnIndex = (autoPlacementMajorAxisDirection() == ForColumns) ? m_grid[0].size() : minorAxisIndex; |
884 const size_t rowIndex = (autoPlacementMajorAxisDirection() == ForColumns) ? minorAxisIndex : m_grid.size(); | 869 const size_t rowIndex = (autoPlacementMajorAxisDirection() == ForColumns) ? minorAxisIndex : m_grid.size(); |
885 growGrid(autoPlacementMajorAxisDirection(), autoPlacementMajorAxisDirection( ) == ForColumns ? m_grid[0].size() : m_grid.size()); | 870 growGrid(autoPlacementMajorAxisDirection(), autoPlacementMajorAxisDirection( ) == ForColumns ? m_grid[0].size() : m_grid.size()); |
886 insertItemIntoGrid(gridItem, rowIndex, columnIndex); | 871 insertItemIntoGrid(gridItem, rowIndex, columnIndex); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
941 | 926 |
942 LayoutRect oldChildRect = child->frameRect(); | 927 LayoutRect oldChildRect = child->frameRect(); |
943 | 928 |
944 // FIXME: Grid items should stretch to fill their cells. Once we | 929 // FIXME: Grid items should stretch to fill their cells. Once we |
945 // implement grid-{column,row}-align, we can also shrink to fit. For | 930 // implement grid-{column,row}-align, we can also shrink to fit. For |
946 // now, just size as if we were a regular child. | 931 // now, just size as if we were a regular child. |
947 child->layoutIfNeeded(); | 932 child->layoutIfNeeded(); |
948 | 933 |
949 #ifndef NDEBUG | 934 #ifndef NDEBUG |
950 const GridCoordinate& coordinate = cachedGridCoordinate(child); | 935 const GridCoordinate& coordinate = cachedGridCoordinate(child); |
951 ASSERT(coordinate.columns.initialPositionIndex < sizingData.columnTracks .size()); | 936 ASSERT(coordinate.columns.resolvedInitialPosition < sizingData.columnTra cks.size()); |
952 ASSERT(coordinate.rows.initialPositionIndex < sizingData.rowTracks.size( )); | 937 ASSERT(coordinate.rows.resolvedInitialPosition < sizingData.rowTracks.si ze()); |
953 #endif | 938 #endif |
954 child->setLogicalLocation(findChildLogicalPosition(child)); | 939 child->setLogicalLocation(findChildLogicalPosition(child)); |
955 | 940 |
956 // Keep track of children overflowing their grid area as we might need t o paint them even if the grid-area is | 941 // Keep track of children overflowing their grid area as we might need t o paint them even if the grid-area is |
957 // not visible | 942 // not visible |
958 if (child->logicalHeight() > overrideContainingBlockContentLogicalHeight | 943 if (child->logicalHeight() > overrideContainingBlockContentLogicalHeight |
959 || child->logicalWidth() > overrideContainingBlockContentLogicalWidt h) | 944 || child->logicalWidth() > overrideContainingBlockContentLogicalWidt h) |
960 m_gridItemsOverflowingGridArea.append(child); | 945 m_gridItemsOverflowingGridArea.append(child); |
961 | 946 |
962 // If the child moved, we have to repaint it as well as any floating/pos itioned | 947 // If the child moved, we have to repaint it as well as any floating/pos itioned |
(...skipping 10 matching lines...) Expand all Loading... | |
973 | 958 |
974 setLogicalHeight(logicalHeight() + borderAndPaddingLogicalHeight()); | 959 setLogicalHeight(logicalHeight() + borderAndPaddingLogicalHeight()); |
975 } | 960 } |
976 | 961 |
977 GridCoordinate RenderGrid::cachedGridCoordinate(const RenderBox* gridItem) const | 962 GridCoordinate RenderGrid::cachedGridCoordinate(const RenderBox* gridItem) const |
978 { | 963 { |
979 ASSERT(m_gridItemCoordinate.contains(gridItem)); | 964 ASSERT(m_gridItemCoordinate.contains(gridItem)); |
980 return m_gridItemCoordinate.get(gridItem); | 965 return m_gridItemCoordinate.get(gridItem); |
981 } | 966 } |
982 | 967 |
983 GridSpan RenderGrid::resolveGridPositionsFromAutoPlacementPosition(const RenderB ox*, GridTrackSizingDirection, size_t initialPosition) const | |
984 { | |
985 // FIXME: We don't support spanning with auto positions yet. Once we do, thi s is wrong. Also we should make | |
986 // sure the grid can accomodate the new item as we only grow 1 position in a given direction. | |
987 return GridSpan(initialPosition, initialPosition); | |
988 } | |
989 | |
990 PassOwnPtr<GridSpan> RenderGrid::resolveGridPositionsFromStyle(const RenderBox* gridItem, GridTrackSizingDirection direction) const | |
991 { | |
992 GridPosition initialPosition = (direction == ForColumns) ? gridItem->style() ->gridColumnStart() : gridItem->style()->gridRowStart(); | |
993 const GridPositionSide initialPositionSide = (direction == ForColumns) ? Col umnStartSide : RowStartSide; | |
994 GridPosition finalPosition = (direction == ForColumns) ? gridItem->style()-> gridColumnEnd() : gridItem->style()->gridRowEnd(); | |
995 const GridPositionSide finalPositionSide = (direction == ForColumns) ? Colum nEndSide : RowEndSide; | |
996 | |
997 // We must handle the placement error handling code here instead of in the S tyleAdjuster because we don't want to | |
998 // overwrite the specified values. | |
999 if (initialPosition.isSpan() && finalPosition.isSpan()) | |
1000 finalPosition.setAutoPosition(); | |
1001 | |
1002 if (initialPosition.isNamedGridArea() && !style()->namedGridArea().contains( initialPosition.namedGridLine())) | |
1003 initialPosition.setAutoPosition(); | |
1004 | |
1005 if (finalPosition.isNamedGridArea() && !style()->namedGridArea().contains(fi nalPosition.namedGridLine())) | |
1006 finalPosition.setAutoPosition(); | |
1007 | |
1008 if (initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPositi on.shouldBeResolvedAgainstOppositePosition()) { | |
1009 if (style()->gridAutoFlow() == AutoFlowNone) | |
1010 return adoptPtr(new GridSpan(0, 0)); | |
1011 | |
1012 // We can't get our grid positions without running the auto placement al gorithm. | |
1013 return nullptr; | |
1014 } | |
1015 | |
1016 if (initialPosition.shouldBeResolvedAgainstOppositePosition()) { | |
1017 // Infer the position from the final position ('auto / 1' or 'span 2 / 3 ' case). | |
1018 const size_t finalResolvedPosition = resolveGridPositionFromStyle(finalP osition, finalPositionSide); | |
1019 return resolveGridPositionAgainstOppositePosition(finalResolvedPosition, initialPosition, initialPositionSide); | |
1020 } | |
1021 | |
1022 if (finalPosition.shouldBeResolvedAgainstOppositePosition()) { | |
1023 // Infer our position from the initial position ('1 / auto' or '3 / span 2' case). | |
1024 const size_t initialResolvedPosition = resolveGridPositionFromStyle(init ialPosition, initialPositionSide); | |
1025 return resolveGridPositionAgainstOppositePosition(initialResolvedPositio n, finalPosition, finalPositionSide); | |
1026 } | |
1027 | |
1028 size_t resolvedInitialPosition = resolveGridPositionFromStyle(initialPositio n, initialPositionSide); | |
1029 size_t resolvedFinalPosition = resolveGridPositionFromStyle(finalPosition, f inalPositionSide); | |
1030 | |
1031 // If 'grid-after' specifies a line at or before that specified by 'grid-bef ore', it computes to 'span 1'. | |
1032 if (resolvedFinalPosition < resolvedInitialPosition) | |
1033 resolvedFinalPosition = resolvedInitialPosition; | |
1034 | |
1035 return adoptPtr(new GridSpan(resolvedInitialPosition, resolvedFinalPosition) ); | |
1036 } | |
1037 | |
1038 size_t RenderGrid::resolveNamedGridLinePositionFromStyle(const GridPosition& pos ition, GridPositionSide side) const | |
1039 { | |
1040 ASSERT(!position.namedGridLine().isNull()); | |
1041 | |
1042 const NamedGridLinesMap& gridLinesNames = (side == ColumnStartSide || side = = ColumnEndSide) ? style()->namedGridColumnLines() : style()->namedGridRowLines( ); | |
1043 NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGri dLine()); | |
1044 if (it == gridLinesNames.end()) { | |
1045 if (position.isPositive()) | |
1046 return 0; | |
1047 const size_t lastLine = explicitGridSizeForSide(side); | |
1048 return GridPosition::adjustGridPositionForSide(lastLine, side); | |
1049 } | |
1050 | |
1051 size_t namedGridLineIndex; | |
1052 if (position.isPositive()) | |
1053 namedGridLineIndex = std::min<size_t>(position.integerPosition(), it->va lue.size()) - 1; | |
1054 else | |
1055 namedGridLineIndex = std::max<int>(it->value.size() - abs(position.integ erPosition()), 0); | |
1056 return GridPosition::adjustGridPositionForSide(it->value[namedGridLineIndex] , side); | |
1057 } | |
1058 | |
1059 size_t RenderGrid::resolveGridPositionFromStyle(const GridPosition& position, Gr idPositionSide side) const | |
1060 { | |
1061 switch (position.type()) { | |
1062 case ExplicitPosition: { | |
1063 ASSERT(position.integerPosition()); | |
1064 | |
1065 if (!position.namedGridLine().isNull()) | |
1066 return resolveNamedGridLinePositionFromStyle(position, side); | |
1067 | |
1068 // Handle <integer> explicit position. | |
1069 if (position.isPositive()) | |
1070 return GridPosition::adjustGridPositionForSide(position.integerPosit ion() - 1, side); | |
1071 | |
1072 size_t resolvedPosition = abs(position.integerPosition()) - 1; | |
1073 const size_t endOfTrack = explicitGridSizeForSide(side); | |
1074 | |
1075 // Per http://lists.w3.org/Archives/Public/www-style/2013Mar/0589.html, we clamp negative value to the first line. | |
1076 if (endOfTrack < resolvedPosition) | |
1077 return 0; | |
1078 | |
1079 return GridPosition::adjustGridPositionForSide(endOfTrack - resolvedPosi tion, side); | |
1080 } | |
1081 case NamedGridAreaPosition: | |
1082 { | |
1083 NamedGridAreaMap::const_iterator it = style()->namedGridArea().find(posi tion.namedGridLine()); | |
1084 // Unknown grid area should have been computed to 'auto' by now. | |
1085 ASSERT_WITH_SECURITY_IMPLICATION(it != style()->namedGridArea().end()); | |
1086 const GridCoordinate& gridAreaCoordinate = it->value; | |
1087 switch (side) { | |
1088 case ColumnStartSide: | |
1089 return gridAreaCoordinate.columns.initialPositionIndex; | |
1090 case ColumnEndSide: | |
1091 return gridAreaCoordinate.columns.finalPositionIndex; | |
1092 case RowStartSide: | |
1093 return gridAreaCoordinate.rows.initialPositionIndex; | |
1094 case RowEndSide: | |
1095 return gridAreaCoordinate.rows.finalPositionIndex; | |
1096 } | |
1097 ASSERT_NOT_REACHED(); | |
1098 return 0; | |
1099 } | |
1100 case AutoPosition: | |
1101 case SpanPosition: | |
1102 // 'auto' and span depend on the opposite position for resolution (e.g. grid-row: auto / 1 or grid-column: span 3 / "myHeader"). | |
1103 ASSERT_NOT_REACHED(); | |
1104 return 0; | |
1105 } | |
1106 ASSERT_NOT_REACHED(); | |
1107 return 0; | |
1108 } | |
1109 | |
1110 PassOwnPtr<GridSpan> RenderGrid::resolveGridPositionAgainstOppositePosition(size _t resolvedOppositePosition, const GridPosition& position, GridPositionSide side ) const | |
1111 { | |
1112 if (position.isAuto()) | |
1113 return GridSpan::create(resolvedOppositePosition, resolvedOppositePositi on); | |
1114 | |
1115 ASSERT(position.isSpan()); | |
1116 ASSERT(position.spanPosition() > 0); | |
1117 | |
1118 if (!position.namedGridLine().isNull()) { | |
1119 // span 2 'c' -> we need to find the appropriate grid line before / afte r our opposite position. | |
1120 return resolveNamedGridLinePositionAgainstOppositePosition(resolvedOppos itePosition, position, side); | |
1121 } | |
1122 | |
1123 return GridSpan::createWithSpanAgainstOpposite(resolvedOppositePosition, pos ition, side); | |
1124 } | |
1125 | |
1126 PassOwnPtr<GridSpan> RenderGrid::resolveNamedGridLinePositionAgainstOppositePosi tion(size_t resolvedOppositePosition, const GridPosition& position, GridPosition Side side) const | |
1127 { | |
1128 ASSERT(position.isSpan()); | |
1129 ASSERT(!position.namedGridLine().isNull()); | |
1130 // Negative positions are not allowed per the specification and should have been handled during parsing. | |
1131 ASSERT(position.spanPosition() > 0); | |
1132 | |
1133 const NamedGridLinesMap& gridLinesNames = (side == ColumnStartSide || side = = ColumnEndSide) ? style()->namedGridColumnLines() : style()->namedGridRowLines( ); | |
1134 NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGri dLine()); | |
1135 | |
1136 // 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). | |
1137 // See http://lists.w3.org/Archives/Public/www-style/2013Jun/0394.html. | |
1138 if (it == gridLinesNames.end()) | |
1139 return GridSpan::create(resolvedOppositePosition, resolvedOppositePositi on); | |
1140 | |
1141 return GridSpan::createWithNamedSpanAgainstOpposite(resolvedOppositePosition , position, side, it->value); | |
1142 } | |
1143 | |
1144 LayoutUnit RenderGrid::gridAreaBreadthForChild(const RenderBox* child, GridTrack SizingDirection direction, const Vector<GridTrack>& tracks) const | 968 LayoutUnit RenderGrid::gridAreaBreadthForChild(const RenderBox* child, GridTrack SizingDirection direction, const Vector<GridTrack>& tracks) const |
1145 { | 969 { |
1146 const GridCoordinate& coordinate = cachedGridCoordinate(child); | 970 const GridCoordinate& coordinate = cachedGridCoordinate(child); |
1147 const GridSpan& span = (direction == ForColumns) ? coordinate.columns : coor dinate.rows; | 971 const GridSpan& span = (direction == ForColumns) ? coordinate.columns : coor dinate.rows; |
1148 LayoutUnit gridAreaBreadth = 0; | 972 LayoutUnit gridAreaBreadth = 0; |
1149 for (size_t trackIndex = span.initialPositionIndex; trackIndex <= span.final PositionIndex; ++trackIndex) | 973 for (GridResolvedPosition trackPosition = span.resolvedInitialPosition; trac kPosition <= span.resolvedFinalPosition; ++trackPosition) |
1150 gridAreaBreadth += tracks[trackIndex].m_usedBreadth; | 974 gridAreaBreadth += tracks[trackPosition].m_usedBreadth; |
1151 return gridAreaBreadth; | 975 return gridAreaBreadth; |
1152 } | 976 } |
1153 | 977 |
1154 void RenderGrid::populateGridPositions(const GridSizingData& sizingData) | 978 void RenderGrid::populateGridPositions(const GridSizingData& sizingData) |
1155 { | 979 { |
1156 m_columnPositions.resize(sizingData.columnTracks.size() + 1); | 980 m_columnPositions.resize(sizingData.columnTracks.size() + 1); |
1157 m_columnPositions[0] = borderAndPaddingStart(); | 981 m_columnPositions[0] = borderAndPaddingStart(); |
1158 for (size_t i = 0; i < m_columnPositions.size() - 1; ++i) | 982 for (size_t i = 0; i < m_columnPositions.size() - 1; ++i) |
1159 m_columnPositions[i + 1] = m_columnPositions[i] + sizingData.columnTrack s[i].m_usedBreadth; | 983 m_columnPositions[i + 1] = m_columnPositions[i] + sizingData.columnTrack s[i].m_usedBreadth; |
1160 | 984 |
1161 m_rowPositions.resize(sizingData.rowTracks.size() + 1); | 985 m_rowPositions.resize(sizingData.rowTracks.size() + 1); |
1162 m_rowPositions[0] = borderAndPaddingBefore(); | 986 m_rowPositions[0] = borderAndPaddingBefore(); |
1163 for (size_t i = 0; i < m_rowPositions.size() - 1; ++i) | 987 for (size_t i = 0; i < m_rowPositions.size() - 1; ++i) |
1164 m_rowPositions[i + 1] = m_rowPositions[i] + sizingData.rowTracks[i].m_us edBreadth; | 988 m_rowPositions[i + 1] = m_rowPositions[i] + sizingData.rowTracks[i].m_us edBreadth; |
1165 } | 989 } |
1166 | 990 |
1167 LayoutUnit RenderGrid::startOfColumnForChild(const RenderBox* child) const | 991 LayoutUnit RenderGrid::startOfColumnForChild(const RenderBox* child) const |
1168 { | 992 { |
1169 const GridCoordinate& coordinate = cachedGridCoordinate(child); | 993 const GridCoordinate& coordinate = cachedGridCoordinate(child); |
1170 LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.initialPosit ionIndex]; | 994 LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.resolvedInit ialPosition]; |
1171 // The grid items should be inside the grid container's border box, that's w hy they need to be shifted. | 995 // The grid items should be inside the grid container's border box, that's w hy they need to be shifted. |
1172 // FIXME: This should account for the grid item's <overflow-position>. | 996 // FIXME: This should account for the grid item's <overflow-position>. |
1173 return startOfColumn + marginStartForChild(child); | 997 return startOfColumn + marginStartForChild(child); |
1174 } | 998 } |
1175 | 999 |
1176 LayoutUnit RenderGrid::endOfColumnForChild(const RenderBox* child) const | 1000 LayoutUnit RenderGrid::endOfColumnForChild(const RenderBox* child) const |
1177 { | 1001 { |
1178 const GridCoordinate& coordinate = cachedGridCoordinate(child); | 1002 const GridCoordinate& coordinate = cachedGridCoordinate(child); |
1179 LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.initialPosit ionIndex]; | 1003 LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.resolvedInit ialPosition]; |
1180 // The grid items should be inside the grid container's border box, that's w hy they need to be shifted. | 1004 // The grid items should be inside the grid container's border box, that's w hy they need to be shifted. |
1181 LayoutUnit columnPosition = startOfColumn + marginStartForChild(child); | 1005 LayoutUnit columnPosition = startOfColumn + marginStartForChild(child); |
1182 | 1006 |
1183 LayoutUnit endOfColumn = m_columnPositions[coordinate.columns.finalPositionI ndex + 1]; | 1007 LayoutUnit endOfColumn = m_columnPositions[coordinate.columns.resolvedFinalP osition + 1]; |
1184 // FIXME: This should account for the grid item's <overflow-position>. | 1008 // FIXME: This should account for the grid item's <overflow-position>. |
1185 return columnPosition + std::max<LayoutUnit>(0, endOfColumn - m_columnPositi ons[coordinate.columns.initialPositionIndex] - child->logicalWidth()); | 1009 return columnPosition + std::max<LayoutUnit>(0, endOfColumn - m_columnPositi ons[coordinate.columns.resolvedInitialPosition] - child->logicalWidth()); |
1186 } | 1010 } |
1187 | 1011 |
1188 LayoutUnit RenderGrid::columnPositionAlignedWithGridContainerStart(const RenderB ox* child) const | 1012 LayoutUnit RenderGrid::columnPositionAlignedWithGridContainerStart(const RenderB ox* child) const |
1189 { | 1013 { |
1190 if (style()->isLeftToRightDirection()) | 1014 if (style()->isLeftToRightDirection()) |
1191 return startOfColumnForChild(child); | 1015 return startOfColumnForChild(child); |
1192 | 1016 |
1193 return endOfColumnForChild(child); | 1017 return endOfColumnForChild(child); |
1194 } | 1018 } |
1195 | 1019 |
1196 LayoutUnit RenderGrid::columnPositionAlignedWithGridContainerEnd(const RenderBox * child) const | 1020 LayoutUnit RenderGrid::columnPositionAlignedWithGridContainerEnd(const RenderBox * child) const |
1197 { | 1021 { |
1198 if (!style()->isLeftToRightDirection()) | 1022 if (!style()->isLeftToRightDirection()) |
1199 return startOfColumnForChild(child); | 1023 return startOfColumnForChild(child); |
1200 | 1024 |
1201 return endOfColumnForChild(child); | 1025 return endOfColumnForChild(child); |
1202 } | 1026 } |
1203 | 1027 |
1204 LayoutUnit RenderGrid::centeredColumnPositionForChild(const RenderBox* child) co nst | 1028 LayoutUnit RenderGrid::centeredColumnPositionForChild(const RenderBox* child) co nst |
1205 { | 1029 { |
1206 const GridCoordinate& coordinate = cachedGridCoordinate(child); | 1030 const GridCoordinate& coordinate = cachedGridCoordinate(child); |
1207 LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.initialPosit ionIndex]; | 1031 LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.resolvedInit ialPosition]; |
1208 LayoutUnit endOfColumn = m_columnPositions[coordinate.columns.finalPositionI ndex + 1]; | 1032 LayoutUnit endOfColumn = m_columnPositions[coordinate.columns.resolvedFinalP osition + 1]; |
1209 LayoutUnit columnPosition = startOfColumn + marginStartForChild(child); | 1033 LayoutUnit columnPosition = startOfColumn + marginStartForChild(child); |
1210 return columnPosition + std::max<LayoutUnit>(0, endOfColumn - startOfColumn - child->logicalWidth()) / 2; | 1034 return columnPosition + std::max<LayoutUnit>(0, endOfColumn - startOfColumn - child->logicalWidth()) / 2; |
1211 } | 1035 } |
1212 | 1036 |
1213 LayoutUnit RenderGrid::columnPositionForChild(const RenderBox* child) const | 1037 LayoutUnit RenderGrid::columnPositionForChild(const RenderBox* child) const |
1214 { | 1038 { |
1215 ItemPosition childJustifySelf = child->style()->justifySelf(); | 1039 ItemPosition childJustifySelf = child->style()->justifySelf(); |
1216 switch (childJustifySelf) { | 1040 switch (childJustifySelf) { |
1217 case ItemPositionSelfStart: | 1041 case ItemPositionSelfStart: |
1218 // self-start is based on the child's direction. That's why we need to c heck against the grid container's direction. | 1042 // self-start is based on the child's direction. That's why we need to c heck against the grid container's direction. |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1267 | 1091 |
1268 ASSERT_NOT_REACHED(); | 1092 ASSERT_NOT_REACHED(); |
1269 return 0; | 1093 return 0; |
1270 } | 1094 } |
1271 | 1095 |
1272 LayoutUnit RenderGrid::rowPositionForChild(const RenderBox* child) const | 1096 LayoutUnit RenderGrid::rowPositionForChild(const RenderBox* child) const |
1273 { | 1097 { |
1274 const GridCoordinate& coordinate = cachedGridCoordinate(child); | 1098 const GridCoordinate& coordinate = cachedGridCoordinate(child); |
1275 | 1099 |
1276 // The grid items should be inside the grid container's border box, that's w hy they need to be shifted. | 1100 // The grid items should be inside the grid container's border box, that's w hy they need to be shifted. |
1277 LayoutUnit startOfRow = m_rowPositions[coordinate.rows.initialPositionIndex] ; | 1101 LayoutUnit startOfRow = m_rowPositions[coordinate.rows.resolvedInitialPositi on]; |
1278 LayoutUnit rowPosition = startOfRow + marginBeforeForChild(child); | 1102 LayoutUnit rowPosition = startOfRow + marginBeforeForChild(child); |
1279 | 1103 |
1280 // FIXME: This function should account for 'align-self'. | 1104 // FIXME: This function should account for 'align-self'. |
1281 | 1105 |
1282 return rowPosition; | 1106 return rowPosition; |
1283 } | 1107 } |
1284 | 1108 |
1285 LayoutPoint RenderGrid::findChildLogicalPosition(const RenderBox* child) const | 1109 LayoutPoint RenderGrid::findChildLogicalPosition(const RenderBox* child) const |
1286 { | 1110 { |
1287 return LayoutPoint(columnPositionForChild(child), rowPositionForChild(child) ); | 1111 return LayoutPoint(columnPositionForChild(child), rowPositionForChild(child) ); |
(...skipping 14 matching lines...) Expand all Loading... | |
1302 | 1126 |
1303 class GridCoordinateSorter { | 1127 class GridCoordinateSorter { |
1304 public: | 1128 public: |
1305 GridCoordinateSorter(RenderGrid* renderer) : m_renderer(renderer) { } | 1129 GridCoordinateSorter(RenderGrid* renderer) : m_renderer(renderer) { } |
1306 | 1130 |
1307 bool operator()(const RenderBox* firstItem, const RenderBox* secondItem) con st | 1131 bool operator()(const RenderBox* firstItem, const RenderBox* secondItem) con st |
1308 { | 1132 { |
1309 GridCoordinate first = m_renderer->cachedGridCoordinate(firstItem); | 1133 GridCoordinate first = m_renderer->cachedGridCoordinate(firstItem); |
1310 GridCoordinate second = m_renderer->cachedGridCoordinate(secondItem); | 1134 GridCoordinate second = m_renderer->cachedGridCoordinate(secondItem); |
1311 | 1135 |
1312 if (first.rows.initialPositionIndex < second.rows.initialPositionIndex) | 1136 if (first.rows.resolvedInitialPosition < second.rows.resolvedInitialPosi tion) |
1313 return true; | 1137 return true; |
1314 if (first.rows.initialPositionIndex > second.rows.initialPositionIndex) | 1138 if (first.rows.resolvedInitialPosition > second.rows.resolvedInitialPosi tion) |
1315 return false; | 1139 return false; |
1316 return first.columns.finalPositionIndex < second.columns.finalPositionIn dex; | 1140 return first.columns.resolvedFinalPosition < second.columns.resolvedFina lPosition; |
1317 } | 1141 } |
1318 private: | 1142 private: |
1319 RenderGrid* m_renderer; | 1143 RenderGrid* m_renderer; |
1320 }; | 1144 }; |
1321 | 1145 |
1322 static inline bool isInSameRowBeforeDirtyArea(const GridCoordinate& coordinate, size_t row, const GridSpan& dirtiedColumns) | 1146 static inline bool isInSameRowBeforeDirtyArea(const GridCoordinate& coordinate, const GridResolvedPosition& row, const GridSpan& dirtiedColumns) |
1323 { | 1147 { |
1324 return coordinate.rows.initialPositionIndex == row && coordinate.columns.ini tialPositionIndex < dirtiedColumns.initialPositionIndex; | 1148 return coordinate.rows.resolvedInitialPosition == row && coordinate.columns. resolvedInitialPosition < dirtiedColumns.resolvedInitialPosition; |
1325 } | 1149 } |
1326 | 1150 |
1327 static inline bool isInSameRowAfterDirtyArea(const GridCoordinate& coordinate, s ize_t row, const GridSpan& dirtiedColumns) | 1151 static inline bool isInSameRowAfterDirtyArea(const GridCoordinate& coordinate, c onst GridResolvedPosition& row, const GridSpan& dirtiedColumns) |
1328 { | 1152 { |
1329 return coordinate.rows.initialPositionIndex == row && coordinate.columns.ini tialPositionIndex >= dirtiedColumns.finalPositionIndex; | 1153 return coordinate.rows.resolvedInitialPosition == row && coordinate.columns. resolvedInitialPosition >= dirtiedColumns.resolvedFinalPosition; |
1330 } | 1154 } |
1331 | 1155 |
1332 static inline bool rowIsBeforeDirtyArea(const GridCoordinate& coordinate, const GridSpan& dirtiedRows) | 1156 static inline bool rowIsBeforeDirtyArea(const GridCoordinate& coordinate, const GridSpan& dirtiedRows) |
1333 { | 1157 { |
1334 return coordinate.rows.initialPositionIndex < dirtiedRows.initialPositionInd ex; | 1158 return coordinate.rows.resolvedInitialPosition < dirtiedRows.resolvedInitial Position; |
1335 } | 1159 } |
1336 | 1160 |
1337 void RenderGrid::paintChildren(PaintInfo& paintInfo, const LayoutPoint& paintOff set) | 1161 void RenderGrid::paintChildren(PaintInfo& paintInfo, const LayoutPoint& paintOff set) |
1338 { | 1162 { |
1339 ASSERT_WITH_SECURITY_IMPLICATION(!gridIsDirty()); | 1163 ASSERT_WITH_SECURITY_IMPLICATION(!gridIsDirty()); |
1340 | 1164 |
1341 LayoutRect localRepaintRect = paintInfo.rect; | 1165 LayoutRect localRepaintRect = paintInfo.rect; |
1342 localRepaintRect.moveBy(-paintOffset); | 1166 localRepaintRect.moveBy(-paintOffset); |
1343 | 1167 |
1344 GridSpan dirtiedColumns = dirtiedGridAreas(m_columnPositions, localRepaintRe ct.x(), localRepaintRect.maxX()); | 1168 GridSpan dirtiedColumns = dirtiedGridAreas(m_columnPositions, localRepaintRe ct.x(), localRepaintRect.maxX()); |
1345 GridSpan dirtiedRows = dirtiedGridAreas(m_rowPositions, localRepaintRect.y() , localRepaintRect.maxY()); | 1169 GridSpan dirtiedRows = dirtiedGridAreas(m_rowPositions, localRepaintRect.y() , localRepaintRect.maxY()); |
1346 | 1170 |
1347 // Sort the overflowing grid items according to their positions in the grid. We collect items during the layout | 1171 // Sort the overflowing grid items according to their positions in the grid. We collect items during the layout |
1348 // process following DOM's order but we have to paint following grid's. | 1172 // process following DOM's order but we have to paint following grid's. |
1349 std::stable_sort(m_gridItemsOverflowingGridArea.begin(), m_gridItemsOverflow ingGridArea.end(), GridCoordinateSorter(this)); | 1173 std::stable_sort(m_gridItemsOverflowingGridArea.begin(), m_gridItemsOverflow ingGridArea.end(), GridCoordinateSorter(this)); |
1350 | 1174 |
1351 OrderIterator paintIterator(this); | 1175 OrderIterator paintIterator(this); |
1352 { | 1176 { |
1353 OrderIteratorPopulator populator(paintIterator); | 1177 OrderIteratorPopulator populator(paintIterator); |
1354 Vector<RenderBox*>::const_iterator overflowIterator = m_gridItemsOverflo wingGridArea.begin(); | 1178 Vector<RenderBox*>::const_iterator overflowIterator = m_gridItemsOverflo wingGridArea.begin(); |
1355 Vector<RenderBox*>::const_iterator end = m_gridItemsOverflowingGridArea. end(); | 1179 Vector<RenderBox*>::const_iterator end = m_gridItemsOverflowingGridArea. end(); |
1356 | 1180 |
1357 for (; overflowIterator != end && rowIsBeforeDirtyArea(cachedGridCoordin ate(*overflowIterator), dirtiedRows); ++overflowIterator) { | 1181 for (; overflowIterator != end && rowIsBeforeDirtyArea(cachedGridCoordin ate(*overflowIterator), dirtiedRows); ++overflowIterator) { |
1358 if ((*overflowIterator)->frameRect().intersects(localRepaintRect)) | 1182 if ((*overflowIterator)->frameRect().intersects(localRepaintRect)) |
1359 populator.storeChild(*overflowIterator); | 1183 populator.storeChild(*overflowIterator); |
1360 } | 1184 } |
1361 | 1185 |
1362 for (size_t row = dirtiedRows.initialPositionIndex; row < dirtiedRows.fi nalPositionIndex; ++row) { | 1186 for (GridResolvedPosition row = dirtiedRows.resolvedInitialPosition; row < dirtiedRows.resolvedFinalPosition; ++row) { |
1363 | 1187 |
1364 for (; overflowIterator != end && isInSameRowBeforeDirtyArea(cachedG ridCoordinate(*overflowIterator), row, dirtiedColumns); ++overflowIterator) { | 1188 for (; overflowIterator != end && isInSameRowBeforeDirtyArea(cachedG ridCoordinate(*overflowIterator), row, dirtiedColumns); ++overflowIterator) { |
1365 if ((*overflowIterator)->frameRect().intersects(localRepaintRect )) | 1189 if ((*overflowIterator)->frameRect().intersects(localRepaintRect )) |
1366 populator.storeChild(*overflowIterator); | 1190 populator.storeChild(*overflowIterator); |
1367 } | 1191 } |
1368 | 1192 |
1369 for (size_t column = dirtiedColumns.initialPositionIndex; column < d irtiedColumns.finalPositionIndex; ++column) { | 1193 for (GridResolvedPosition column = dirtiedColumns.resolvedInitialPos ition; column < dirtiedColumns.resolvedFinalPosition; ++column) { |
1370 const Vector<RenderBox*, 1>& children = m_grid[row][column]; | 1194 const Vector<RenderBox*, 1>& children = m_grid[row][column]; |
1371 // FIXME: If we start adding spanning children in all grid areas they span, this | 1195 // FIXME: If we start adding spanning children in all grid areas they span, this |
1372 // would make us paint them several times, which is wrong! | 1196 // would make us paint them several times, which is wrong! |
1373 for (size_t j = 0; j < children.size(); ++j) { | 1197 for (size_t j = 0; j < children.size(); ++j) { |
1374 populator.storeChild(children[j]); | 1198 populator.storeChild(children[j]); |
1375 // Do not paint overflowing grid items twice. | 1199 // Do not paint overflowing grid items twice. |
1376 if (overflowIterator != end && *overflowIterator == children [j]) | 1200 if (overflowIterator != end && *overflowIterator == children [j]) |
1377 ++overflowIterator; | 1201 ++overflowIterator; |
1378 } | 1202 } |
1379 } | 1203 } |
(...skipping 21 matching lines...) Expand all Loading... | |
1401 if (isOutOfFlowPositioned()) | 1225 if (isOutOfFlowPositioned()) |
1402 return "RenderGrid (positioned)"; | 1226 return "RenderGrid (positioned)"; |
1403 if (isAnonymous()) | 1227 if (isAnonymous()) |
1404 return "RenderGrid (generated)"; | 1228 return "RenderGrid (generated)"; |
1405 if (isRelPositioned()) | 1229 if (isRelPositioned()) |
1406 return "RenderGrid (relative positioned)"; | 1230 return "RenderGrid (relative positioned)"; |
1407 return "RenderGrid"; | 1231 return "RenderGrid"; |
1408 } | 1232 } |
1409 | 1233 |
1410 } // namespace WebCore | 1234 } // namespace WebCore |
OLD | NEW |