[webkit-changes] [WebKit/WebKit] 321eee: Initial implementation of CSS Grid Masonry Layout.

Sammy Gill noreply at github.com
Tue Nov 29 09:44:44 PST 2022


  Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 321eeed11b55bd231fd6d1173a94bfbb2a2c6700
      https://github.com/WebKit/WebKit/commit/321eeed11b55bd231fd6d1173a94bfbb2a2c6700
  Author: Sammy Gill <sammy.gill at apple.com>
  Date:   2022-11-29 (Tue, 29 Nov 2022)

  Changed paths:
    M LayoutTests/TestExpectations
    M Source/WebCore/Sources.txt
    M Source/WebCore/WebCore.xcodeproj/project.pbxproj
    M Source/WebCore/rendering/Grid.cpp
    M Source/WebCore/rendering/Grid.h
    A Source/WebCore/rendering/GridMasonryLayout.cpp
    A Source/WebCore/rendering/GridMasonryLayout.h
    M Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp
    M Source/WebCore/rendering/RenderGrid.cpp
    M Source/WebCore/rendering/RenderGrid.h
    M Source/WebCore/rendering/style/GridArea.h
    M Source/WebCore/rendering/style/GridPositionsResolver.h
    M Source/WebCore/rendering/style/StyleGridData.cpp

  Log Message:
  -----------
  Initial implementation of CSS Grid Masonry Layout.
https://bugs.webkit.org/show_bug.cgi?id=246702
rdar://101303069

Reviewed by Brent Fulgham.

CSS Grid Module Level 3 defines a new layout mode for grid containers
called Masonry Layout. Masonry layout is triggered by setting either
grid-template-rows or grid-template-columns to “masonry.” The axis that
is set to “masonry,” will be called the masonry axis and the other axis
will be known as the grid axis. The algorithm will go through each item
that needs a position and choose the grid axis track that has the most
available room. The specification does not provide any strict
requirements for the masonry axis track (e.g. how many there should be
or when they should be created), so the initial implementation has only
one masonry axis track.

Masonry layout is performed after an initial layout of the grid. The
initial layout will be done as if the masonry axis had “none,” set as
its value. The initial setup for masonry layout is done in the end of
RenderGrid::placeItemsOnGrid after the initial layout has completed.
This gives us the opportunity to collect items into a HashMap or an
appropriate Vector that will be used in a particular part of the layout
algorithm.

The HashMap will contain grid items that were placed on the first
implicit line in the masonry axis and their GridAreas so that they can
be easily placed in the original positions during the first step of the
algorithm. The number of grid axis tracks that are available for this
initial placement should be equal to the number of them before auto
placement of grid items occurs in the original item placement algorithm.

The two Vectors are used to store the items which have a definite grid
axis track placement and items with an indefinite placement, since those
will need to be handled separately.

Once the grid items have been collected, control is given over to the
GridMasonryLayout class that holds all of the state and information for
masonry layout to actually position the items into the appropriate areas.
GridMasonryLayout will hold information such as the running positions of
each of the tracks to reference during the positioning algorithm. These
running positions will be held inside of a Vector that will be
referenced using the corresponding starting line index of the track.
Each item will also have a corresponding offset that is stored in a
HashMap to be used to position at the correct location in its track.

* LayoutTests/TestExpectations:
* Source/WebCore/Sources.txt:
* Source/WebCore/WebCore.xcodeproj/project.pbxproj:
* Source/WebCore/rendering/Grid.cpp:
(WebCore::Grid::setupGridForMasonryLayout):
* Source/WebCore/rendering/Grid.h:
* Source/WebCore/rendering/GridMasonryLayout.cpp: Added.
(WebCore::GridMasonryLayout::performMasonryPlacement):
(WebCore::GridMasonryLayout::resizeAndResetRunningPositions):
(WebCore::GridMasonryLayout::addItemsToFirstTrack):
(WebCore::GridMasonryLayout::placeItemsWithDefiniteGridAxisPosition):
(WebCore::GridMasonryLayout::placeItemsWithIndefiniteGridAxisPosition):
(WebCore::GridMasonryLayout::insertIntoGridAndLayoutItem):
(WebCore::GridMasonryLayout::updateRunningPositions):
(WebCore::GridMasonryLayout::updateItemOffset):
(WebCore::GridMasonryLayout::nextMasonryPositionForItem):
(WebCore::GridMasonryLayout::offsetForChild const):
* Source/WebCore/rendering/GridMasonryLayout.h: Added.
(WebCore::GridMasonryLayout::GridMasonryLayout):
(WebCore::GridMasonryLayout::gridContentSize const):
* Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp:
(WebCore::GridTrackSizingAlgorithm::computeTrackBasedSize const):
Since the resulting grid does not define any strict tracks in the
masonry axis, the min/max content sizes for a grid are defined slightly
differently. They are defined as, "the largest distance between the grid
container’s content-box start edge and the maximum margin-box end of all
the items." This can be easily computed by using the running positions
of the grid axis tracks.

* Source/WebCore/rendering/RenderGrid.cpp:
(WebCore::RenderGrid::RenderGrid):
(WebCore::isMasonryRows):
(WebCore::isMasonryColumns):
(WebCore::RenderGrid::placeItemsOnGrid):
The containing block of a grid item in this spec is defined as, "its
grid area in the grid axis and the grid container’s content-box in the
masonry axis," so we must make sure we do not override the containing
block size incorrectly for each item in the masonry axis.

(WebCore::RenderGrid::allocateSpaceForMasonryVectors):
(WebCore::RenderGrid::masonryContentSize const):
(WebCore::itemGridAreaStartsAtFirstLine):
(WebCore::RenderGrid::hasDefiniteGridAxisPosition const):
(WebCore::itemGridAreaIsWithinImplicitGrid):
(WebCore::RenderGrid::collectMasonryItems const):
(WebCore::RenderGrid::layoutGridItems):
(WebCore::RenderGrid::gridAreaBreadthForChildIncludingAlignmentOffsets const):
We cannot use the size of the grid track as we would normally do here to
have the items stretch to fill the track since masonry axis tracks do
not behave the same way as in standard grid layout. Instead the items
should not stretch and should just be the size of their content.

(WebCore::RenderGrid::columnAxisOffsetForChild const):
(WebCore::RenderGrid::rowAxisOffsetForChild const):
* Source/WebCore/rendering/RenderGrid.h:
* Source/WebCore/rendering/style/GridArea.h:
(WebCore::GridSpan::masonryAxisTranslatedDefiniteGridSpan):
(WebCore::GridSpan::GridSpan):
* Source/WebCore/rendering/style/GridPositionsResolver.h:
(WebCore::GridPositionsResolver::gridAxisDirection):
* Source/WebCore/rendering/style/StyleGridData.cpp:
(WebCore::StyleGridData::setColumns):
There was a small bug where masonry was not being set correctly with
grid-template-columns.

Canonical link: https://commits.webkit.org/257124@main




More information about the webkit-changes mailing list