Changeset 183399 in webkit


Ignore:
Timestamp:
Apr 27, 2015 10:24:44 AM (9 years ago)
Author:
jfernandez@igalia.com
Message:

[CSS Grid Layout] Support for the justify-self and justify-items in grid layout
https://bugs.webkit.org/show_bug.cgi?id=133280

Source/WebCore:

Reviewed by David Hyatt.

Implementation of justify-self and justify-items properties for grid. It supports
different writing-modes and direction. Margins, borders and paddings are also
considered when computing the final position and stretched size.

This patch applies also a quite important refactoring of the alignment logic in
order to share code between the two alignment dimensions, row-axis and column-axis.

Overflow handling is still missing and will be added later in a follow-up bug.

Tests: fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-lr.html

fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-rl.html
fast/css-grid-layout/grid-align-justify-margin-border-padding.html
fast/css-grid-layout/justify-self-cell.html

  • rendering/RenderGrid.cpp:

(WebCore::RenderGrid::layoutGridItems):
(WebCore::RenderGrid::columnAxisPositionForChild):
(WebCore::RenderGrid::rowAxisPositionForChild):
(WebCore::RenderGrid::rowPositionForChild):
(WebCore::RenderGrid::columnPositionForChild):
(WebCore::RenderGrid::findChildLogicalPosition):
(WebCore::RenderGrid::allowedToStretchLogicalHeightForChild): Deleted.
(WebCore::RenderGrid::needToStretchChildLogicalHeight): Deleted.
(WebCore::RenderGrid::marginLogicalHeightForChild): Deleted.
(WebCore::RenderGrid::availableAlignmentSpaceForChildBeforeStretching): Deleted.
(WebCore::RenderGrid::applyStretchAlignmentToChildIfNeeded): Deleted.

  • rendering/RenderGrid.h:
  • rendering/style/RenderStyle.cpp:

(WebCore::RenderStyle::resolveJustification):

  • rendering/style/RenderStyle.h:

LayoutTests:

Implementation of justify-self and justify-items properties for grid.
Added additional testing for ensuring margin, padding and border are considered when
computing grid item's position.

Reviewed by David Hyatt.

  • fast/css-grid-layout/grid-align-justify-margin-border-padding-expected.txt: Added.
  • fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-lr-expected.txt: Added.
  • fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-lr.html: Added.
  • fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-rl-expected.txt: Added.
  • fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-rl.html: Added.
  • fast/css-grid-layout/grid-align-justify-margin-border-padding.html: Added.
  • fast/css-grid-layout/justify-self-cell-expected.txt: Added.
  • fast/css-grid-layout/justify-self-cell.html: Added.
  • fast/css-grid-layout/resources/grid.css:

(.directionLTR): Added. Useful for defining orthogonal flows.

Location:
trunk
Files:
8 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r183397 r183399  
     12015-04-27  Javier Fernandez  <jfernandez@igalia.com>
     2
     3        [CSS Grid Layout] Support for the justify-self and justify-items in grid layout
     4        https://bugs.webkit.org/show_bug.cgi?id=133280
     5
     6        Implementation of justify-self and justify-items properties for grid.
     7        Added additional testing for ensuring margin, padding and border are considered when
     8        computing grid item's position.
     9
     10        Reviewed by David Hyatt.
     11
     12        * fast/css-grid-layout/grid-align-justify-margin-border-padding-expected.txt: Added.
     13        * fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-lr-expected.txt: Added.
     14        * fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-lr.html: Added.
     15        * fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-rl-expected.txt: Added.
     16        * fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-rl.html: Added.
     17        * fast/css-grid-layout/grid-align-justify-margin-border-padding.html: Added.
     18        * fast/css-grid-layout/justify-self-cell-expected.txt: Added.
     19        * fast/css-grid-layout/justify-self-cell.html: Added.
     20        * fast/css-grid-layout/resources/grid.css:
     21        (.directionLTR): Added. Useful for defining orthogonal flows.
     22
    1232015-04-27  Youenn Fablet  <youenn.fablet@crf.canon.fr> and Xabier Rodriguez Calvar  <calvaris@igalia.com>
    224
  • trunk/LayoutTests/fast/css-grid-layout/resources/grid.css

    r180567 r183399  
    223223    direction: rtl;
    224224}
     225
     226.directionLTR {
     227    direction: ltr;
     228}
  • trunk/Source/WebCore/ChangeLog

    r183398 r183399  
     12015-04-27  Javier Fernandez  <jfernandez@igalia.com>
     2
     3        [CSS Grid Layout] Support for the justify-self and justify-items in grid layout
     4        https://bugs.webkit.org/show_bug.cgi?id=133280
     5
     6        Reviewed by David Hyatt.
     7
     8        Implementation of justify-self and justify-items properties for grid. It supports
     9        different writing-modes and direction. Margins, borders and paddings are also
     10        considered when computing the final position and stretched size.
     11
     12        This patch applies also a quite important refactoring of the alignment logic in
     13        order to share code between the two alignment dimensions, row-axis and column-axis.
     14
     15        Overflow handling is still missing and will be added later in a follow-up bug.
     16
     17        Tests: fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-lr.html
     18               fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-rl.html
     19               fast/css-grid-layout/grid-align-justify-margin-border-padding.html
     20               fast/css-grid-layout/justify-self-cell.html
     21
     22        * rendering/RenderGrid.cpp:
     23        (WebCore::RenderGrid::layoutGridItems):
     24        (WebCore::RenderGrid::columnAxisPositionForChild):
     25        (WebCore::RenderGrid::rowAxisPositionForChild):
     26        (WebCore::RenderGrid::rowPositionForChild):
     27        (WebCore::RenderGrid::columnPositionForChild):
     28        (WebCore::RenderGrid::findChildLogicalPosition):
     29        (WebCore::RenderGrid::allowedToStretchLogicalHeightForChild): Deleted.
     30        (WebCore::RenderGrid::needToStretchChildLogicalHeight): Deleted.
     31        (WebCore::RenderGrid::marginLogicalHeightForChild): Deleted.
     32        (WebCore::RenderGrid::availableAlignmentSpaceForChildBeforeStretching): Deleted.
     33        (WebCore::RenderGrid::applyStretchAlignmentToChildIfNeeded): Deleted.
     34        * rendering/RenderGrid.h:
     35        * rendering/style/RenderStyle.cpp:
     36        (WebCore::RenderStyle::resolveJustification):
     37        * rendering/style/RenderStyle.h:
     38
    1392015-04-27  Darin Adler  <darin@apple.com>
    240
  • trunk/Source/WebCore/rendering/RenderGrid.cpp

    r183370 r183399  
    4141static const int infinity = -1;
    4242
    43 enum GridAxisPosition {GridAxisStart, GridAxisEnd, GridAxisCenter};
    44 
    4543class GridTrack {
    4644public:
     
    11871185        child->layoutIfNeeded();
    11881186
    1189         child->setLogicalLocation(findChildLogicalPosition(*child, sizingData));
     1187        child->setLogicalLocation(findChildLogicalPosition(*child));
    11901188
    11911189        // If the child moved, we have to repaint it as well as any floating/positioned
     
    12411239}
    12421240
    1243 LayoutUnit RenderGrid::endOfRowForChild(const RenderBox& child) const
    1244 {
    1245     const GridCoordinate& coordinate = cachedGridCoordinate(child);
    1246 
    1247     LayoutUnit startOfRow = m_rowPositions[coordinate.rows.resolvedInitialPosition.toInt()];
    1248     // The grid items should be inside the grid container's border box, that's why they need to be shifted.
    1249     LayoutUnit rowPosition = startOfRow + marginBeforeForChild(child);
    1250 
    1251     LayoutUnit endOfRow = m_rowPositions[coordinate.rows.resolvedFinalPosition.next().toInt()];
    1252     // FIXME: This should account for the grid item's <overflow-position>.
    1253     return rowPosition + std::max<LayoutUnit>(0, endOfRow - startOfRow - child.logicalHeight());
    1254 }
    1255 
    1256 LayoutUnit RenderGrid::startOfRowForChild(const RenderBox& child) const
    1257 {
    1258     const GridCoordinate& coordinate = cachedGridCoordinate(child);
    1259 
    1260     LayoutUnit startOfRow = m_rowPositions[coordinate.rows.resolvedInitialPosition.toInt()];
    1261     // The grid items should be inside the grid container's border box, that's why they need to be shifted.
    1262     // FIXME: This should account for the grid item's <overflow-position>.
    1263     LayoutUnit rowPosition = startOfRow + marginBeforeForChild(child);
    1264 
    1265     return rowPosition;
    1266 }
    1267 
    1268 LayoutUnit RenderGrid::centeredRowPositionForChild(const RenderBox& child) const
    1269 {
    1270     const GridCoordinate& coordinate = cachedGridCoordinate(child);
    1271 
    1272     // The grid items should be inside the grid container's border box, that's why they need to be shifted.
    1273     LayoutUnit startOfRow = m_rowPositions[coordinate.rows.resolvedInitialPosition.toInt()];
    1274     LayoutUnit endOfRow = m_rowPositions[coordinate.rows.resolvedFinalPosition.next().toInt()];
    1275     // FIXME: This should account for the grid item's <overflow-position>.
    1276     return startOfRow + std::max<LayoutUnit>(0, endOfRow - startOfRow - child.logicalHeight()) / 2;
    1277 }
    1278 
    12791241bool RenderGrid::allowedToStretchLogicalHeightForChild(const RenderBox& child) const
    12801242{
     
    13281290}
    13291291
    1330 static GridAxisPosition columnAxisPosition(ItemPosition position, bool hasOrthogonalWritingMode, bool hasSameWritingMode)
    1331 {
    1332     switch (position) {
     1292GridAxisPosition RenderGrid::columnAxisPositionForChild(const RenderBox& child) const
     1293{
     1294    bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizontalWritingMode();
     1295    bool hasSameWritingMode = child.style().writingMode() == style().writingMode();
     1296
     1297    switch (RenderStyle::resolveAlignment(style(), child.style(), ItemPositionStretch)) {
    13331298    case ItemPositionSelfStart:
    13341299        // If orthogonal writing-modes, this computes to 'start'.
     
    13631328    case ItemPositionBaseline:
    13641329    case ItemPositionLastBaseline:
    1365         // FIXME: Implement the ItemPositionBaseline value. For now, we always 'start' align the child.
     1330        // FIXME: Implement the previous values. For now, we always 'start' align the child.
    13661331        return GridAxisStart;
    13671332    case ItemPositionAuto:
     
    13731338}
    13741339
     1340GridAxisPosition RenderGrid::rowAxisPositionForChild(const RenderBox& child) const
     1341{
     1342    bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizontalWritingMode();
     1343    bool hasSameDirection = child.style().direction() == style().direction();
     1344    bool isLTR = style().isLeftToRightDirection();
     1345
     1346    switch (RenderStyle::resolveJustification(style(), child.style(), ItemPositionStretch)) {
     1347    case ItemPositionSelfStart:
     1348        // For orthogonal writing-modes, this computes to 'start'
     1349        // FIXME: grid track sizing and positioning do not support orthogonal modes yet.
     1350        // self-start is based on the child's direction. That's why we need to check against the grid container's direction.
     1351        return (hasOrthogonalWritingMode || hasSameDirection) ? GridAxisStart : GridAxisEnd;
     1352    case ItemPositionSelfEnd:
     1353        // For orthogonal writing-modes, this computes to 'start'
     1354        // FIXME: grid track sizing and positioning do not support orthogonal modes yet.
     1355        return (hasOrthogonalWritingMode || hasSameDirection) ? GridAxisEnd : GridAxisStart;
     1356    case ItemPositionLeft:
     1357        return isLTR ? GridAxisStart : GridAxisEnd;
     1358    case ItemPositionRight:
     1359        return isLTR ? GridAxisEnd : GridAxisStart;
     1360    case ItemPositionCenter:
     1361        return GridAxisCenter;
     1362    case ItemPositionFlexStart: // Only used in flex layout, otherwise equivalent to 'start'.
     1363    case ItemPositionStart:
     1364        return GridAxisStart;
     1365    case ItemPositionFlexEnd: // Only used in flex layout, otherwise equivalent to 'end'.
     1366    case ItemPositionEnd:
     1367        return GridAxisEnd;
     1368    case ItemPositionStretch:
     1369        return GridAxisStart;
     1370    case ItemPositionBaseline:
     1371    case ItemPositionLastBaseline:
     1372        // FIXME: Implement the previous values. For now, we always 'start' align the child.
     1373        return GridAxisStart;
     1374    case ItemPositionAuto:
     1375        break;
     1376    }
     1377
     1378    ASSERT_NOT_REACHED();
     1379    return GridAxisStart;
     1380}
     1381
    13751382LayoutUnit RenderGrid::rowPositionForChild(const RenderBox& child) const
    13761383{
    1377     bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizontalWritingMode();
    1378     bool hasSameWritingMode = child.style().writingMode() == style().writingMode();
    1379     ItemPosition position = RenderStyle::resolveAlignment(style(), child.style(), ItemPositionStretch);
    1380 
    1381     switch (columnAxisPosition(position, hasOrthogonalWritingMode, hasSameWritingMode)) {
     1384    const GridCoordinate& coordinate = cachedGridCoordinate(child);
     1385    LayoutUnit startOfRow = m_rowPositions[coordinate.rows.resolvedInitialPosition.toInt()];
     1386    LayoutUnit endOfRow = m_rowPositions[coordinate.rows.resolvedFinalPosition.next().toInt()];
     1387    LayoutUnit startPosition = startOfRow + marginBeforeForChild(child);
     1388    // FIXME: This should account for the grid item's <overflow-position>.
     1389    LayoutUnit offsetFromStartPosition = endOfRow - startOfRow - child.logicalHeight() - child.marginLogicalHeight();
     1390
     1391    switch (columnAxisPositionForChild(child)) {
    13821392    case GridAxisStart:
    1383         return startOfRowForChild(child);
     1393        return startPosition;
    13841394    case GridAxisEnd:
    1385         return endOfRowForChild(child);
     1395        return startPosition + offsetFromStartPosition;
    13861396    case GridAxisCenter:
    1387         return centeredRowPositionForChild(child);
     1397        return startPosition + offsetFromStartPosition / 2;
    13881398    }
    13891399
     
    13921402}
    13931403
    1394 LayoutPoint RenderGrid::findChildLogicalPosition(const RenderBox& child, const GridSizingData& sizingData) const
     1404
     1405LayoutUnit RenderGrid::columnPositionForChild(const RenderBox& child) const
    13951406{
    13961407    const GridCoordinate& coordinate = cachedGridCoordinate(child);
    1397     ASSERT_UNUSED(sizingData, coordinate.columns.resolvedInitialPosition.toInt() < sizingData.columnTracks.size());
    1398     ASSERT_UNUSED(sizingData, coordinate.rows.resolvedInitialPosition.toInt() < sizingData.rowTracks.size());
    1399 
    1400     LayoutUnit columnPosition = m_columnPositions[coordinate.columns.resolvedInitialPosition.toInt()] + marginStartForChild(child);
     1408    LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.resolvedInitialPosition.toInt()];
     1409    LayoutUnit endOfColumn = m_columnPositions[coordinate.columns.resolvedFinalPosition.next().toInt()];
     1410    LayoutUnit startPosition = startOfColumn + marginStartForChild(child);
     1411    // FIXME: This should account for the grid item's <overflow-position>.
     1412    LayoutUnit offsetFromStartPosition = endOfColumn - startOfColumn - child.logicalWidth() - child.marginLogicalWidth();
     1413
     1414    switch (rowAxisPositionForChild(child)) {
     1415    case GridAxisStart:
     1416        return startPosition;
     1417    case GridAxisEnd:
     1418        return startPosition + offsetFromStartPosition;
     1419    case GridAxisCenter:
     1420        return startPosition + offsetFromStartPosition / 2;
     1421    }
     1422
     1423    ASSERT_NOT_REACHED();
     1424    return 0;
     1425}
     1426
     1427LayoutPoint RenderGrid::findChildLogicalPosition(const RenderBox& child) const
     1428{
     1429    LayoutUnit columnPosition = columnPositionForChild(child);
    14011430    // We stored m_columnPositions's data ignoring the direction, hence we might need now
    14021431    // to translate positions from RTL to LTR, as it's more convenient for painting.
  • trunk/Source/WebCore/rendering/RenderGrid.h

    r183370 r183399  
    4040class GridTrack;
    4141class GridItemWithSpan;
     42
     43enum GridAxisPosition {GridAxisStart, GridAxisEnd, GridAxisCenter};
    4244
    4345class RenderGrid final : public RenderBlock {
     
    118120    LayoutUnit minContentForChild(RenderBox&, GridTrackSizingDirection, Vector<GridTrack>& columnTracks);
    119121    LayoutUnit maxContentForChild(RenderBox&, GridTrackSizingDirection, Vector<GridTrack>& columnTracks);
    120     LayoutUnit startOfRowForChild(const RenderBox&) const;
    121     LayoutUnit endOfRowForChild(const RenderBox&) const;
    122     LayoutUnit centeredRowPositionForChild(const RenderBox&) const;
     122    GridAxisPosition columnAxisPositionForChild(const RenderBox&) const;
     123    GridAxisPosition rowAxisPositionForChild(const RenderBox&) const;
    123124    LayoutUnit rowPositionForChild(const RenderBox&) const;
    124     LayoutPoint findChildLogicalPosition(const RenderBox&, const GridSizingData&) const;
     125    LayoutUnit columnPositionForChild(const RenderBox&) const;
     126    LayoutPoint findChildLogicalPosition(const RenderBox&) const;
    125127    GridCoordinate cachedGridCoordinate(const RenderBox&) const;
     128
    126129
    127130    LayoutUnit gridAreaBreadthForChild(const RenderBox& child, GridTrackSizingDirection, const Vector<GridTrack>&) const;
  • trunk/Source/WebCore/rendering/style/RenderStyle.cpp

    r182974 r183399  
    180180}
    181181
     182ItemPosition RenderStyle::resolveJustification(const RenderStyle& parentStyle, const RenderStyle& childStyle, ItemPosition resolvedAutoPositionForLayoutObject)
     183{
     184    if (childStyle.justifySelf() == ItemPositionAuto)
     185        return (parentStyle.justifyItems() == ItemPositionAuto) ? resolvedAutoPositionForLayoutObject : parentStyle.justifyItems();
     186    return childStyle.justifySelf();
     187}
     188
    182189void RenderStyle::inheritFrom(const RenderStyle* inheritParent, IsAtShadowBoundary isAtShadowBoundary)
    183190{
  • trunk/Source/WebCore/rendering/style/RenderStyle.h

    r183364 r183399  
    493493
    494494    static ItemPosition resolveAlignment(const RenderStyle& parentStyle, const RenderStyle& childStyle, ItemPosition resolvedAutoPositionForRenderer);
     495    static ItemPosition resolveJustification(const RenderStyle& parentStyle, const RenderStyle& childStyle, ItemPosition resolvedAutoPositionForLayoutObject);
    495496
    496497    enum IsAtShadowBoundary {
Note: See TracChangeset for help on using the changeset viewer.