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

Side by Side Diff: Source/core/layout/LayoutFlexibleBox.cpp

Issue 988523003: Reimplement min-width: auto (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: rebaselined Created 5 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
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 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 // For multiline, the min preferred width is if you put a break between each item. 110 // For multiline, the min preferred width is if you put a break between each item.
111 minLogicalWidth = std::max(minLogicalWidth, minPreferredLogicalW idth); 111 minLogicalWidth = std::max(minLogicalWidth, minPreferredLogicalW idth);
112 } else { 112 } else {
113 minLogicalWidth += minPreferredLogicalWidth; 113 minLogicalWidth += minPreferredLogicalWidth;
114 } 114 }
115 } else { 115 } else {
116 minLogicalWidth = std::max(minPreferredLogicalWidth, minLogicalWidth ); 116 minLogicalWidth = std::max(minPreferredLogicalWidth, minLogicalWidth );
117 maxLogicalWidth = std::max(maxPreferredLogicalWidth, maxLogicalWidth ); 117 maxLogicalWidth = std::max(maxPreferredLogicalWidth, maxLogicalWidth );
118 } 118 }
119 } 119 }
120
121 maxLogicalWidth = std::max(minLogicalWidth, maxLogicalWidth); 120 maxLogicalWidth = std::max(minLogicalWidth, maxLogicalWidth);
122 121
123 LayoutUnit scrollbarWidth = intrinsicScrollbarLogicalWidth(); 122 LayoutUnit scrollbarWidth = intrinsicScrollbarLogicalWidth();
124 maxLogicalWidth += scrollbarWidth; 123 maxLogicalWidth += scrollbarWidth;
125 minLogicalWidth += scrollbarWidth; 124 minLogicalWidth += scrollbarWidth;
126 } 125 }
127 126
128 static int synthesizedBaselineFromContentBox(const LayoutBox& box, LineDirection Mode direction) 127 static int synthesizedBaselineFromContentBox(const LayoutBox& box, LineDirection Mode direction)
129 { 128 {
130 if (direction == HorizontalLine) { 129 if (direction == HorizontalLine) {
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 } 331 }
333 332
334 Length LayoutFlexibleBox::flexBasisForChild(LayoutBox& child) const 333 Length LayoutFlexibleBox::flexBasisForChild(LayoutBox& child) const
335 { 334 {
336 Length flexLength = child.style()->flexBasis(); 335 Length flexLength = child.style()->flexBasis();
337 if (flexLength.isAuto()) 336 if (flexLength.isAuto())
338 flexLength = isHorizontalFlow() ? child.style()->width() : child.style() ->height(); 337 flexLength = isHorizontalFlow() ? child.style()->width() : child.style() ->height();
339 return flexLength; 338 return flexLength;
340 } 339 }
341 340
341 bool LayoutFlexibleBox::percentageMainSizeIsResolvable()
342 {
343 return isHorizontalFlow() ? hasDefiniteLogicalWidth() : hasDefiniteLogicalHe ight();
344 }
345
342 LayoutUnit LayoutFlexibleBox::crossAxisExtentForChild(LayoutBox& child) const 346 LayoutUnit LayoutFlexibleBox::crossAxisExtentForChild(LayoutBox& child) const
343 { 347 {
344 return isHorizontalFlow() ? child.size().height() : child.size().width(); 348 return isHorizontalFlow() ? child.size().height() : child.size().width();
345 } 349 }
346 350
347 static inline LayoutUnit constrainedChildIntrinsicContentLogicalHeight(LayoutBox & child) 351 static inline LayoutUnit constrainedChildIntrinsicContentLogicalHeight(LayoutBox & child)
348 { 352 {
349 LayoutUnit childIntrinsicContentLogicalHeight = child.intrinsicContentLogica lHeight(); 353 LayoutUnit childIntrinsicContentLogicalHeight = child.intrinsicContentLogica lHeight();
350 return child.constrainLogicalHeightByMinMax(childIntrinsicContentLogicalHeig ht + child.borderAndPaddingLogicalHeight(), childIntrinsicContentLogicalHeight); 354 return child.constrainLogicalHeightByMinMax(childIntrinsicContentLogicalHeig ht + child.borderAndPaddingLogicalHeight(), childIntrinsicContentLogicalHeight);
351 } 355 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 } 408 }
405 409
406 LayoutUnit LayoutFlexibleBox::computeMainAxisExtentForChild(LayoutBox& child, Si zeType sizeType, const Length& size) 410 LayoutUnit LayoutFlexibleBox::computeMainAxisExtentForChild(LayoutBox& child, Si zeType sizeType, const Length& size)
407 { 411 {
408 // FIXME: This is wrong for orthogonal flows. It should use the flexbox's wr iting-mode, not the child's in order 412 // FIXME: This is wrong for orthogonal flows. It should use the flexbox's wr iting-mode, not the child's in order
409 // to figure out the logical height/width. 413 // to figure out the logical height/width.
410 if (isColumnFlow()) { 414 if (isColumnFlow()) {
411 // We don't have to check for "auto" here - computeContentLogicalHeight will just return -1 for that case anyway. 415 // We don't have to check for "auto" here - computeContentLogicalHeight will just return -1 for that case anyway.
412 if (size.isIntrinsic()) 416 if (size.isIntrinsic())
413 child.layoutIfNeeded(); 417 child.layoutIfNeeded();
414 return child.computeContentLogicalHeight(size, child.logicalHeight() - c hild.borderAndPaddingLogicalHeight()) + child.scrollbarLogicalHeight(); 418 return child.computeContentLogicalHeight(sizeType, size, child.logicalHe ight() - child.borderAndPaddingLogicalHeight()) + child.scrollbarLogicalHeight() ;
415 } 419 }
416 return child.computeLogicalWidthUsing(sizeType, size, contentLogicalWidth(), this) - child.borderAndPaddingLogicalWidth(); 420 return child.computeLogicalWidthUsing(sizeType, size, contentLogicalWidth(), this) - child.borderAndPaddingLogicalWidth();
417 } 421 }
418 422
419 WritingMode LayoutFlexibleBox::transformedWritingMode() const 423 WritingMode LayoutFlexibleBox::transformedWritingMode() const
420 { 424 {
421 WritingMode mode = style()->writingMode(); 425 WritingMode mode = style()->writingMode();
422 if (!isColumnFlow()) 426 if (!isColumnFlow())
423 return mode; 427 return mode;
424 428
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 if (isHorizontalFlow()) { 824 if (isHorizontalFlow()) {
821 child->setMarginLeft(computeChildMarginValue(child->style()->marginL eft())); 825 child->setMarginLeft(computeChildMarginValue(child->style()->marginL eft()));
822 child->setMarginRight(computeChildMarginValue(child->style()->margin Right())); 826 child->setMarginRight(computeChildMarginValue(child->style()->margin Right()));
823 } else { 827 } else {
824 child->setMarginTop(computeChildMarginValue(child->style()->marginTo p())); 828 child->setMarginTop(computeChildMarginValue(child->style()->marginTo p()));
825 child->setMarginBottom(computeChildMarginValue(child->style()->margi nBottom())); 829 child->setMarginBottom(computeChildMarginValue(child->style()->margi nBottom()));
826 } 830 }
827 } 831 }
828 } 832 }
829 833
830 LayoutUnit LayoutFlexibleBox::adjustChildSizeForMinAndMax(LayoutBox& child, Layo utUnit childSize) 834 LayoutUnit LayoutFlexibleBox::adjustChildSizeForMinAndMax(LayoutBox& child, Layo utUnit childSize, bool hasInfiniteLineLength)
831 { 835 {
832 Length max = isHorizontalFlow() ? child.style()->maxWidth() : child.style()- >maxHeight(); 836 Length max = isHorizontalFlow() ? child.style()->maxWidth() : child.style()- >maxHeight();
837 LayoutUnit maxExtent = -1;
833 if (max.isSpecifiedOrIntrinsic()) { 838 if (max.isSpecifiedOrIntrinsic()) {
834 LayoutUnit maxExtent = computeMainAxisExtentForChild(child, MaxSize, max ); 839 maxExtent = computeMainAxisExtentForChild(child, MaxSize, max);
835 if (maxExtent != -1 && childSize > maxExtent) 840 if (maxExtent != -1 && childSize > maxExtent)
836 childSize = maxExtent; 841 childSize = maxExtent;
837 } 842 }
838 843
839 Length min = isHorizontalFlow() ? child.style()->minWidth() : child.style()- >minHeight(); 844 Length min = isHorizontalFlow() ? child.style()->minWidth() : child.style()- >minHeight();
840 LayoutUnit minExtent = 0; 845 LayoutUnit minExtent = 0;
841 if (min.isSpecifiedOrIntrinsic()) 846 if (min.isSpecifiedOrIntrinsic()) {
842 minExtent = computeMainAxisExtentForChild(child, MinSize, min); 847 minExtent = computeMainAxisExtentForChild(child, MinSize, min);
848 // computeMainAxisExtentForChild can return -1 when the child has a perc entage
849 // min size, but we have an indefinite size in that axis.
850 minExtent = std::max(LayoutUnit(0), minExtent);
851 } else if (min.isAuto() && mainAxisOverflowForChild(child) == OVISIBLE) {
852 // css-flexbox section 4.5
853 LayoutUnit contentSize = computeMainAxisExtentForChild(child, MinSize, L ength(MinContent));
854 ASSERT(contentSize >= 0);
855 if (maxExtent != -1 && contentSize > maxExtent)
856 contentSize = maxExtent;
857
858 bool hasClampedSize = !childPreferredMainAxisContentExtentRequiresLayout (child, hasInfiniteLineLength);
859 if (hasClampedSize) {
860 Length flexBasis = flexBasisForChild(child);
861 bool flexBasisIsDefinite = flexBasis.isFixed() || (flexBasis.isPerce nt() && percentageMainSizeIsResolvable());
862 if (flexBasisIsDefinite) {
863 LayoutUnit resolvedFlexBasis = computeMainAxisExtentForChild(chi ld, MainOrPreferredSize, flexBasis);
864 ASSERT(resolvedFlexBasis >= 0);
865 LayoutUnit clampedSize = resolvedFlexBasis;
866 if (maxExtent != -1 && clampedSize > maxExtent)
867 clampedSize = maxExtent;
868
869 minExtent = std::min(clampedSize, contentSize);
870 } else {
871 minExtent = contentSize;
872 }
873 } else {
874 minExtent = contentSize;
875 }
876 // TODO(cbiesinger): Implement aspect ratio handling (here, transferred size)
leviw_travelin_and_unemployed 2015/04/02 22:14:36 Tracking bug?
cbiesinger 2015/04/03 18:49:17 Done.
877 }
878 ASSERT(minExtent >= 0);
843 return std::max(childSize, minExtent); 879 return std::max(childSize, minExtent);
844 } 880 }
845 881
846 bool LayoutFlexibleBox::computeNextFlexLine(OrderedFlexItemList& orderedChildren , LayoutUnit& sumFlexBaseSize, double& totalFlexGrow, double& totalWeightedFlexS hrink, LayoutUnit& sumHypotheticalMainSize, bool& hasInfiniteLineLength, bool re layoutChildren) 882 bool LayoutFlexibleBox::computeNextFlexLine(OrderedFlexItemList& orderedChildren , LayoutUnit& sumFlexBaseSize, double& totalFlexGrow, double& totalWeightedFlexS hrink, LayoutUnit& sumHypotheticalMainSize, bool& hasInfiniteLineLength, bool re layoutChildren)
847 { 883 {
848 orderedChildren.clear(); 884 orderedChildren.clear();
849 sumFlexBaseSize = 0; 885 sumFlexBaseSize = 0;
850 totalFlexGrow = totalWeightedFlexShrink = 0; 886 totalFlexGrow = totalWeightedFlexShrink = 0;
851 sumHypotheticalMainSize = 0; 887 sumHypotheticalMainSize = 0;
852 888
853 if (!m_orderIterator.currentChild()) 889 if (!m_orderIterator.currentChild())
854 return false; 890 return false;
855 891
856 LayoutUnit lineBreakLength = mainAxisContentExtent(LayoutUnit::max()); 892 LayoutUnit lineBreakLength = mainAxisContentExtent(LayoutUnit::max());
857 hasInfiniteLineLength = lineBreakLength == LayoutUnit::max(); 893 hasInfiniteLineLength = lineBreakLength == LayoutUnit::max();
858 894
859 bool lineHasInFlowItem = false; 895 bool lineHasInFlowItem = false;
860 896
861 for (LayoutBox* child = m_orderIterator.currentChild(); child; child = m_ord erIterator.next()) { 897 for (LayoutBox* child = m_orderIterator.currentChild(); child; child = m_ord erIterator.next()) {
862 if (child->isOutOfFlowPositioned()) { 898 if (child->isOutOfFlowPositioned()) {
863 orderedChildren.append(child); 899 orderedChildren.append(child);
864 continue; 900 continue;
865 } 901 }
866 902
867 LayoutUnit childMainAxisExtent = preferredMainAxisContentExtentForChild( *child, hasInfiniteLineLength, relayoutChildren); 903 LayoutUnit childMainAxisExtent = preferredMainAxisContentExtentForChild( *child, hasInfiniteLineLength, relayoutChildren);
868 LayoutUnit childMainAxisMarginBorderPadding = mainAxisBorderAndPaddingEx tentForChild(*child) 904 LayoutUnit childMainAxisMarginBorderPadding = mainAxisBorderAndPaddingEx tentForChild(*child)
869 + (isHorizontalFlow() ? child->marginWidth() : child->marginHeight() ); 905 + (isHorizontalFlow() ? child->marginWidth() : child->marginHeight() );
870 LayoutUnit childFlexBaseSize = childMainAxisExtent + childMainAxisMargin BorderPadding; 906 LayoutUnit childFlexBaseSize = childMainAxisExtent + childMainAxisMargin BorderPadding;
871 907
872 LayoutUnit childMinMaxAppliedMainAxisExtent = adjustChildSizeForMinAndMa x(*child, childMainAxisExtent); 908 LayoutUnit childMinMaxAppliedMainAxisExtent = adjustChildSizeForMinAndMa x(*child, childMainAxisExtent, hasInfiniteLineLength);
873 LayoutUnit childHypotheticalMainSize = childMinMaxAppliedMainAxisExtent + childMainAxisMarginBorderPadding; 909 LayoutUnit childHypotheticalMainSize = childMinMaxAppliedMainAxisExtent + childMainAxisMarginBorderPadding;
874 910
875 if (isMultiline() && sumHypotheticalMainSize + childHypotheticalMainSize > lineBreakLength && lineHasInFlowItem) 911 if (isMultiline() && sumHypotheticalMainSize + childHypotheticalMainSize > lineBreakLength && lineHasInFlowItem)
876 break; 912 break;
877 orderedChildren.append(child); 913 orderedChildren.append(child);
878 lineHasInFlowItem = true; 914 lineHasInFlowItem = true;
879 sumFlexBaseSize += childFlexBaseSize; 915 sumFlexBaseSize += childFlexBaseSize;
880 totalFlexGrow += child->style()->flexGrow(); 916 totalFlexGrow += child->style()->flexGrow();
881 totalWeightedFlexShrink += child->style()->flexShrink() * childMainAxisE xtent; 917 totalWeightedFlexShrink += child->style()->flexShrink() * childMainAxisE xtent;
882 sumHypotheticalMainSize += childHypotheticalMainSize; 918 sumHypotheticalMainSize += childHypotheticalMainSize;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
918 LayoutUnit preferredChildSize = preferredMainAxisContentExtentForChi ld(*child, hasInfiniteLineLength); 954 LayoutUnit preferredChildSize = preferredMainAxisContentExtentForChi ld(*child, hasInfiniteLineLength);
919 LayoutUnit childSize = preferredChildSize; 955 LayoutUnit childSize = preferredChildSize;
920 double extraSpace = 0; 956 double extraSpace = 0;
921 if (availableFreeSpace > 0 && totalFlexGrow > 0 && flexSign == Posit iveFlexibility && std::isfinite(totalFlexGrow)) 957 if (availableFreeSpace > 0 && totalFlexGrow > 0 && flexSign == Posit iveFlexibility && std::isfinite(totalFlexGrow))
922 extraSpace = availableFreeSpace * child->style()->flexGrow() / t otalFlexGrow; 958 extraSpace = availableFreeSpace * child->style()->flexGrow() / t otalFlexGrow;
923 else if (availableFreeSpace < 0 && totalWeightedFlexShrink > 0 && fl exSign == NegativeFlexibility && std::isfinite(totalWeightedFlexShrink)) 959 else if (availableFreeSpace < 0 && totalWeightedFlexShrink > 0 && fl exSign == NegativeFlexibility && std::isfinite(totalWeightedFlexShrink))
924 extraSpace = availableFreeSpace * child->style()->flexShrink() * preferredChildSize / totalWeightedFlexShrink; 960 extraSpace = availableFreeSpace * child->style()->flexShrink() * preferredChildSize / totalWeightedFlexShrink;
925 if (std::isfinite(extraSpace)) 961 if (std::isfinite(extraSpace))
926 childSize += LayoutUnit::fromFloatRound(extraSpace); 962 childSize += LayoutUnit::fromFloatRound(extraSpace);
927 963
928 LayoutUnit adjustedChildSize = adjustChildSizeForMinAndMax(*child, c hildSize); 964 LayoutUnit adjustedChildSize = adjustChildSizeForMinAndMax(*child, c hildSize, hasInfiniteLineLength);
929 childSizes.append(adjustedChildSize); 965 childSizes.append(adjustedChildSize);
930 usedFreeSpace += adjustedChildSize - preferredChildSize; 966 usedFreeSpace += adjustedChildSize - preferredChildSize;
931 967
932 LayoutUnit violation = adjustedChildSize - childSize; 968 LayoutUnit violation = adjustedChildSize - childSize;
933 if (violation > 0) 969 if (violation > 0)
934 minViolations.append(Violation(child, adjustedChildSize)); 970 minViolations.append(Violation(child, adjustedChildSize));
935 else if (violation < 0) 971 else if (violation < 0)
936 maxViolations.append(Violation(child, adjustedChildSize)); 972 maxViolations.append(Violation(child, adjustedChildSize));
937 totalViolation += violation; 973 totalViolation += violation;
938 } 974 }
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1045 } 1081 }
1046 1082
1047 bool LayoutFlexibleBox::needToStretchChildLogicalHeight(LayoutBox& child) const 1083 bool LayoutFlexibleBox::needToStretchChildLogicalHeight(LayoutBox& child) const
1048 { 1084 {
1049 if (alignmentForChild(child) != ItemPositionStretch) 1085 if (alignmentForChild(child) != ItemPositionStretch)
1050 return false; 1086 return false;
1051 1087
1052 return isHorizontalFlow() && child.style()->height().isAuto(); 1088 return isHorizontalFlow() && child.style()->height().isAuto();
1053 } 1089 }
1054 1090
1091 EOverflow LayoutFlexibleBox::mainAxisOverflowForChild(LayoutBox& child) const
1092 {
1093 if (isHorizontalFlow())
1094 return child.styleRef().overflowX();
1095 return child.styleRef().overflowY();
1096 }
1097
1055 void LayoutFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, cons t OrderedFlexItemList& children, const Vector<LayoutUnit, 16>& childSizes, Layou tUnit availableFreeSpace, bool relayoutChildren, Vector<LineContext>& lineContex ts, bool hasInfiniteLineLength) 1098 void LayoutFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, cons t OrderedFlexItemList& children, const Vector<LayoutUnit, 16>& childSizes, Layou tUnit availableFreeSpace, bool relayoutChildren, Vector<LineContext>& lineContex ts, bool hasInfiniteLineLength)
1056 { 1099 {
1057 ASSERT(childSizes.size() == children.size()); 1100 ASSERT(childSizes.size() == children.size());
1058 1101
1059 size_t numberOfChildrenForJustifyContent = numberOfInFlowPositionedChildren( children); 1102 size_t numberOfChildrenForJustifyContent = numberOfInFlowPositionedChildren( children);
1060 LayoutUnit autoMarginOffset = autoMarginOffsetInMainAxis(children, available FreeSpace); 1103 LayoutUnit autoMarginOffset = autoMarginOffsetInMainAxis(children, available FreeSpace);
1061 LayoutUnit mainAxisOffset = flowAwareBorderStart() + flowAwarePaddingStart() ; 1104 LayoutUnit mainAxisOffset = flowAwareBorderStart() + flowAwarePaddingStart() ;
1062 mainAxisOffset += initialJustifyContentOffset(availableFreeSpace, style()->j ustifyContent(), style()->justifyContentDistribution(), numberOfChildrenForJusti fyContent); 1105 mainAxisOffset += initialJustifyContentOffset(availableFreeSpace, style()->j ustifyContent(), style()->justifyContentDistribution(), numberOfChildrenForJusti fyContent);
1063 if (style()->flexDirection() == FlowRowReverse) 1106 if (style()->flexDirection() == FlowRowReverse)
1064 mainAxisOffset += isHorizontalFlow() ? verticalScrollbarWidth() : horizo ntalScrollbarHeight(); 1107 mainAxisOffset += isHorizontalFlow() ? verticalScrollbarWidth() : horizo ntalScrollbarHeight();
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
1395 ASSERT(child); 1438 ASSERT(child);
1396 LayoutUnit lineCrossAxisExtent = lineContexts[lineNumber].crossAxisE xtent; 1439 LayoutUnit lineCrossAxisExtent = lineContexts[lineNumber].crossAxisE xtent;
1397 LayoutUnit originalOffset = lineContexts[lineNumber].crossAxisOffset - crossAxisStartEdge; 1440 LayoutUnit originalOffset = lineContexts[lineNumber].crossAxisOffset - crossAxisStartEdge;
1398 LayoutUnit newOffset = contentExtent - originalOffset - lineCrossAxi sExtent; 1441 LayoutUnit newOffset = contentExtent - originalOffset - lineCrossAxi sExtent;
1399 adjustAlignmentForChild(*child, newOffset - originalOffset); 1442 adjustAlignmentForChild(*child, newOffset - originalOffset);
1400 } 1443 }
1401 } 1444 }
1402 } 1445 }
1403 1446
1404 } 1447 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698