Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(501)

Side by Side Diff: Source/core/rendering/RenderGrid.cpp

Issue 613273002: [CSS Grid Layout] Stretch value for align and justify properties. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: resolveAlignment and resolveJustification now defined in RenderStyle. Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 600 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 const GridLength& oldMinTrackBreadth = trackSize.minTrackBreadth(); 611 const GridLength& oldMinTrackBreadth = trackSize.minTrackBreadth();
612 const GridLength& oldMaxTrackBreadth = trackSize.maxTrackBreadth(); 612 const GridLength& oldMaxTrackBreadth = trackSize.maxTrackBreadth();
613 return GridTrackSize(oldMinTrackBreadth.isPercentage() ? Length(MinConte nt) : oldMinTrackBreadth, oldMaxTrackBreadth.isPercentage() ? Length(MaxContent) : oldMaxTrackBreadth); 613 return GridTrackSize(oldMinTrackBreadth.isPercentage() ? Length(MinConte nt) : oldMinTrackBreadth, oldMaxTrackBreadth.isPercentage() ? Length(MaxContent) : oldMaxTrackBreadth);
614 } 614 }
615 615
616 return trackSize; 616 return trackSize;
617 } 617 }
618 618
619 LayoutUnit RenderGrid::logicalHeightForChild(RenderBox& child, Vector<GridTrack> & columnTracks) 619 LayoutUnit RenderGrid::logicalHeightForChild(RenderBox& child, Vector<GridTrack> & columnTracks)
620 { 620 {
621 child.clearOverrideLogicalContentHeight();
Julien - ping for review 2014/10/31 17:17:12 If we don't need this call before everything else,
jfernandez 2014/10/31 22:55:59 Acknowledged.
622
621 SubtreeLayoutScope layoutScope(child); 623 SubtreeLayoutScope layoutScope(child);
622 LayoutUnit oldOverrideContainingBlockContentLogicalWidth = child.hasOverride ContainingBlockLogicalWidth() ? child.overrideContainingBlockContentLogicalWidth () : LayoutUnit(); 624 LayoutUnit oldOverrideContainingBlockContentLogicalWidth = child.hasOverride ContainingBlockLogicalWidth() ? child.overrideContainingBlockContentLogicalWidth () : LayoutUnit();
623 LayoutUnit overrideContainingBlockContentLogicalWidth = gridAreaBreadthForCh ild(child, ForColumns, columnTracks); 625 LayoutUnit overrideContainingBlockContentLogicalWidth = gridAreaBreadthForCh ild(child, ForColumns, columnTracks);
624 if (child.style()->logicalHeight().isPercent() || oldOverrideContainingBlock ContentLogicalWidth != overrideContainingBlockContentLogicalWidth) 626 if (child.style()->logicalHeight().isPercent() || oldOverrideContainingBlock ContentLogicalWidth != overrideContainingBlockContentLogicalWidth)
625 layoutScope.setNeedsLayout(&child); 627 layoutScope.setNeedsLayout(&child);
626 628
627 child.setOverrideContainingBlockContentLogicalWidth(overrideContainingBlockC ontentLogicalWidth); 629 child.setOverrideContainingBlockContentLogicalWidth(overrideContainingBlockC ontentLogicalWidth);
628 // If |child| has a percentage logical height, we shouldn't let it override its intrinsic height, which is 630 // If |child| has a percentage logical height, we shouldn't let it override its intrinsic height, which is
629 // what we are interested in here. Thus we need to set the override logical height to -1 (no possible resolution). 631 // what we are interested in here. Thus we need to set the override logical height to -1 (no possible resolution).
630 child.setOverrideContainingBlockContentLogicalHeight(-1); 632 child.setOverrideContainingBlockContentLogicalHeight(-1);
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after
1110 LayoutUnit overrideContainingBlockContentLogicalWidth = gridAreaBreadthF orChild(*child, ForColumns, sizingData.columnTracks); 1112 LayoutUnit overrideContainingBlockContentLogicalWidth = gridAreaBreadthF orChild(*child, ForColumns, sizingData.columnTracks);
1111 LayoutUnit overrideContainingBlockContentLogicalHeight = gridAreaBreadth ForChild(*child, ForRows, sizingData.rowTracks); 1113 LayoutUnit overrideContainingBlockContentLogicalHeight = gridAreaBreadth ForChild(*child, ForRows, sizingData.rowTracks);
1112 1114
1113 SubtreeLayoutScope layoutScope(*child); 1115 SubtreeLayoutScope layoutScope(*child);
1114 if (oldOverrideContainingBlockContentLogicalWidth != overrideContainingB lockContentLogicalWidth || (oldOverrideContainingBlockContentLogicalHeight != ov errideContainingBlockContentLogicalHeight && child->hasRelativeLogicalHeight())) 1116 if (oldOverrideContainingBlockContentLogicalWidth != overrideContainingB lockContentLogicalWidth || (oldOverrideContainingBlockContentLogicalHeight != ov errideContainingBlockContentLogicalHeight && child->hasRelativeLogicalHeight()))
1115 layoutScope.setNeedsLayout(child); 1117 layoutScope.setNeedsLayout(child);
1116 1118
1117 child->setOverrideContainingBlockContentLogicalWidth(overrideContainingB lockContentLogicalWidth); 1119 child->setOverrideContainingBlockContentLogicalWidth(overrideContainingB lockContentLogicalWidth);
1118 child->setOverrideContainingBlockContentLogicalHeight(overrideContaining BlockContentLogicalHeight); 1120 child->setOverrideContainingBlockContentLogicalHeight(overrideContaining BlockContentLogicalHeight);
1119 1121
1120 // FIXME: Grid items should stretch to fill their cells. Once we 1122 applyStretchAlignmentToChildIfNeeded(*child, overrideContainingBlockCont entLogicalHeight);
1121 // implement grid-{column,row}-align, we can also shrink to fit. For 1123
1122 // now, just size as if we were a regular child.
1123 child->layoutIfNeeded(); 1124 child->layoutIfNeeded();
1124 1125
1125 #if ENABLE(ASSERT) 1126 #if ENABLE(ASSERT)
1126 const GridCoordinate& coordinate = cachedGridCoordinate(*child); 1127 const GridCoordinate& coordinate = cachedGridCoordinate(*child);
1127 ASSERT(coordinate.columns.resolvedInitialPosition.toInt() < sizingData.c olumnTracks.size()); 1128 ASSERT(coordinate.columns.resolvedInitialPosition.toInt() < sizingData.c olumnTracks.size());
1128 ASSERT(coordinate.rows.resolvedInitialPosition.toInt() < sizingData.rowT racks.size()); 1129 ASSERT(coordinate.rows.resolvedInitialPosition.toInt() < sizingData.rowT racks.size());
1129 #endif 1130 #endif
1130 child->setLogicalLocation(findChildLogicalPosition(*child)); 1131 child->setLogicalLocation(findChildLogicalPosition(*child));
1131 1132
1132 // Keep track of children overflowing their grid area as we might need t o paint them even if the grid-area is 1133 // Keep track of children overflowing their grid area as we might need t o paint them even if the grid-area is
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1213 LayoutUnit RenderGrid::centeredColumnPositionForChild(const RenderBox& child) co nst 1214 LayoutUnit RenderGrid::centeredColumnPositionForChild(const RenderBox& child) co nst
1214 { 1215 {
1215 const GridCoordinate& coordinate = cachedGridCoordinate(child); 1216 const GridCoordinate& coordinate = cachedGridCoordinate(child);
1216 LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.resolvedInit ialPosition.toInt()]; 1217 LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.resolvedInit ialPosition.toInt()];
1217 LayoutUnit endOfColumn = m_columnPositions[coordinate.columns.resolvedFinalP osition.next().toInt()]; 1218 LayoutUnit endOfColumn = m_columnPositions[coordinate.columns.resolvedFinalP osition.next().toInt()];
1218 LayoutUnit columnPosition = startOfColumn + marginStartForChild(&child); 1219 LayoutUnit columnPosition = startOfColumn + marginStartForChild(&child);
1219 // FIXME: This should account for the grid item's <overflow-position>. 1220 // FIXME: This should account for the grid item's <overflow-position>.
1220 return columnPosition + std::max<LayoutUnit>(0, endOfColumn - startOfColumn - child.logicalWidth()) / 2; 1221 return columnPosition + std::max<LayoutUnit>(0, endOfColumn - startOfColumn - child.logicalWidth()) / 2;
1221 } 1222 }
1222 1223
1223 static ItemPosition resolveJustification(const RenderStyle* parentStyle, const R enderStyle* childStyle)
1224 {
1225 ItemPosition justify = childStyle->justifySelf();
1226 if (justify == ItemPositionAuto)
1227 justify = (parentStyle->justifyItems() == ItemPositionAuto) ? ItemPositi onStretch : parentStyle->justifyItems();
1228
1229 return justify;
1230 }
1231
1232 LayoutUnit RenderGrid::columnPositionForChild(const RenderBox& child) const 1224 LayoutUnit RenderGrid::columnPositionForChild(const RenderBox& child) const
1233 { 1225 {
1234 bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizon talWritingMode(); 1226 bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizon talWritingMode();
1235 1227
1236 switch (resolveJustification(style(), child.style())) { 1228 switch (RenderStyle::resolveJustification(style(), child.style())) {
1237 case ItemPositionSelfStart: 1229 case ItemPositionSelfStart:
1238 // For orthogonal writing-modes, this computes to 'start' 1230 // For orthogonal writing-modes, this computes to 'start'
1239 // FIXME: grid track sizing and positioning do not support orthogonal mo des yet. 1231 // FIXME: grid track sizing and positioning do not support orthogonal mo des yet.
1240 if (hasOrthogonalWritingMode) 1232 if (hasOrthogonalWritingMode)
1241 return columnPositionAlignedWithGridContainerStart(child); 1233 return columnPositionAlignedWithGridContainerStart(child);
1242 1234
1243 // self-start is based on the child's direction. That's why we need to c heck against the grid container's direction. 1235 // self-start is based on the child's direction. That's why we need to c heck against the grid container's direction.
1244 if (child.style()->direction() != style()->direction()) 1236 if (child.style()->direction() != style()->direction())
1245 return columnPositionAlignedWithGridContainerEnd(child); 1237 return columnPositionAlignedWithGridContainerEnd(child);
1246 1238
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1286 case ItemPositionCenter: 1278 case ItemPositionCenter:
1287 return centeredColumnPositionForChild(child); 1279 return centeredColumnPositionForChild(child);
1288 case ItemPositionStart: 1280 case ItemPositionStart:
1289 return columnPositionAlignedWithGridContainerStart(child); 1281 return columnPositionAlignedWithGridContainerStart(child);
1290 case ItemPositionEnd: 1282 case ItemPositionEnd:
1291 return columnPositionAlignedWithGridContainerEnd(child); 1283 return columnPositionAlignedWithGridContainerEnd(child);
1292 1284
1293 case ItemPositionAuto: 1285 case ItemPositionAuto:
1294 break; 1286 break;
1295 case ItemPositionStretch: 1287 case ItemPositionStretch:
1288 return startOfColumnForChild(child);
1296 case ItemPositionBaseline: 1289 case ItemPositionBaseline:
1297 case ItemPositionLastBaseline: 1290 case ItemPositionLastBaseline:
1298 // FIXME: Implement the previous values. For now, we always start align the child. 1291 // FIXME: Implement the previous values. For now, we always start align the child.
1299 return startOfColumnForChild(child); 1292 return startOfColumnForChild(child);
1300 } 1293 }
1301 1294
1302 ASSERT_NOT_REACHED(); 1295 ASSERT_NOT_REACHED();
1303 return 0; 1296 return 0;
1304 } 1297 }
1305 1298
(...skipping 27 matching lines...) Expand all
1333 const GridCoordinate& coordinate = cachedGridCoordinate(child); 1326 const GridCoordinate& coordinate = cachedGridCoordinate(child);
1334 1327
1335 // The grid items should be inside the grid container's border box, that's w hy they need to be shifted. 1328 // The grid items should be inside the grid container's border box, that's w hy they need to be shifted.
1336 LayoutUnit startOfRow = m_rowPositions[coordinate.rows.resolvedInitialPositi on.toInt()] + marginBeforeForChild(&child); 1329 LayoutUnit startOfRow = m_rowPositions[coordinate.rows.resolvedInitialPositi on.toInt()] + marginBeforeForChild(&child);
1337 LayoutUnit endOfRow = m_rowPositions[coordinate.rows.resolvedFinalPosition.n ext().toInt()]; 1330 LayoutUnit endOfRow = m_rowPositions[coordinate.rows.resolvedFinalPosition.n ext().toInt()];
1338 1331
1339 // FIXME: This should account for the grid item's <overflow-position>. 1332 // FIXME: This should account for the grid item's <overflow-position>.
1340 return startOfRow + std::max<LayoutUnit>(0, endOfRow - startOfRow - child.lo gicalHeight()) / 2; 1333 return startOfRow + std::max<LayoutUnit>(0, endOfRow - startOfRow - child.lo gicalHeight()) / 2;
1341 } 1334 }
1342 1335
1336 static inline LayoutUnit constrainedChildIntrinsicContentLogicalHeight(const Ren derBox& child)
1337 {
1338 LayoutUnit childIntrinsicContentLogicalHeight = child.intrinsicContentLogica lHeight();
1339 return child.constrainLogicalHeightByMinMax(childIntrinsicContentLogicalHeig ht + child.borderAndPaddingLogicalHeight(), childIntrinsicContentLogicalHeight);
Julien - ping for review 2014/10/31 17:17:12 The min / max constraining logic is not tested :(
jfernandez 2014/10/31 22:55:59 The grid-align-justify-stretch.html test contains
1340 }
1341
1342 bool RenderGrid::needToStretchChildLogicalHeight(const RenderBox& child) const
1343 {
1344 if (RenderStyle::resolveAlignment(style(), child.style()) != ItemPositionStr etch)
1345 return false;
1346
1347 return isHorizontalWritingMode() && child.style()->height().isAuto();
1348 }
1349
1350 LayoutUnit RenderGrid::childIntrinsicHeight(const RenderBox& child) const
1351 {
1352 if (child.isHorizontalWritingMode() && needToStretchChildLogicalHeight(child ))
1353 return constrainedChildIntrinsicContentLogicalHeight(child);
1354 return child.height();
1355 }
1356
1357 LayoutUnit RenderGrid::childIntrinsicWidth(const RenderBox& child) const
1358 {
1359 if (!child.isHorizontalWritingMode() && needToStretchChildLogicalHeight(chil d))
1360 return constrainedChildIntrinsicContentLogicalHeight(child);
1361 return child.width();
1362 }
1363
1364 LayoutUnit RenderGrid::intrinsicLogicalHeightForChild(const RenderBox& child) co nst
1365 {
1366 return isHorizontalWritingMode() ? childIntrinsicHeight(child) : childIntrin sicWidth(child);
1367 }
1368
1369 LayoutUnit RenderGrid::marginLogicalHeightForChild(const RenderBox& child) const
Julien - ping for review 2014/10/31 17:17:13 This doesn't look grid related so it should be mov
jfernandez 2014/10/31 22:55:59 I agree. As I commented before, I'll do a new patc
1370 {
1371 return isHorizontalWritingMode() ? child.marginHeight() : child.marginWidth( );
1372 }
1373
1374 LayoutUnit RenderGrid::availableAlignmentSpaceForChildBeforeStretching(LayoutUni t gridAreaBreadthForChild, const RenderBox& child) const
1375 {
1376 ASSERT(!child.isOutOfFlowPositioned());
1377 LayoutUnit childLogicalHeight = marginLogicalHeightForChild(child) + intrins icLogicalHeightForChild(child);
1378 return gridAreaBreadthForChild - childLogicalHeight;
1379 }
1380
1381 void RenderGrid::applyStretchAlignmentToChildIfNeeded(RenderBox& child, LayoutUn it gridAreaBreadthForChild)
1382 {
1383 if (RenderStyle::resolveAlignment(style(), child.style()) != ItemPositionStr etch)
1384 return;
1385
1386 bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizon talWritingMode();
1387 if (child.style()->logicalHeight().isAuto()) {
1388 // FIXME: If the child has orthogonal flow, then it already has an overr ide height set, so use it.
1389 // FIXME: grid track sizing and positioning do not support orthogonal mo des yet.
1390 if (!hasOrthogonalWritingMode) {
1391 LayoutUnit heightBeforeStretching = needToStretchChildLogicalHeight( child) ? constrainedChildIntrinsicContentLogicalHeight(child) : child.logicalHei ght();
1392 LayoutUnit stretchedLogicalHeight = heightBeforeStretching + availab leAlignmentSpaceForChildBeforeStretching(gridAreaBreadthForChild, child);
1393 LayoutUnit desiredLogicalHeight = child.constrainLogicalHeightByMinM ax(stretchedLogicalHeight, heightBeforeStretching - child.borderAndPaddingLogica lHeight());
1394 LayoutUnit desiredLogicalContentHeight = desiredLogicalHeight - chil d.borderAndPaddingLogicalHeight();
1395
1396 // FIXME: Can avoid laying out here in some cases. See https://webki t.org/b/87905.
1397 if (desiredLogicalHeight != child.logicalHeight() || !child.hasOverr ideHeight() || desiredLogicalContentHeight != child.overrideLogicalContentHeight ()) {
1398 child.setOverrideLogicalContentHeight(desiredLogicalContentHeigh t);
1399 child.setLogicalHeight(0);
1400 child.forceChildLayout();
1401 }
1402 }
1403 }
Julien - ping for review 2014/10/31 17:17:12 A lot of this logic is similar to RenderFlexibleBo
jfernandez 2014/10/31 22:55:59 Acknowledged.
1404 }
1405
1343 LayoutUnit RenderGrid::rowPositionForChild(const RenderBox& child) const 1406 LayoutUnit RenderGrid::rowPositionForChild(const RenderBox& child) const
1344 { 1407 {
1345 bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizon talWritingMode(); 1408 bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizon talWritingMode();
1346 ItemPosition alignSelf = RenderStyle::resolveAlignment(style(), child.style( )); 1409 switch (RenderStyle::resolveAlignment(style(), child.style())) {
1347
1348 switch (alignSelf) {
1349 case ItemPositionSelfStart: 1410 case ItemPositionSelfStart:
1350 // If orthogonal writing-modes, this computes to 'Start'. 1411 // If orthogonal writing-modes, this computes to 'Start'.
1351 // FIXME: grid track sizing and positioning does not support orthogonal modes yet. 1412 // FIXME: grid track sizing and positioning does not support orthogonal modes yet.
1352 if (hasOrthogonalWritingMode) 1413 if (hasOrthogonalWritingMode)
1353 return startOfRowForChild(child); 1414 return startOfRowForChild(child);
1354 1415
1355 // self-start is based on the child's block axis direction. That's why w e need to check against the grid container's block flow. 1416 // self-start is based on the child's block axis direction. That's why w e need to check against the grid container's block flow.
1356 if (child.style()->writingMode() != style()->writingMode()) 1417 if (child.style()->writingMode() != style()->writingMode())
1357 return endOfRowForChild(child); 1418 return endOfRowForChild(child);
1358 1419
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1391 return centeredRowPositionForChild(child); 1452 return centeredRowPositionForChild(child);
1392 // Only used in flex layout, for other layout, it's equivalent to 'Start '. 1453 // Only used in flex layout, for other layout, it's equivalent to 'Start '.
1393 case ItemPositionFlexStart: 1454 case ItemPositionFlexStart:
1394 case ItemPositionStart: 1455 case ItemPositionStart:
1395 return startOfRowForChild(child); 1456 return startOfRowForChild(child);
1396 // Only used in flex layout, for other layout, it's equivalent to 'End'. 1457 // Only used in flex layout, for other layout, it's equivalent to 'End'.
1397 case ItemPositionFlexEnd: 1458 case ItemPositionFlexEnd:
1398 case ItemPositionEnd: 1459 case ItemPositionEnd:
1399 return endOfRowForChild(child); 1460 return endOfRowForChild(child);
1400 case ItemPositionStretch: 1461 case ItemPositionStretch:
1401 // FIXME: Implement the Stretch value. For now, we always start align th e child.
1402 return startOfRowForChild(child); 1462 return startOfRowForChild(child);
1403 case ItemPositionBaseline: 1463 case ItemPositionBaseline:
1404 case ItemPositionLastBaseline: 1464 case ItemPositionLastBaseline:
1405 // FIXME: Implement the ItemPositionBaseline value. For now, we always s tart align the child. 1465 // FIXME: Implement the ItemPositionBaseline value. For now, we always s tart align the child.
1406 return startOfRowForChild(child); 1466 return startOfRowForChild(child);
1407 case ItemPositionAuto: 1467 case ItemPositionAuto:
1408 break; 1468 break;
1409 } 1469 }
1410 1470
1411 ASSERT_NOT_REACHED(); 1471 ASSERT_NOT_REACHED();
(...skipping 17 matching lines...) Expand all
1429 if (isOutOfFlowPositioned()) 1489 if (isOutOfFlowPositioned())
1430 return "RenderGrid (positioned)"; 1490 return "RenderGrid (positioned)";
1431 if (isAnonymous()) 1491 if (isAnonymous())
1432 return "RenderGrid (generated)"; 1492 return "RenderGrid (generated)";
1433 if (isRelPositioned()) 1493 if (isRelPositioned())
1434 return "RenderGrid (relative positioned)"; 1494 return "RenderGrid (relative positioned)";
1435 return "RenderGrid"; 1495 return "RenderGrid";
1436 } 1496 }
1437 1497
1438 } // namespace blink 1498 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698