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

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

Issue 237823002: Properly shrink stretched flexbox children on relayout (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Made comments clearer Created 6 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « Source/core/rendering/RenderFlexibleBox.h ('k') | Source/core/rendering/RenderListBox.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011 Google Inc. All rights reserved. 2 * Copyright (C) 2011 Google 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 are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 setHeight(extent); 383 setHeight(extent);
384 else 384 else
385 setWidth(extent); 385 setWidth(extent);
386 } 386 }
387 387
388 LayoutUnit RenderFlexibleBox::crossAxisExtentForChild(RenderBox* child) const 388 LayoutUnit RenderFlexibleBox::crossAxisExtentForChild(RenderBox* child) const
389 { 389 {
390 return isHorizontalFlow() ? child->height() : child->width(); 390 return isHorizontalFlow() ? child->height() : child->width();
391 } 391 }
392 392
393 static inline LayoutUnit constrainedChildIntrinsicContentLogicalHeight(RenderBox * child)
394 {
395 LayoutUnit childIntrinsicContentLogicalHeight = child->intrinsicContentLogic alHeight();
396 return child->constrainLogicalHeightByMinMax(childIntrinsicContentLogicalHei ght + child->borderAndPaddingLogicalHeight(), childIntrinsicContentLogicalHeight );
397 }
398
399 LayoutUnit RenderFlexibleBox::childIntrinsicHeight(RenderBox* child) const
400 {
401 if (child->isHorizontalWritingMode() && needToStretchChildLogicalHeight(chil d))
402 return constrainedChildIntrinsicContentLogicalHeight(child);
403 return child->height();
404 }
405
406 LayoutUnit RenderFlexibleBox::childIntrinsicWidth(RenderBox* child) const
407 {
408 if (!child->isHorizontalWritingMode() && needToStretchChildLogicalHeight(chi ld))
409 return constrainedChildIntrinsicContentLogicalHeight(child);
410 return child->width();
411 }
412
413 LayoutUnit RenderFlexibleBox::crossAxisIntrinsicExtentForChild(RenderBox* child) const
414 {
415 return isHorizontalFlow() ? childIntrinsicHeight(child) : childIntrinsicWidt h(child);
416 }
417
393 LayoutUnit RenderFlexibleBox::mainAxisExtentForChild(RenderBox* child) const 418 LayoutUnit RenderFlexibleBox::mainAxisExtentForChild(RenderBox* child) const
394 { 419 {
395 return isHorizontalFlow() ? child->width() : child->height(); 420 return isHorizontalFlow() ? child->width() : child->height();
396 } 421 }
397 422
398 LayoutUnit RenderFlexibleBox::crossAxisExtent() const 423 LayoutUnit RenderFlexibleBox::crossAxisExtent() const
399 { 424 {
400 return isHorizontalFlow() ? height() : width(); 425 return isHorizontalFlow() ? height() : width();
401 } 426 }
402 427
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
759 return child->style()->marginLeft().isAuto() || child->style()->marginRight( ).isAuto(); 784 return child->style()->marginLeft().isAuto() || child->style()->marginRight( ).isAuto();
760 } 785 }
761 786
762 LayoutUnit RenderFlexibleBox::availableAlignmentSpaceForChild(LayoutUnit lineCro ssAxisExtent, RenderBox* child) 787 LayoutUnit RenderFlexibleBox::availableAlignmentSpaceForChild(LayoutUnit lineCro ssAxisExtent, RenderBox* child)
763 { 788 {
764 ASSERT(!child->isOutOfFlowPositioned()); 789 ASSERT(!child->isOutOfFlowPositioned());
765 LayoutUnit childCrossExtent = crossAxisMarginExtentForChild(child) + crossAx isExtentForChild(child); 790 LayoutUnit childCrossExtent = crossAxisMarginExtentForChild(child) + crossAx isExtentForChild(child);
766 return lineCrossAxisExtent - childCrossExtent; 791 return lineCrossAxisExtent - childCrossExtent;
767 } 792 }
768 793
794 LayoutUnit RenderFlexibleBox::availableAlignmentSpaceForChildBeforeStretching(La youtUnit lineCrossAxisExtent, RenderBox* child)
795 {
796 ASSERT(!child->isOutOfFlowPositioned());
797 LayoutUnit childCrossExtent = crossAxisMarginExtentForChild(child) + crossAx isIntrinsicExtentForChild(child);
798 return lineCrossAxisExtent - childCrossExtent;
799 }
800
769 bool RenderFlexibleBox::updateAutoMarginsInCrossAxis(RenderBox* child, LayoutUni t availableAlignmentSpace) 801 bool RenderFlexibleBox::updateAutoMarginsInCrossAxis(RenderBox* child, LayoutUni t availableAlignmentSpace)
770 { 802 {
771 ASSERT(!child->isOutOfFlowPositioned()); 803 ASSERT(!child->isOutOfFlowPositioned());
772 ASSERT(availableAlignmentSpace >= 0); 804 ASSERT(availableAlignmentSpace >= 0);
773 805
774 bool isHorizontal = isHorizontalFlow(); 806 bool isHorizontal = isHorizontalFlow();
775 Length topOrLeft = isHorizontal ? child->style()->marginTop() : child->style ()->marginLeft(); 807 Length topOrLeft = isHorizontal ? child->style()->marginTop() : child->style ()->marginLeft();
776 Length bottomOrRight = isHorizontal ? child->style()->marginBottom() : child ->style()->marginRight(); 808 Length bottomOrRight = isHorizontal ? child->style()->marginBottom() : child ->style()->marginRight();
777 if (topOrLeft.isAuto() && bottomOrRight.isAuto()) { 809 if (topOrLeft.isAuto() && bottomOrRight.isAuto()) {
778 adjustAlignmentForChild(child, availableAlignmentSpace / 2); 810 adjustAlignmentForChild(child, availableAlignmentSpace / 2);
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
1068 child->setMarginBottom(0); 1100 child->setMarginBottom(0);
1069 } else { 1101 } else {
1070 if (child->style()->marginLeft().isAuto()) 1102 if (child->style()->marginLeft().isAuto())
1071 child->setMarginLeft(0); 1103 child->setMarginLeft(0);
1072 if (child->style()->marginRight().isAuto()) 1104 if (child->style()->marginRight().isAuto())
1073 child->setMarginRight(0); 1105 child->setMarginRight(0);
1074 } 1106 }
1075 } 1107 }
1076 } 1108 }
1077 1109
1110 bool RenderFlexibleBox::needToStretchChildLogicalHeight(RenderBox* child) const
1111 {
1112 if (alignmentForChild(child) != ItemPositionStretch)
1113 return false;
1114
1115 return isHorizontalFlow() && child->style()->height().isAuto();
1116 }
1117
1078 void RenderFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, cons t OrderedFlexItemList& children, const Vector<LayoutUnit, 16>& childSizes, Layou tUnit availableFreeSpace, bool relayoutChildren, Vector<LineContext>& lineContex ts, bool hasInfiniteLineLength) 1118 void RenderFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, cons t OrderedFlexItemList& children, const Vector<LayoutUnit, 16>& childSizes, Layou tUnit availableFreeSpace, bool relayoutChildren, Vector<LineContext>& lineContex ts, bool hasInfiniteLineLength)
1079 { 1119 {
1080 ASSERT(childSizes.size() == children.size()); 1120 ASSERT(childSizes.size() == children.size());
1081 1121
1082 size_t numberOfChildrenForJustifyContent = numberOfInFlowPositionedChildren( children); 1122 size_t numberOfChildrenForJustifyContent = numberOfInFlowPositionedChildren( children);
1083 LayoutUnit autoMarginOffset = autoMarginOffsetInMainAxis(children, available FreeSpace); 1123 LayoutUnit autoMarginOffset = autoMarginOffsetInMainAxis(children, available FreeSpace);
1084 LayoutUnit mainAxisOffset = flowAwareBorderStart() + flowAwarePaddingStart() ; 1124 LayoutUnit mainAxisOffset = flowAwareBorderStart() + flowAwarePaddingStart() ;
1085 mainAxisOffset += initialJustifyContentOffset(availableFreeSpace, style()->j ustifyContent(), numberOfChildrenForJustifyContent); 1125 mainAxisOffset += initialJustifyContentOffset(availableFreeSpace, style()->j ustifyContent(), numberOfChildrenForJustifyContent);
1086 if (style()->flexDirection() == FlowRowReverse) 1126 if (style()->flexDirection() == FlowRowReverse)
1087 mainAxisOffset += isHorizontalFlow() ? verticalScrollbarWidth() : horizo ntalScrollbarHeight(); 1127 mainAxisOffset += isHorizontalFlow() ? verticalScrollbarWidth() : horizo ntalScrollbarHeight();
(...skipping 28 matching lines...) Expand all
1116 1156
1117 LayoutUnit childCrossAxisMarginBoxExtent; 1157 LayoutUnit childCrossAxisMarginBoxExtent;
1118 if (alignmentForChild(child) == ItemPositionBaseline && !hasAutoMarginsI nCrossAxis(child)) { 1158 if (alignmentForChild(child) == ItemPositionBaseline && !hasAutoMarginsI nCrossAxis(child)) {
1119 LayoutUnit ascent = marginBoxAscentForChild(child); 1159 LayoutUnit ascent = marginBoxAscentForChild(child);
1120 LayoutUnit descent = (crossAxisMarginExtentForChild(child) + crossAx isExtentForChild(child)) - ascent; 1160 LayoutUnit descent = (crossAxisMarginExtentForChild(child) + crossAx isExtentForChild(child)) - ascent;
1121 1161
1122 maxAscent = std::max(maxAscent, ascent); 1162 maxAscent = std::max(maxAscent, ascent);
1123 maxDescent = std::max(maxDescent, descent); 1163 maxDescent = std::max(maxDescent, descent);
1124 1164
1125 childCrossAxisMarginBoxExtent = maxAscent + maxDescent; 1165 childCrossAxisMarginBoxExtent = maxAscent + maxDescent;
1126 } else 1166 } else {
1127 childCrossAxisMarginBoxExtent = crossAxisExtentForChild(child) + cro ssAxisMarginExtentForChild(child); 1167 childCrossAxisMarginBoxExtent = crossAxisIntrinsicExtentForChild(chi ld) + crossAxisMarginExtentForChild(child);
1168 }
1128 if (!isColumnFlow()) 1169 if (!isColumnFlow())
1129 setLogicalHeight(std::max(logicalHeight(), crossAxisOffset + flowAwa reBorderAfter() + flowAwarePaddingAfter() + childCrossAxisMarginBoxExtent + cros sAxisScrollbarExtent())); 1170 setLogicalHeight(std::max(logicalHeight(), crossAxisOffset + flowAwa reBorderAfter() + flowAwarePaddingAfter() + childCrossAxisMarginBoxExtent + cros sAxisScrollbarExtent()));
1130 maxChildCrossAxisExtent = std::max(maxChildCrossAxisExtent, childCrossAx isMarginBoxExtent); 1171 maxChildCrossAxisExtent = std::max(maxChildCrossAxisExtent, childCrossAx isMarginBoxExtent);
1131 1172
1132 mainAxisOffset += flowAwareMarginStartForChild(child); 1173 mainAxisOffset += flowAwareMarginStartForChild(child);
1133 1174
1134 LayoutUnit childMainExtent = mainAxisExtentForChild(child); 1175 LayoutUnit childMainExtent = mainAxisExtentForChild(child);
1135 // In an RTL column situation, this will apply the margin-right/margin-e nd on the left. 1176 // In an RTL column situation, this will apply the margin-right/margin-e nd on the left.
1136 // This will be fixed later in flipForRightToLeftColumn. 1177 // This will be fixed later in flipForRightToLeftColumn.
1137 LayoutPoint childLocation(shouldFlipMainAxis ? totalMainExtent - mainAxi sOffset - childMainExtent : mainAxisOffset, 1178 LayoutPoint childLocation(shouldFlipMainAxis ? totalMainExtent - mainAxi sOffset - childMainExtent : mainAxisOffset,
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
1337 adjustAlignmentForChild(child, minMarginAfterBaseline); 1378 adjustAlignmentForChild(child, minMarginAfterBaseline);
1338 } 1379 }
1339 } 1380 }
1340 } 1381 }
1341 1382
1342 void RenderFlexibleBox::applyStretchAlignmentToChild(RenderBox* child, LayoutUni t lineCrossAxisExtent) 1383 void RenderFlexibleBox::applyStretchAlignmentToChild(RenderBox* child, LayoutUni t lineCrossAxisExtent)
1343 { 1384 {
1344 if (!isColumnFlow() && child->style()->logicalHeight().isAuto()) { 1385 if (!isColumnFlow() && child->style()->logicalHeight().isAuto()) {
1345 // FIXME: If the child has orthogonal flow, then it already has an overr ide height set, so use it. 1386 // FIXME: If the child has orthogonal flow, then it already has an overr ide height set, so use it.
1346 if (!hasOrthogonalFlow(child)) { 1387 if (!hasOrthogonalFlow(child)) {
1347 LayoutUnit stretchedLogicalHeight = child->logicalHeight() + availab leAlignmentSpaceForChild(lineCrossAxisExtent, child); 1388 LayoutUnit heightBeforeStretching = needToStretchChildLogicalHeight( child) ? constrainedChildIntrinsicContentLogicalHeight(child) : child->logicalHe ight();
1389 LayoutUnit stretchedLogicalHeight = heightBeforeStretching + availab leAlignmentSpaceForChildBeforeStretching(lineCrossAxisExtent, child);
1348 ASSERT(!child->needsLayout()); 1390 ASSERT(!child->needsLayout());
1349 LayoutUnit desiredLogicalHeight = child->constrainLogicalHeightByMin Max(stretchedLogicalHeight, child->logicalHeight() - child->borderAndPaddingLogi calHeight()); 1391 LayoutUnit desiredLogicalHeight = child->constrainLogicalHeightByMin Max(stretchedLogicalHeight, heightBeforeStretching - child->borderAndPaddingLogi calHeight());
1350 1392
1351 // FIXME: Can avoid laying out here in some cases. See https://webki t.org/b/87905. 1393 // FIXME: Can avoid laying out here in some cases. See https://webki t.org/b/87905.
1352 if (desiredLogicalHeight != child->logicalHeight()) { 1394 if (desiredLogicalHeight != child->logicalHeight()) {
1353 child->setOverrideLogicalContentHeight(desiredLogicalHeight - ch ild->borderAndPaddingLogicalHeight()); 1395 child->setOverrideLogicalContentHeight(desiredLogicalHeight - ch ild->borderAndPaddingLogicalHeight());
1354 child->setLogicalHeight(0); 1396 child->setLogicalHeight(0);
1355 child->forceChildLayout(); 1397 child->forceChildLayout();
1356 } 1398 }
1357 } 1399 }
1358 } else if (isColumnFlow() && child->style()->logicalWidth().isAuto()) { 1400 } else if (isColumnFlow() && child->style()->logicalWidth().isAuto()) {
1359 // FIXME: If the child doesn't have orthogonal flow, then it already has an override width set, so use it. 1401 // FIXME: If the child doesn't have orthogonal flow, then it already has an override width set, so use it.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1395 ASSERT(child); 1437 ASSERT(child);
1396 LayoutUnit lineCrossAxisExtent = lineContexts[lineNumber].crossAxisE xtent; 1438 LayoutUnit lineCrossAxisExtent = lineContexts[lineNumber].crossAxisE xtent;
1397 LayoutUnit originalOffset = lineContexts[lineNumber].crossAxisOffset - crossAxisStartEdge; 1439 LayoutUnit originalOffset = lineContexts[lineNumber].crossAxisOffset - crossAxisStartEdge;
1398 LayoutUnit newOffset = contentExtent - originalOffset - lineCrossAxi sExtent; 1440 LayoutUnit newOffset = contentExtent - originalOffset - lineCrossAxi sExtent;
1399 adjustAlignmentForChild(child, newOffset - originalOffset); 1441 adjustAlignmentForChild(child, newOffset - originalOffset);
1400 } 1442 }
1401 } 1443 }
1402 } 1444 }
1403 1445
1404 } 1446 }
OLDNEW
« no previous file with comments | « Source/core/rendering/RenderFlexibleBox.h ('k') | Source/core/rendering/RenderListBox.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698