Ignore:
Timestamp:
Feb 24, 2014, 2:29:20 PM (12 years ago)
Author:
commit-queue@webkit.org
Message:

[CSS Grid Layout] handle undefined RemainingSpace in computeUsedBreadthOfGridTracks algorithm
https://bugs.webkit.org/show_bug.cgi?id=128372

Patch by Javier Fernandez <jfernandez@igalia.com> on 2014-02-24
Reviewed by David Hyatt.

From Blink r165692 by <svillar@igalia.com>

Source/WebCore:

The spec defines a different code path for the computeUsedBreadthOfGridTracks algorithm
http://dev.w3.org/csswg/css-grid/#function-ComputeUsedBreadthOfGridTracks.

Basically the track breadth is different when the available size is undefined and thus,
cannot be taken into account during the computations.
The available size is undefined whenever the height is auto or the grid element has a
shrink-to-fit behavior.

It was also renamed the function to match the specs so the function name starts with
'compute' instead of 'computed'.

No new tests, but added new cases to some of them.

  • rendering/RenderGrid.cpp:

(WebCore::RenderGrid::computeIntrinsicLogicalWidths):
(WebCore::RenderGrid::computeUsedBreadthOfGridTracks):
(WebCore::gridElementIsShrinkToFit):
(WebCore::RenderGrid::computeNormalizedFractionBreadth):
(WebCore::RenderGrid::layoutGridItems):

  • rendering/RenderGrid.h:

LayoutTests:

Adapt tests to consider also cases for undefined RemainingSpace.

  • fast/css-grid-layout/flex-and-minmax-content-resolution-rows-expected.txt:
  • fast/css-grid-layout/flex-and-minmax-content-resolution-rows.html:
  • fast/css-grid-layout/flex-content-resolution-rows-expected.txt:
  • fast/css-grid-layout/flex-content-resolution-rows.html:
  • fast/css-grid-layout/grid-auto-columns-rows-update-expected.txt:
  • fast/css-grid-layout/grid-auto-columns-rows-update.html:
  • fast/css-grid-layout/grid-dynamic-updates-relayout-expected.txt:
  • fast/css-grid-layout/grid-dynamic-updates-relayout.html:
  • fast/css-grid-layout/grid-item-addition-track-breadth-update-expected.txt:
  • fast/css-grid-layout/grid-item-addition-track-breadth-update.html:
  • fast/css-grid-layout/grid-item-multiple-minmax-content-resolution-expected.txt:
  • fast/css-grid-layout/grid-item-multiple-minmax-content-resolution.html:
  • fast/css-grid-layout/grid-item-removal-track-breadth-update-expected.txt:
  • fast/css-grid-layout/grid-item-removal-track-breadth-update.html:
  • fast/css-grid-layout/grid-item-with-percent-height-in-auto-height-grid-resolution-expected.txt:
  • fast/css-grid-layout/grid-item-with-percent-height-in-auto-height-grid-resolution.html:
  • fast/css-grid-layout/implicit-position-dynamic-change-expected.txt:
  • fast/css-grid-layout/implicit-position-dynamic-change.html:
  • fast/css-grid-layout/minmax-max-content-resolution-rows-expected.txt:
  • fast/css-grid-layout/minmax-max-content-resolution-rows.html:
  • fast/css-grid-layout/minmax-min-content-column-resolution-rows-expected.txt:
  • fast/css-grid-layout/minmax-min-content-column-resolution-rows.html:
  • fast/css-grid-layout/minmax-spanning-resolution-rows-expected.txt:
  • fast/css-grid-layout/minmax-spanning-resolution-rows.html:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/rendering/RenderGrid.cpp

    r164214 r164609  
    223223    GridSizingData sizingData(gridColumnCount(), gridRowCount());
    224224    LayoutUnit availableLogicalSpace = 0;
    225     const_cast<RenderGrid*>(this)->computedUsedBreadthOfGridTracks(ForColumns, sizingData, availableLogicalSpace);
     225    const_cast<RenderGrid*>(this)->computeUsedBreadthOfGridTracks(ForColumns, sizingData, availableLogicalSpace);
    226226
    227227    for (size_t i = 0; i < sizingData.columnTracks.size(); ++i) {
     
    258258}
    259259
    260 void RenderGrid::computedUsedBreadthOfGridTracks(GridTrackSizingDirection direction, GridSizingData& sizingData)
     260void RenderGrid::computeUsedBreadthOfGridTracks(GridTrackSizingDirection direction, GridSizingData& sizingData)
    261261{
    262262    LayoutUnit availableLogicalSpace = (direction == ForColumns) ? availableLogicalWidth() : availableLogicalHeight(IncludeMarginBorderPadding);
    263     computedUsedBreadthOfGridTracks(direction, sizingData, availableLogicalSpace);
    264 }
    265 
    266 void RenderGrid::computedUsedBreadthOfGridTracks(GridTrackSizingDirection direction, GridSizingData& sizingData, LayoutUnit& availableLogicalSpace)
     263    computeUsedBreadthOfGridTracks(direction, sizingData, availableLogicalSpace);
     264}
     265
     266bool RenderGrid::gridElementIsShrinkToFit()
     267{
     268    return isFloatingOrOutOfFlowPositioned();
     269}
     270
     271void RenderGrid::computeUsedBreadthOfGridTracks(GridTrackSizingDirection direction, GridSizingData& sizingData, LayoutUnit& availableLogicalSpace)
    267272{
    268273    Vector<GridTrack>& tracks = (direction == ForColumns) ? sizingData.columnTracks : sizingData.rowTracks;
     274    Vector<size_t> flexibleSizedTracksIndex;
    269275    sizingData.contentSizedTracksIndex.shrink(0);
     276
     277    // 1. Initialize per Grid track variables.
    270278    for (size_t i = 0; i < tracks.size(); ++i) {
    271279        GridTrack& track = tracks[i];
     
    281289        if (trackSize.isContentSized())
    282290            sizingData.contentSizedTracksIndex.append(i);
    283     }
    284 
     291        if (trackSize.maxTrackBreadth().isFlex())
     292            flexibleSizedTracksIndex.append(i);
     293    }
     294
     295    // 2. Resolve content-based TrackSizingFunctions.
    285296    if (!sizingData.contentSizedTracksIndex.isEmpty())
    286297        resolveContentBasedTrackSizingFunctions(direction, sizingData);
     
    291302    }
    292303
    293     if (availableLogicalSpace <= 0)
     304    const bool hasUndefinedRemainingSpace = (direction == ForRows) ? style().logicalHeight().isAuto() : gridElementIsShrinkToFit();
     305
     306    if (!hasUndefinedRemainingSpace && availableLogicalSpace <= 0)
    294307        return;
    295308
     309    // 3. Grow all Grid tracks in GridTracks from their UsedBreadth up to their MaxBreadth value until
     310    // availableLogicalSpace (RemainingSpace in the specs) is exhausted.
    296311    const size_t tracksSize = tracks.size();
    297     Vector<GridTrack*> tracksForDistribution(tracksSize);
    298     for (size_t i = 0; i < tracksSize; ++i)
    299         tracksForDistribution[i] = tracks.data() + i;
    300 
    301     distributeSpaceToTracks(tracksForDistribution, 0, &GridTrack::usedBreadth, &GridTrack::growUsedBreadth, sizingData, availableLogicalSpace);
     312    if (!hasUndefinedRemainingSpace) {
     313        Vector<GridTrack*> tracksForDistribution(tracksSize);
     314        for (size_t i = 0; i < tracksSize; ++i)
     315            tracksForDistribution[i] = tracks.data() + i;
     316
     317        distributeSpaceToTracks(tracksForDistribution, 0, &GridTrack::usedBreadth, &GridTrack::growUsedBreadth, sizingData, availableLogicalSpace);
     318    } else {
     319        for (size_t i = 0; i < tracksSize; ++i)
     320            tracks[i].m_usedBreadth = tracks[i].m_maxBreadth;
     321    }
     322
     323    if (flexibleSizedTracksIndex.isEmpty())
     324        return;
    302325
    303326    // 4. Grow all Grid tracks having a fraction as the MaxTrackSizingFunction.
    304 
    305     // FIXME: Handle the case where RemainingSpace is not defined.
    306     double normalizedFractionBreadth = computeNormalizedFractionBreadth(tracks, direction, availableLogicalSpace);
    307     for (size_t i = 0; i < tracksSize; ++i) {
    308         const GridTrackSize& trackSize = gridTrackSize(direction, i);
    309         if (!trackSize.maxTrackBreadth().isFlex())
    310             continue;
    311 
    312         tracks[i].m_usedBreadth = std::max<LayoutUnit>(tracks[i].m_usedBreadth, normalizedFractionBreadth * trackSize.maxTrackBreadth().flex());
     327    double normalizedFractionBreadth = 0;
     328    if (!hasUndefinedRemainingSpace)
     329        normalizedFractionBreadth = computeNormalizedFractionBreadth(tracks, GridSpan(0, tracks.size() - 1), direction, availableLogicalSpace);
     330    else {
     331        for (size_t i = 0; i < flexibleSizedTracksIndex.size(); ++i) {
     332            const size_t trackIndex = flexibleSizedTracksIndex[i];
     333            const GridTrackSize& trackSize = gridTrackSize(direction, trackIndex);
     334            normalizedFractionBreadth = std::max(normalizedFractionBreadth, tracks[trackIndex].m_usedBreadth / trackSize.maxTrackBreadth().flex());
     335        }
     336
     337        for (size_t i = 0; i < flexibleSizedTracksIndex.size(); ++i) {
     338            GridIterator iterator(m_grid, direction, flexibleSizedTracksIndex[i]);
     339            while (RenderBox* gridItem = iterator.nextGridItem()) {
     340                const GridCoordinate coordinate = cachedGridCoordinate(gridItem);
     341                const GridSpan span = (direction == ForColumns) ? coordinate.columns : coordinate.rows;
     342
     343                // Do not include already processed items.
     344                if (i > 0 && span.initialPositionIndex <= flexibleSizedTracksIndex[i - 1])
     345                    continue;
     346
     347                double itemNormalizedFlexBreadth = computeNormalizedFractionBreadth(tracks, span, direction, maxContentForChild(gridItem, direction, sizingData.columnTracks));
     348                normalizedFractionBreadth = std::max(normalizedFractionBreadth, itemNormalizedFlexBreadth);
     349            }
     350        }
     351    }
     352
     353    for (size_t i = 0; i < flexibleSizedTracksIndex.size(); ++i) {
     354        const size_t trackIndex = flexibleSizedTracksIndex[i];
     355        const GridTrackSize& trackSize = gridTrackSize(direction, trackIndex);
     356
     357        tracks[trackIndex].m_usedBreadth = std::max<LayoutUnit>(tracks[trackIndex].m_usedBreadth, normalizedFractionBreadth * trackSize.maxTrackBreadth().flex());
    313358    }
    314359}
     
    351396}
    352397
    353 double RenderGrid::computeNormalizedFractionBreadth(Vector<GridTrack>& tracks, GridTrackSizingDirection direction, LayoutUnit availableLogicalSpace) const
     398double RenderGrid::computeNormalizedFractionBreadth(Vector<GridTrack>& tracks, const GridSpan& tracksSpan, GridTrackSizingDirection direction, LayoutUnit availableLogicalSpace) const
    354399{
    355400    // |availableLogicalSpace| already accounts for the used breadths so no need to remove it here.
    356401
    357402    Vector<GridTrackForNormalization> tracksForNormalization;
    358     for (size_t i = 0; i < tracks.size(); ++i) {
     403    for (size_t i = tracksSpan.initialPositionIndex; i <= tracksSpan.finalPositionIndex; ++i) {
    359404        const GridTrackSize& trackSize = gridTrackSize(direction, i);
    360405        if (!trackSize.maxTrackBreadth().isFlex())
     
    364409    }
    365410
    366     // FIXME: Ideally we shouldn't come here without any <flex> grid track.
    367     if (tracksForNormalization.isEmpty())
    368         return LayoutUnit();
     411    // The function is not called if we don't have <flex> grid tracks
     412    ASSERT(!tracksForNormalization.isEmpty());
    369413
    370414    std::sort(tracksForNormalization.begin(), tracksForNormalization.end(),
     
    749793
    750794    GridSizingData sizingData(gridColumnCount(), gridRowCount());
    751     computedUsedBreadthOfGridTracks(ForColumns, sizingData);
     795    computeUsedBreadthOfGridTracks(ForColumns, sizingData);
    752796    ASSERT(tracksAreWiderThanMinTrackBreadth(ForColumns, sizingData.columnTracks));
    753     computedUsedBreadthOfGridTracks(ForRows, sizingData);
     797    computeUsedBreadthOfGridTracks(ForRows, sizingData);
    754798    ASSERT(tracksAreWiderThanMinTrackBreadth(ForRows, sizingData.rowTracks));
    755799
Note: See TracChangeset for help on using the changeset viewer.