| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/layout/GridTrackSizingAlgorithm.h" | 5 #include "core/layout/GridTrackSizingAlgorithm.h" |
| 6 | 6 |
| 7 #include "core/frame/FrameView.h" | 7 #include "core/frame/FrameView.h" |
| 8 #include "core/layout/Grid.h" | 8 #include "core/layout/Grid.h" |
| 9 #include "core/layout/LayoutGrid.h" | 9 #include "core/layout/LayoutGrid.h" |
| 10 #include "platform/LengthFunctions.h" | 10 #include "platform/LengthFunctions.h" |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 IndefiniteSizeStrategy(GridTrackSizingAlgorithm& algorithm) | 81 IndefiniteSizeStrategy(GridTrackSizingAlgorithm& algorithm) |
| 82 : GridTrackSizingAlgorithmStrategy(algorithm) {} | 82 : GridTrackSizingAlgorithmStrategy(algorithm) {} |
| 83 | 83 |
| 84 private: | 84 private: |
| 85 LayoutUnit minLogicalWidthForChild(LayoutBox&, | 85 LayoutUnit minLogicalWidthForChild(LayoutBox&, |
| 86 Length childMinSize, | 86 Length childMinSize, |
| 87 GridTrackSizingDirection) const override; | 87 GridTrackSizingDirection) const override; |
| 88 void layoutGridItemForMinSizeComputation( | 88 void layoutGridItemForMinSizeComputation( |
| 89 LayoutBox&, | 89 LayoutBox&, |
| 90 bool overrideSizeHasChanged) const override; | 90 bool overrideSizeHasChanged) const override; |
| 91 void maximizeTracks(Vector<GridTrack>&, LayoutUnit& freeSpace) override; | 91 void maximizeTracks(Vector<GridTrack>&, |
| 92 Optional<LayoutUnit>& freeSpace) override; |
| 92 double findUsedFlexFraction(Vector<size_t>& flexibleSizedTracksIndex, | 93 double findUsedFlexFraction(Vector<size_t>& flexibleSizedTracksIndex, |
| 93 GridTrackSizingDirection, | 94 GridTrackSizingDirection, |
| 94 LayoutUnit freeSpace) const override; | 95 Optional<LayoutUnit> freeSpace) const override; |
| 95 bool recomputeUsedFlexFractionIfNeeded( | 96 bool recomputeUsedFlexFractionIfNeeded( |
| 96 Vector<size_t>& flexibleSizedTracksIndex, | 97 Vector<size_t>& flexibleSizedTracksIndex, |
| 97 double& flexFraction, | 98 double& flexFraction, |
| 98 Vector<LayoutUnit>& increments, | 99 Vector<LayoutUnit>& increments, |
| 99 LayoutUnit& totalGrowth) const override; | 100 LayoutUnit& totalGrowth) const override; |
| 100 }; | 101 }; |
| 101 | 102 |
| 102 class DefiniteSizeStrategy final : public GridTrackSizingAlgorithmStrategy { | 103 class DefiniteSizeStrategy final : public GridTrackSizingAlgorithmStrategy { |
| 103 public: | 104 public: |
| 104 DefiniteSizeStrategy(GridTrackSizingAlgorithm& algorithm) | 105 DefiniteSizeStrategy(GridTrackSizingAlgorithm& algorithm) |
| 105 : GridTrackSizingAlgorithmStrategy(algorithm) {} | 106 : GridTrackSizingAlgorithmStrategy(algorithm) {} |
| 106 | 107 |
| 107 private: | 108 private: |
| 108 LayoutUnit minLogicalWidthForChild(LayoutBox&, | 109 LayoutUnit minLogicalWidthForChild(LayoutBox&, |
| 109 Length childMinSize, | 110 Length childMinSize, |
| 110 GridTrackSizingDirection) const override; | 111 GridTrackSizingDirection) const override; |
| 111 void layoutGridItemForMinSizeComputation( | 112 void layoutGridItemForMinSizeComputation( |
| 112 LayoutBox&, | 113 LayoutBox&, |
| 113 bool overrideSizeHasChanged) const override; | 114 bool overrideSizeHasChanged) const override; |
| 114 void maximizeTracks(Vector<GridTrack>&, LayoutUnit& freeSpace) override; | 115 void maximizeTracks(Vector<GridTrack>&, |
| 116 Optional<LayoutUnit>& freeSpace) override; |
| 115 double findUsedFlexFraction(Vector<size_t>& flexibleSizedTracksIndex, | 117 double findUsedFlexFraction(Vector<size_t>& flexibleSizedTracksIndex, |
| 116 GridTrackSizingDirection, | 118 GridTrackSizingDirection, |
| 117 LayoutUnit freeSpace) const override; | 119 Optional<LayoutUnit> freeSpace) const override; |
| 118 bool recomputeUsedFlexFractionIfNeeded( | 120 bool recomputeUsedFlexFractionIfNeeded( |
| 119 Vector<size_t>& flexibleSizedTracksIndex, | 121 Vector<size_t>& flexibleSizedTracksIndex, |
| 120 double& flexFraction, | 122 double& flexFraction, |
| 121 Vector<LayoutUnit>& increments, | 123 Vector<LayoutUnit>& increments, |
| 122 LayoutUnit& totalGrowth) const override { | 124 LayoutUnit& totalGrowth) const override { |
| 123 return false; | 125 return false; |
| 124 } | 126 } |
| 125 }; | 127 }; |
| 126 | 128 |
| 127 // TODO(svillar): Repeated in LayoutGrid. | 129 // TODO(svillar): Repeated in LayoutGrid. |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 | 441 |
| 440 void DefiniteSizeStrategy::layoutGridItemForMinSizeComputation( | 442 void DefiniteSizeStrategy::layoutGridItemForMinSizeComputation( |
| 441 LayoutBox& child, | 443 LayoutBox& child, |
| 442 bool overrideSizeHasChanged) const { | 444 bool overrideSizeHasChanged) const { |
| 443 if (overrideSizeHasChanged) | 445 if (overrideSizeHasChanged) |
| 444 setGridItemNeedsLayout(child); | 446 setGridItemNeedsLayout(child); |
| 445 child.layoutIfNeeded(); | 447 child.layoutIfNeeded(); |
| 446 } | 448 } |
| 447 | 449 |
| 448 void DefiniteSizeStrategy::maximizeTracks(Vector<GridTrack>& tracks, | 450 void DefiniteSizeStrategy::maximizeTracks(Vector<GridTrack>& tracks, |
| 449 LayoutUnit& freeSpace) { | 451 Optional<LayoutUnit>& freeSpace) { |
| 450 size_t tracksSize = tracks.size(); | 452 size_t tracksSize = tracks.size(); |
| 451 Vector<GridTrack*> tracksForDistribution(tracksSize); | 453 Vector<GridTrack*> tracksForDistribution(tracksSize); |
| 452 for (size_t i = 0; i < tracksSize; ++i) { | 454 for (size_t i = 0; i < tracksSize; ++i) { |
| 453 tracksForDistribution[i] = tracks.data() + i; | 455 tracksForDistribution[i] = tracks.data() + i; |
| 454 tracksForDistribution[i]->setPlannedSize( | 456 tracksForDistribution[i]->setPlannedSize( |
| 455 tracksForDistribution[i]->baseSize()); | 457 tracksForDistribution[i]->baseSize()); |
| 456 } | 458 } |
| 457 | 459 |
| 458 distributeSpaceToTracks(tracksForDistribution, freeSpace); | 460 DCHECK(freeSpace); |
| 461 distributeSpaceToTracks(tracksForDistribution, freeSpace.value()); |
| 459 | 462 |
| 460 for (auto* track : tracksForDistribution) | 463 for (auto* track : tracksForDistribution) |
| 461 track->setBaseSize(track->plannedSize()); | 464 track->setBaseSize(track->plannedSize()); |
| 462 } | 465 } |
| 463 | 466 |
| 464 double DefiniteSizeStrategy::findUsedFlexFraction( | 467 double DefiniteSizeStrategy::findUsedFlexFraction( |
| 465 Vector<size_t>& flexibleSizedTracksIndex, | 468 Vector<size_t>& flexibleSizedTracksIndex, |
| 466 GridTrackSizingDirection direction, | 469 GridTrackSizingDirection direction, |
| 467 LayoutUnit freeSpace) const { | 470 Optional<LayoutUnit> freeSpace) const { |
| 468 GridSpan allTracksSpan = GridSpan::translatedDefiniteGridSpan( | 471 GridSpan allTracksSpan = GridSpan::translatedDefiniteGridSpan( |
| 469 0, m_algorithm.tracks(direction).size()); | 472 0, m_algorithm.tracks(direction).size()); |
| 470 return findFrUnitSize(allTracksSpan, freeSpace); | 473 DCHECK(freeSpace); |
| 474 return findFrUnitSize(allTracksSpan, freeSpace.value()); |
| 471 } | 475 } |
| 472 | 476 |
| 473 LayoutUnit IndefiniteSizeStrategy::minLogicalWidthForChild( | 477 LayoutUnit IndefiniteSizeStrategy::minLogicalWidthForChild( |
| 474 LayoutBox& child, | 478 LayoutBox& child, |
| 475 Length childMinSize, | 479 Length childMinSize, |
| 476 GridTrackSizingDirection childInlineDirection) const { | 480 GridTrackSizingDirection childInlineDirection) const { |
| 477 // TODO(svillar): we should use marginIntrinsicLogicalWidthForChild() instead | 481 // TODO(svillar): we should use marginIntrinsicLogicalWidthForChild() instead |
| 478 // but it is protected for LayoutObjects. Apparently none of the current tests | 482 // but it is protected for LayoutObjects. Apparently none of the current tests |
| 479 // fail, so we need a test case for this too. | 483 // fail, so we need a test case for this too. |
| 480 LayoutUnit marginLogicalWidth = LayoutUnit(); | 484 LayoutUnit marginLogicalWidth = LayoutUnit(); |
| 481 return child.computeLogicalWidthUsing( | 485 return child.computeLogicalWidthUsing( |
| 482 MinSize, childMinSize, overrideContainingBlockContentSizeForChild( | 486 MinSize, childMinSize, overrideContainingBlockContentSizeForChild( |
| 483 child, childInlineDirection), | 487 child, childInlineDirection), |
| 484 layoutGrid()) + | 488 layoutGrid()) + |
| 485 marginLogicalWidth; | 489 marginLogicalWidth; |
| 486 } | 490 } |
| 487 | 491 |
| 488 void IndefiniteSizeStrategy::layoutGridItemForMinSizeComputation( | 492 void IndefiniteSizeStrategy::layoutGridItemForMinSizeComputation( |
| 489 LayoutBox& child, | 493 LayoutBox& child, |
| 490 bool overrideSizeHasChanged) const { | 494 bool overrideSizeHasChanged) const { |
| 491 if (overrideSizeHasChanged && direction() != ForColumns) | 495 if (overrideSizeHasChanged && direction() != ForColumns) |
| 492 setGridItemNeedsLayout(child); | 496 setGridItemNeedsLayout(child); |
| 493 child.layoutIfNeeded(); | 497 child.layoutIfNeeded(); |
| 494 } | 498 } |
| 495 | 499 |
| 496 void IndefiniteSizeStrategy::maximizeTracks(Vector<GridTrack>& tracks, | 500 void IndefiniteSizeStrategy::maximizeTracks(Vector<GridTrack>& tracks, |
| 497 LayoutUnit&) { | 501 Optional<LayoutUnit>&) { |
| 498 for (auto& track : tracks) | 502 for (auto& track : tracks) |
| 499 track.setBaseSize(track.growthLimit()); | 503 track.setBaseSize(track.growthLimit()); |
| 500 } | 504 } |
| 501 | 505 |
| 502 static inline double normalizedFlexFraction(const GridTrack& track, | 506 static inline double normalizedFlexFraction(const GridTrack& track, |
| 503 double flexFactor) { | 507 double flexFactor) { |
| 504 return track.baseSize() / std::max<double>(1, flexFactor); | 508 return track.baseSize() / std::max<double>(1, flexFactor); |
| 505 } | 509 } |
| 506 | 510 |
| 507 double IndefiniteSizeStrategy::findUsedFlexFraction( | 511 double IndefiniteSizeStrategy::findUsedFlexFraction( |
| 508 Vector<size_t>& flexibleSizedTracksIndex, | 512 Vector<size_t>& flexibleSizedTracksIndex, |
| 509 GridTrackSizingDirection direction, | 513 GridTrackSizingDirection direction, |
| 510 LayoutUnit freeSpace) const { | 514 Optional<LayoutUnit>) const { |
| 511 auto allTracks = m_algorithm.tracks(direction); | 515 auto allTracks = m_algorithm.tracks(direction); |
| 512 | 516 |
| 513 double flexFraction = 0; | 517 double flexFraction = 0; |
| 514 for (const auto& trackIndex : flexibleSizedTracksIndex) { | 518 for (const auto& trackIndex : flexibleSizedTracksIndex) { |
| 515 // TODO(svillar): we pass TrackSizing to gridTrackSize() because it does not | 519 // TODO(svillar): we pass TrackSizing to gridTrackSize() because it does not |
| 516 // really matter as we know the track is a flex sized track. It'd be nice | 520 // really matter as we know the track is a flex sized track. It'd be nice |
| 517 // not to have to do that. | 521 // not to have to do that. |
| 518 flexFraction = std::max( | 522 flexFraction = std::max( |
| 519 flexFraction, | 523 flexFraction, |
| 520 normalizedFlexFraction( | 524 normalizedFlexFraction( |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 freeSpace = std::max(freeSpace, minSize) - | 577 freeSpace = std::max(freeSpace, minSize) - |
| 574 layoutGrid->guttersSize(grid, ForRows, 0, grid.numTracks(ForRows), | 578 layoutGrid->guttersSize(grid, ForRows, 0, grid.numTracks(ForRows), |
| 575 IntrinsicSizeComputation); | 579 IntrinsicSizeComputation); |
| 576 | 580 |
| 577 size_t numberOfTracks = m_algorithm.tracks(direction()).size(); | 581 size_t numberOfTracks = m_algorithm.tracks(direction()).size(); |
| 578 flexFraction = findFrUnitSize( | 582 flexFraction = findFrUnitSize( |
| 579 GridSpan::translatedDefiniteGridSpan(0, numberOfTracks), freeSpace); | 583 GridSpan::translatedDefiniteGridSpan(0, numberOfTracks), freeSpace); |
| 580 return true; | 584 return true; |
| 581 } | 585 } |
| 582 | 586 |
| 583 LayoutUnit& GridTrackSizingAlgorithm::freeSpace( | 587 Optional<LayoutUnit> GridTrackSizingAlgorithm::freeSpace( |
| 584 GridTrackSizingDirection direction) { | 588 GridTrackSizingDirection direction) { |
| 585 return direction == ForRows ? m_freeSpaceRows : m_freeSpaceColumns; | 589 return direction == ForRows ? m_freeSpaceRows : m_freeSpaceColumns; |
| 586 } | 590 } |
| 587 | 591 |
| 588 Vector<GridTrack>& GridTrackSizingAlgorithm::tracks( | 592 Vector<GridTrack>& GridTrackSizingAlgorithm::tracks( |
| 589 GridTrackSizingDirection direction) { | 593 GridTrackSizingDirection direction) { |
| 590 return direction == ForColumns ? m_columns : m_rows; | 594 return direction == ForColumns ? m_columns : m_rows; |
| 591 } | 595 } |
| 592 | 596 |
| 593 const Vector<GridTrack>& GridTrackSizingAlgorithm::tracks( | 597 const Vector<GridTrack>& GridTrackSizingAlgorithm::tracks( |
| 594 GridTrackSizingDirection direction) const { | 598 GridTrackSizingDirection direction) const { |
| 595 return direction == ForColumns ? m_columns : m_rows; | 599 return direction == ForColumns ? m_columns : m_rows; |
| 596 } | 600 } |
| 597 | 601 |
| 602 void GridTrackSizingAlgorithm::setFreeSpace(GridTrackSizingDirection direction, |
| 603 Optional<LayoutUnit> freeSpace) { |
| 604 if (direction == ForColumns) |
| 605 m_freeSpaceColumns = freeSpace; |
| 606 else |
| 607 m_freeSpaceRows = freeSpace; |
| 608 } |
| 609 |
| 598 GridTrackSize GridTrackSizingAlgorithm::rawGridTrackSize( | 610 GridTrackSize GridTrackSizingAlgorithm::rawGridTrackSize( |
| 599 GridTrackSizingDirection direction, | 611 GridTrackSizingDirection direction, |
| 600 size_t translatedIndex) const { | 612 size_t translatedIndex) const { |
| 601 bool isRowAxis = direction == ForColumns; | 613 bool isRowAxis = direction == ForColumns; |
| 602 const Vector<GridTrackSize>& trackStyles = | 614 const Vector<GridTrackSize>& trackStyles = |
| 603 isRowAxis ? m_layoutGrid->styleRef().gridTemplateColumns() | 615 isRowAxis ? m_layoutGrid->styleRef().gridTemplateColumns() |
| 604 : m_layoutGrid->styleRef().gridTemplateRows(); | 616 : m_layoutGrid->styleRef().gridTemplateRows(); |
| 605 const Vector<GridTrackSize>& autoRepeatTrackStyles = | 617 const Vector<GridTrackSize>& autoRepeatTrackStyles = |
| 606 isRowAxis ? m_layoutGrid->styleRef().gridAutoRepeatColumns() | 618 isRowAxis ? m_layoutGrid->styleRef().gridAutoRepeatColumns() |
| 607 : m_layoutGrid->styleRef().gridAutoRepeatRows(); | 619 : m_layoutGrid->styleRef().gridAutoRepeatRows(); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 694 } | 706 } |
| 695 | 707 |
| 696 LayoutUnit GridTrackSizingAlgorithm::initialBaseSize( | 708 LayoutUnit GridTrackSizingAlgorithm::initialBaseSize( |
| 697 const GridTrackSize& trackSize) const { | 709 const GridTrackSize& trackSize) const { |
| 698 const GridLength& gridLength = trackSize.minTrackBreadth(); | 710 const GridLength& gridLength = trackSize.minTrackBreadth(); |
| 699 if (gridLength.isFlex()) | 711 if (gridLength.isFlex()) |
| 700 return LayoutUnit(); | 712 return LayoutUnit(); |
| 701 | 713 |
| 702 const Length& trackLength = gridLength.length(); | 714 const Length& trackLength = gridLength.length(); |
| 703 if (trackLength.isSpecified()) | 715 if (trackLength.isSpecified()) |
| 704 return valueForLength(trackLength, m_availableSpace.clampNegativeToZero()); | 716 return valueForLength(trackLength, m_availableSpace.value_or(LayoutUnit())); |
| 705 | 717 |
| 706 DCHECK(trackLength.isMinContent() || trackLength.isAuto() || | 718 DCHECK(trackLength.isMinContent() || trackLength.isAuto() || |
| 707 trackLength.isMaxContent()); | 719 trackLength.isMaxContent()); |
| 708 return LayoutUnit(); | 720 return LayoutUnit(); |
| 709 } | 721 } |
| 710 | 722 |
| 711 LayoutUnit GridTrackSizingAlgorithm::initialGrowthLimit( | 723 LayoutUnit GridTrackSizingAlgorithm::initialGrowthLimit( |
| 712 const GridTrackSize& trackSize, | 724 const GridTrackSize& trackSize, |
| 713 LayoutUnit baseSize) const { | 725 LayoutUnit baseSize) const { |
| 714 const GridLength& gridLength = trackSize.maxTrackBreadth(); | 726 const GridLength& gridLength = trackSize.maxTrackBreadth(); |
| 715 if (gridLength.isFlex()) | 727 if (gridLength.isFlex()) |
| 716 return baseSize; | 728 return baseSize; |
| 717 | 729 |
| 718 const Length& trackLength = gridLength.length(); | 730 const Length& trackLength = gridLength.length(); |
| 719 if (trackLength.isSpecified()) | 731 if (trackLength.isSpecified()) |
| 720 return valueForLength(trackLength, m_availableSpace.clampNegativeToZero()); | 732 return valueForLength(trackLength, m_availableSpace.value_or(LayoutUnit())); |
| 721 | 733 |
| 722 DCHECK(trackLength.isMinContent() || trackLength.isAuto() || | 734 DCHECK(trackLength.isMinContent() || trackLength.isAuto() || |
| 723 trackLength.isMaxContent()); | 735 trackLength.isMaxContent()); |
| 724 return LayoutUnit(infinity); | 736 return LayoutUnit(infinity); |
| 725 } | 737 } |
| 726 | 738 |
| 727 void GridTrackSizingAlgorithm::initializeTrackSizes() { | 739 void GridTrackSizingAlgorithm::initializeTrackSizes() { |
| 728 DCHECK(m_contentSizedTracksIndex.isEmpty()); | 740 DCHECK(m_contentSizedTracksIndex.isEmpty()); |
| 729 DCHECK(m_flexibleSizedTracksIndex.isEmpty()); | 741 DCHECK(m_flexibleSizedTracksIndex.isEmpty()); |
| 730 Vector<GridTrack>& trackList = tracks(m_direction); | 742 Vector<GridTrack>& trackList = tracks(m_direction); |
| 731 bool hasDefiniteFreeSpace = m_sizingOperation == TrackSizing; | 743 bool hasDefiniteFreeSpace = !!m_availableSpace; |
| 732 size_t numTracks = trackList.size(); | 744 size_t numTracks = trackList.size(); |
| 733 for (size_t i = 0; i < numTracks; ++i) { | 745 for (size_t i = 0; i < numTracks; ++i) { |
| 734 GridTrackSize trackSize = gridTrackSize(m_direction, i); | 746 GridTrackSize trackSize = gridTrackSize(m_direction, i); |
| 735 GridTrack& track = trackList[i]; | 747 GridTrack& track = trackList[i]; |
| 736 track.setBaseSize(initialBaseSize(trackSize)); | 748 track.setBaseSize(initialBaseSize(trackSize)); |
| 737 track.setGrowthLimit(initialGrowthLimit(trackSize, track.baseSize())); | 749 track.setGrowthLimit(initialGrowthLimit(trackSize, track.baseSize())); |
| 738 track.setInfinitelyGrowable(false); | 750 track.setInfinitelyGrowable(false); |
| 739 | 751 |
| 740 if (trackSize.isFitContent()) { | 752 if (trackSize.isFitContent()) { |
| 741 GridLength gridLength = trackSize.fitContentTrackBreadth(); | 753 GridLength gridLength = trackSize.fitContentTrackBreadth(); |
| 742 if (!gridLength.hasPercentage() || hasDefiniteFreeSpace) { | 754 if (!gridLength.hasPercentage() || hasDefiniteFreeSpace) { |
| 743 track.setGrowthLimitCap(valueForLength( | 755 track.setGrowthLimitCap(valueForLength( |
| 744 gridLength.length(), m_availableSpace.clampNegativeToZero())); | 756 gridLength.length(), m_availableSpace.value_or(LayoutUnit()))); |
| 745 } | 757 } |
| 746 } | 758 } |
| 747 | 759 |
| 748 if (trackSize.isContentSized()) | 760 if (trackSize.isContentSized()) |
| 749 m_contentSizedTracksIndex.push_back(i); | 761 m_contentSizedTracksIndex.push_back(i); |
| 750 if (trackSize.maxTrackBreadth().isFlex()) | 762 if (trackSize.maxTrackBreadth().isFlex()) |
| 751 m_flexibleSizedTracksIndex.push_back(i); | 763 m_flexibleSizedTracksIndex.push_back(i); |
| 752 } | 764 } |
| 753 } | 765 } |
| 754 | 766 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 772 | 784 |
| 773 if (trackSize.hasMinContentMaxTrackBreadth()) { | 785 if (trackSize.hasMinContentMaxTrackBreadth()) { |
| 774 track.setGrowthLimit(std::max(track.growthLimit(), | 786 track.setGrowthLimit(std::max(track.growthLimit(), |
| 775 m_strategy->minContentForChild(gridItem))); | 787 m_strategy->minContentForChild(gridItem))); |
| 776 } else if (trackSize.hasMaxContentOrAutoMaxTrackBreadth()) { | 788 } else if (trackSize.hasMaxContentOrAutoMaxTrackBreadth()) { |
| 777 LayoutUnit growthLimit = m_strategy->maxContentForChild(gridItem); | 789 LayoutUnit growthLimit = m_strategy->maxContentForChild(gridItem); |
| 778 if (trackSize.isFitContent()) { | 790 if (trackSize.isFitContent()) { |
| 779 growthLimit = | 791 growthLimit = |
| 780 std::min(growthLimit, | 792 std::min(growthLimit, |
| 781 valueForLength(trackSize.fitContentTrackBreadth().length(), | 793 valueForLength(trackSize.fitContentTrackBreadth().length(), |
| 782 m_availableSpace)); | 794 m_availableSpace.value_or(LayoutUnit()))); |
| 783 } | 795 } |
| 784 track.setGrowthLimit(std::max(track.growthLimit(), growthLimit)); | 796 track.setGrowthLimit(std::max(track.growthLimit(), growthLimit)); |
| 785 } | 797 } |
| 786 } | 798 } |
| 787 | 799 |
| 788 bool GridTrackSizingAlgorithm::spanningItemCrossesFlexibleSizedTracks( | 800 bool GridTrackSizingAlgorithm::spanningItemCrossesFlexibleSizedTracks( |
| 789 const GridSpan& span) const { | 801 const GridSpan& span) const { |
| 790 for (const auto& trackPosition : span) { | 802 for (const auto& trackPosition : span) { |
| 791 const GridTrackSize& trackSize = gridTrackSize(m_direction, trackPosition); | 803 const GridTrackSize& trackSize = gridTrackSize(m_direction, trackPosition); |
| 792 if (trackSize.minTrackBreadth().isFlex() || | 804 if (trackSize.minTrackBreadth().isFlex() || |
| (...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1289 DCHECK(trackSize.maxTrackBreadth().isFlex()); | 1301 DCHECK(trackSize.maxTrackBreadth().isFlex()); |
| 1290 LayoutUnit oldBaseSize = allTracks[trackIndex].baseSize(); | 1302 LayoutUnit oldBaseSize = allTracks[trackIndex].baseSize(); |
| 1291 LayoutUnit newBaseSize = | 1303 LayoutUnit newBaseSize = |
| 1292 std::max(oldBaseSize, | 1304 std::max(oldBaseSize, |
| 1293 LayoutUnit(flexFraction * trackSize.maxTrackBreadth().flex())); | 1305 LayoutUnit(flexFraction * trackSize.maxTrackBreadth().flex())); |
| 1294 increments[i] = newBaseSize - oldBaseSize; | 1306 increments[i] = newBaseSize - oldBaseSize; |
| 1295 totalGrowth += increments[i]; | 1307 totalGrowth += increments[i]; |
| 1296 } | 1308 } |
| 1297 } | 1309 } |
| 1298 | 1310 |
| 1299 void GridTrackSizingAlgorithm::stretchFlexibleTracks(LayoutUnit freeSpace) { | 1311 void GridTrackSizingAlgorithm::stretchFlexibleTracks( |
| 1312 Optional<LayoutUnit> freeSpace) { |
| 1300 double flexFraction = m_strategy->findUsedFlexFraction( | 1313 double flexFraction = m_strategy->findUsedFlexFraction( |
| 1301 m_flexibleSizedTracksIndex, m_direction, freeSpace); | 1314 m_flexibleSizedTracksIndex, m_direction, freeSpace); |
| 1302 | 1315 |
| 1303 LayoutUnit totalGrowth; | 1316 LayoutUnit totalGrowth; |
| 1304 Vector<LayoutUnit> increments; | 1317 Vector<LayoutUnit> increments; |
| 1305 increments.grow(m_flexibleSizedTracksIndex.size()); | 1318 increments.grow(m_flexibleSizedTracksIndex.size()); |
| 1306 computeFlexSizedTracksGrowth(flexFraction, increments, totalGrowth); | 1319 computeFlexSizedTracksGrowth(flexFraction, increments, totalGrowth); |
| 1307 | 1320 |
| 1308 if (m_strategy->recomputeUsedFlexFractionIfNeeded( | 1321 if (m_strategy->recomputeUsedFlexFractionIfNeeded( |
| 1309 m_flexibleSizedTracksIndex, flexFraction, increments, totalGrowth)) { | 1322 m_flexibleSizedTracksIndex, flexFraction, increments, totalGrowth)) { |
| 1310 totalGrowth = LayoutUnit(0); | 1323 totalGrowth = LayoutUnit(0); |
| 1311 computeFlexSizedTracksGrowth(flexFraction, increments, totalGrowth); | 1324 computeFlexSizedTracksGrowth(flexFraction, increments, totalGrowth); |
| 1312 } | 1325 } |
| 1313 | 1326 |
| 1314 size_t i = 0; | 1327 size_t i = 0; |
| 1315 Vector<GridTrack>& allTracks = tracks(m_direction); | 1328 Vector<GridTrack>& allTracks = tracks(m_direction); |
| 1316 for (auto trackIndex : m_flexibleSizedTracksIndex) { | 1329 for (auto trackIndex : m_flexibleSizedTracksIndex) { |
| 1317 auto& track = allTracks[trackIndex]; | 1330 auto& track = allTracks[trackIndex]; |
| 1318 if (LayoutUnit increment = increments[i++]) | 1331 if (LayoutUnit increment = increments[i++]) |
| 1319 track.setBaseSize(track.baseSize() + increment); | 1332 track.setBaseSize(track.baseSize() + increment); |
| 1320 } | 1333 } |
| 1321 this->freeSpace(m_direction) -= totalGrowth; | 1334 if (this->freeSpace(m_direction)) { |
| 1335 setFreeSpace(m_direction, |
| 1336 this->freeSpace(m_direction).value() - totalGrowth); |
| 1337 } |
| 1322 m_maxContentSize += totalGrowth; | 1338 m_maxContentSize += totalGrowth; |
| 1323 } | 1339 } |
| 1324 | 1340 |
| 1325 void GridTrackSizingAlgorithm::advanceNextState() { | 1341 void GridTrackSizingAlgorithm::advanceNextState() { |
| 1326 switch (m_sizingState) { | 1342 switch (m_sizingState) { |
| 1327 case ColumnSizingFirstIteration: | 1343 case ColumnSizingFirstIteration: |
| 1328 m_sizingState = RowSizingFirstIteration; | 1344 m_sizingState = RowSizingFirstIteration; |
| 1329 return; | 1345 return; |
| 1330 case RowSizingFirstIteration: | 1346 case RowSizingFirstIteration: |
| 1331 m_sizingState = ColumnSizingSecondIteration; | 1347 m_sizingState = ColumnSizingSecondIteration; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1350 case RowSizingSecondIteration: | 1366 case RowSizingSecondIteration: |
| 1351 return m_direction == ForRows; | 1367 return m_direction == ForRows; |
| 1352 } | 1368 } |
| 1353 NOTREACHED(); | 1369 NOTREACHED(); |
| 1354 return false; | 1370 return false; |
| 1355 } | 1371 } |
| 1356 | 1372 |
| 1357 void GridTrackSizingAlgorithm::setup(GridTrackSizingDirection direction, | 1373 void GridTrackSizingAlgorithm::setup(GridTrackSizingDirection direction, |
| 1358 size_t numTracks, | 1374 size_t numTracks, |
| 1359 SizingOperation sizingOperation, | 1375 SizingOperation sizingOperation, |
| 1360 LayoutUnit availableSpace, | 1376 Optional<LayoutUnit> availableSpace, |
| 1361 LayoutUnit freeSpace) { | 1377 Optional<LayoutUnit> freeSpace) { |
| 1362 DCHECK(m_needsSetup); | 1378 DCHECK(m_needsSetup); |
| 1379 DCHECK_EQ(!!availableSpace, !!freeSpace); |
| 1363 m_direction = direction; | 1380 m_direction = direction; |
| 1364 m_availableSpace = availableSpace; | 1381 m_availableSpace = availableSpace |
| 1382 ? availableSpace.value().clampNegativeToZero() |
| 1383 : availableSpace; |
| 1365 | 1384 |
| 1366 m_sizingOperation = sizingOperation; | 1385 m_sizingOperation = sizingOperation; |
| 1367 switch (m_sizingOperation) { | 1386 |
| 1368 case IntrinsicSizeComputation: | 1387 if (availableSpace) |
| 1369 m_strategy = WTF::makeUnique<IndefiniteSizeStrategy>(*this); | 1388 m_strategy = WTF::makeUnique<DefiniteSizeStrategy>(*this); |
| 1370 break; | 1389 else |
| 1371 case TrackSizing: | 1390 m_strategy = WTF::makeUnique<IndefiniteSizeStrategy>(*this); |
| 1372 m_strategy = WTF::makeUnique<DefiniteSizeStrategy>(*this); | |
| 1373 break; | |
| 1374 } | |
| 1375 | 1391 |
| 1376 m_contentSizedTracksIndex.shrink(0); | 1392 m_contentSizedTracksIndex.shrink(0); |
| 1377 m_flexibleSizedTracksIndex.shrink(0); | 1393 m_flexibleSizedTracksIndex.shrink(0); |
| 1378 | 1394 |
| 1379 this->freeSpace(direction) = freeSpace; | 1395 setFreeSpace(direction, freeSpace); |
| 1380 tracks(direction).resize(numTracks); | 1396 tracks(direction).resize(numTracks); |
| 1381 | 1397 |
| 1382 m_needsSetup = false; | 1398 m_needsSetup = false; |
| 1383 } | 1399 } |
| 1384 | 1400 |
| 1385 // Described in https://drafts.csswg.org/css-grid/#algo-track-sizing | 1401 // Described in https://drafts.csswg.org/css-grid/#algo-track-sizing |
| 1386 void GridTrackSizingAlgorithm::run() { | 1402 void GridTrackSizingAlgorithm::run() { |
| 1387 StateMachine stateMachine(*this); | 1403 StateMachine stateMachine(*this); |
| 1388 | 1404 |
| 1389 // Step 1. | 1405 // Step 1. |
| 1390 LayoutUnit initialFreeSpace = freeSpace(m_direction); | 1406 Optional<LayoutUnit> initialFreeSpace = freeSpace(m_direction); |
| 1391 initializeTrackSizes(); | 1407 initializeTrackSizes(); |
| 1392 | 1408 |
| 1393 // Step 2. | 1409 // Step 2. |
| 1394 if (!m_contentSizedTracksIndex.isEmpty()) | 1410 if (!m_contentSizedTracksIndex.isEmpty()) |
| 1395 resolveIntrinsicTrackSizes(); | 1411 resolveIntrinsicTrackSizes(); |
| 1396 | 1412 |
| 1397 // This is not exactly a step of the track sizing algorithm, but we use the | 1413 // This is not exactly a step of the track sizing algorithm, but we use the |
| 1398 // track sizes computed | 1414 // track sizes computed |
| 1399 // up to this moment (before maximization) to calculate the grid container | 1415 // up to this moment (before maximization) to calculate the grid container |
| 1400 // intrinsic sizes. | 1416 // intrinsic sizes. |
| 1401 computeGridContainerIntrinsicSizes(); | 1417 computeGridContainerIntrinsicSizes(); |
| 1402 freeSpace(m_direction) -= m_minContentSize; | |
| 1403 | 1418 |
| 1404 if (m_sizingOperation == TrackSizing && freeSpace(m_direction) <= 0) | 1419 if (freeSpace(m_direction)) { |
| 1405 return; | 1420 LayoutUnit updatedFreeSpace = |
| 1421 freeSpace(m_direction).value() - m_minContentSize; |
| 1422 setFreeSpace(m_direction, updatedFreeSpace); |
| 1423 if (updatedFreeSpace <= 0) |
| 1424 return; |
| 1425 } |
| 1406 | 1426 |
| 1407 // Step 3. | 1427 // Step 3. |
| 1408 m_strategy->maximizeTracks(tracks(m_direction), freeSpace(m_direction)); | 1428 m_strategy->maximizeTracks(tracks(m_direction), m_direction == ForColumns |
| 1429 ? m_freeSpaceColumns |
| 1430 : m_freeSpaceRows); |
| 1409 | 1431 |
| 1410 if (m_flexibleSizedTracksIndex.isEmpty()) | 1432 if (m_flexibleSizedTracksIndex.isEmpty()) |
| 1411 return; | 1433 return; |
| 1412 | 1434 |
| 1413 // Step 4. | 1435 // Step 4. |
| 1414 stretchFlexibleTracks(initialFreeSpace); | 1436 stretchFlexibleTracks(initialFreeSpace); |
| 1415 } | 1437 } |
| 1416 | 1438 |
| 1417 void GridTrackSizingAlgorithm::reset() { | 1439 void GridTrackSizingAlgorithm::reset() { |
| 1418 m_sizingState = ColumnSizingFirstIteration; | 1440 m_sizingState = ColumnSizingFirstIteration; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1440 DCHECK(m_algorithm.isValidTransition()); | 1462 DCHECK(m_algorithm.isValidTransition()); |
| 1441 DCHECK(!m_algorithm.m_needsSetup); | 1463 DCHECK(!m_algorithm.m_needsSetup); |
| 1442 } | 1464 } |
| 1443 | 1465 |
| 1444 GridTrackSizingAlgorithm::StateMachine::~StateMachine() { | 1466 GridTrackSizingAlgorithm::StateMachine::~StateMachine() { |
| 1445 m_algorithm.advanceNextState(); | 1467 m_algorithm.advanceNextState(); |
| 1446 m_algorithm.m_needsSetup = true; | 1468 m_algorithm.m_needsSetup = true; |
| 1447 } | 1469 } |
| 1448 | 1470 |
| 1449 } // namespace blink | 1471 } // namespace blink |
| OLD | NEW |