OLD | NEW |
---|---|
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 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
262 } | 262 } |
263 } | 263 } |
264 | 264 |
265 void LayoutFlexibleBox::layoutBlock(bool relayoutChildren) | 265 void LayoutFlexibleBox::layoutBlock(bool relayoutChildren) |
266 { | 266 { |
267 ASSERT(needsLayout()); | 267 ASSERT(needsLayout()); |
268 | 268 |
269 if (!relayoutChildren && simplifiedLayout()) | 269 if (!relayoutChildren && simplifiedLayout()) |
270 return; | 270 return; |
271 | 271 |
272 m_relaidOutChildren.clear(); | |
273 | |
272 if (updateLogicalWidthAndColumnWidth()) | 274 if (updateLogicalWidthAndColumnWidth()) |
273 relayoutChildren = true; | 275 relayoutChildren = true; |
274 | 276 |
275 SubtreeLayoutScope layoutScope(*this); | 277 SubtreeLayoutScope layoutScope(*this); |
276 LayoutUnit previousHeight = logicalHeight(); | 278 LayoutUnit previousHeight = logicalHeight(); |
277 setLogicalHeight(borderAndPaddingLogicalHeight() + scrollbarLogicalHeight()) ; | 279 setLogicalHeight(borderAndPaddingLogicalHeight() + scrollbarLogicalHeight()) ; |
278 | 280 |
279 { | 281 { |
280 TextAutosizer::LayoutScope textAutosizerLayoutScope(this); | 282 TextAutosizer::LayoutScope textAutosizerLayoutScope(this); |
281 LayoutState state(*this, locationOffset()); | 283 LayoutState state(*this, locationOffset()); |
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
729 LayoutUnit mainSize; | 731 LayoutUnit mainSize; |
730 if (hasOrthogonalFlow(child)) { | 732 if (hasOrthogonalFlow(child)) { |
731 mainSize = child.logicalHeight(); | 733 mainSize = child.logicalHeight(); |
732 } else { | 734 } else { |
733 // The max preferred logical width includes the intrinsic scrollbar logi cal width, which is only set for | 735 // The max preferred logical width includes the intrinsic scrollbar logi cal width, which is only set for |
734 // overflow: scroll. To handle overflow: auto, we have to take scrollbar LogicalWidth() into account, and then | 736 // overflow: scroll. To handle overflow: auto, we have to take scrollbar LogicalWidth() into account, and then |
735 // subtract the intrinsic width again so as to not double-count overflow : scroll scrollbars. | 737 // subtract the intrinsic width again so as to not double-count overflow : scroll scrollbars. |
736 mainSize = child.maxPreferredLogicalWidth() + child.scrollbarLogicalWidt h() - child.intrinsicScrollbarLogicalWidth(); | 738 mainSize = child.maxPreferredLogicalWidth() + child.scrollbarLogicalWidt h() - child.intrinsicScrollbarLogicalWidth(); |
737 } | 739 } |
738 m_intrinsicSizeAlongMainAxis.set(&child, mainSize); | 740 m_intrinsicSizeAlongMainAxis.set(&child, mainSize); |
741 m_relaidOutChildren.add(&child); | |
739 } | 742 } |
740 | 743 |
741 void LayoutFlexibleBox::clearCachedMainSizeForChild(const LayoutBox& child) | 744 void LayoutFlexibleBox::clearCachedMainSizeForChild(const LayoutBox& child) |
742 { | 745 { |
743 m_intrinsicSizeAlongMainAxis.remove(&child); | 746 m_intrinsicSizeAlongMainAxis.remove(&child); |
744 } | 747 } |
745 | 748 |
746 LayoutUnit LayoutFlexibleBox::computeInnerFlexBaseSizeForChild(LayoutBox& child, ChildLayoutType childLayoutType) | 749 LayoutUnit LayoutFlexibleBox::computeInnerFlexBaseSizeForChild(LayoutBox& child, ChildLayoutType childLayoutType) |
747 { | 750 { |
748 child.clearOverrideSize(); | 751 child.clearOverrideSize(); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
780 Vector<LineContext> lineContexts; | 783 Vector<LineContext> lineContexts; |
781 OrderedFlexItemList orderedChildren; | 784 OrderedFlexItemList orderedChildren; |
782 LayoutUnit sumFlexBaseSize; | 785 LayoutUnit sumFlexBaseSize; |
783 double totalFlexGrow; | 786 double totalFlexGrow; |
784 double totalFlexShrink; | 787 double totalFlexShrink; |
785 double totalWeightedFlexShrink; | 788 double totalWeightedFlexShrink; |
786 LayoutUnit sumHypotheticalMainSize; | 789 LayoutUnit sumHypotheticalMainSize; |
787 | 790 |
788 Vector<LayoutUnit, 16> childSizes; | 791 Vector<LayoutUnit, 16> childSizes; |
789 | 792 |
793 dirtyForLayoutFromPercentageHeightDescendants(layoutScope); | |
leviw_travelin_and_unemployed
2016/04/13 20:10:22
Why this change? Is it necessary?
| |
794 | |
790 m_orderIterator.first(); | 795 m_orderIterator.first(); |
791 LayoutUnit crossAxisOffset = flowAwareBorderBefore() + flowAwarePaddingBefor e(); | 796 LayoutUnit crossAxisOffset = flowAwareBorderBefore() + flowAwarePaddingBefor e(); |
792 while (computeNextFlexLine(orderedChildren, sumFlexBaseSize, totalFlexGrow, totalFlexShrink, totalWeightedFlexShrink, sumHypotheticalMainSize, relayoutChild ren)) { | 797 while (computeNextFlexLine(orderedChildren, sumFlexBaseSize, totalFlexGrow, totalFlexShrink, totalWeightedFlexShrink, sumHypotheticalMainSize, relayoutChild ren)) { |
793 LayoutUnit containerMainInnerSize = mainAxisContentExtent(sumHypothetica lMainSize); | 798 LayoutUnit containerMainInnerSize = mainAxisContentExtent(sumHypothetica lMainSize); |
794 // availableFreeSpace is the initial amount of free space in this flexbo x. | 799 // availableFreeSpace is the initial amount of free space in this flexbo x. |
795 // remainingFreeSpace starts out at the same value but as we place and l ay out | 800 // remainingFreeSpace starts out at the same value but as we place and l ay out |
796 // flex items we subtract from it. Note that both values can be negative . | 801 // flex items we subtract from it. Note that both values can be negative . |
797 LayoutUnit availableFreeSpace = containerMainInnerSize - sumFlexBaseSize ; | 802 LayoutUnit availableFreeSpace = containerMainInnerSize - sumFlexBaseSize ; |
798 LayoutUnit remainingFreeSpace = availableFreeSpace; | 803 LayoutUnit remainingFreeSpace = availableFreeSpace; |
799 FlexSign flexSign = (sumHypotheticalMainSize < containerMainInnerSize) ? PositiveFlexibility : NegativeFlexibility; | 804 FlexSign flexSign = (sumHypotheticalMainSize < containerMainInnerSize) ? PositiveFlexibility : NegativeFlexibility; |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1060 return LayoutUnit(-1); | 1065 return LayoutUnit(-1); |
1061 return toLayoutFlexibleBox(parent())->childLogicalHeightForPercentageRes olution(*this); | 1066 return toLayoutFlexibleBox(parent())->childLogicalHeightForPercentageRes olution(*this); |
1062 } | 1067 } |
1063 LogicalExtentComputedValues computedValues; | 1068 LogicalExtentComputedValues computedValues; |
1064 computeLogicalHeight(LayoutUnit(-1), LayoutUnit(), computedValues); | 1069 computeLogicalHeight(LayoutUnit(-1), LayoutUnit(), computedValues); |
1065 return computedValues.m_extent; | 1070 return computedValues.m_extent; |
1066 } | 1071 } |
1067 | 1072 |
1068 LayoutUnit LayoutFlexibleBox::crossSizeForPercentageResolution(const LayoutBox& child) | 1073 LayoutUnit LayoutFlexibleBox::crossSizeForPercentageResolution(const LayoutBox& child) |
1069 { | 1074 { |
1070 // This function implements section 9.8. Definite and Indefinite Sizes, case | 1075 if (alignmentForChild(child) != ItemPositionStretch) |
1071 // 1) of the flexbox spec. | |
1072 // We need to check for multiline and a definite cross size of the flexbox | |
1073 // per https://drafts.csswg.org/css-flexbox/#definite-sizes, and for | |
1074 // stretch, auto margins, and an indefinite cross size of the flex item per | |
1075 // https://drafts.csswg.org/css-flexbox/#stretched (linked from that | |
1076 // section) | |
1077 if (isMultiline() || alignmentForChild(child) != ItemPositionStretch || hasA utoMarginsInCrossAxis(child)) | |
1078 return LayoutUnit(-1); | 1076 return LayoutUnit(-1); |
1079 | 1077 |
1080 const Length& childCrossLength = isHorizontalFlow() ? child.styleRef().heigh t() : child.styleRef().width(); | 1078 // Here we implement https://drafts.csswg.org/css-flexbox/#algo-stretch |
1081 if (crossAxisLengthIsDefinite(child, childCrossLength)) | 1079 if (hasOrthogonalFlow(child) && child.hasOverrideLogicalContentWidth()) |
1082 return LayoutUnit(-1); | 1080 return child.overrideLogicalContentWidth(); |
1081 if (!hasOrthogonalFlow(child) && child.hasOverrideLogicalContentHeight()) | |
1082 return child.overrideLogicalContentHeight(); | |
1083 | 1083 |
1084 LayoutUnit childCrossSize; | 1084 // We don't currently implement the optimization from https://drafts.csswg.o rg/css-flexbox/#definite-sizes |
1085 | 1085 // case 1. While that could speed up a specialized case, it requires determi ning if we have a definite |
1086 if (isColumnFlow()) { | 1086 // size, which itself is not cheap. We can consider implementing it at a lat er time. |
1087 LayoutUnit definiteWidth = computeDefiniteLogicalWidth(); | 1087 // (The correctness is ensured by redoing layout in applyStretchAlignmentToC hild) |
1088 if (definiteWidth == LayoutUnit(-1)) | 1088 return LayoutUnit(-1); |
1089 return definiteWidth; | |
1090 childCrossSize = definiteWidth - borderAndPaddingLogicalWidth() - scroll barLogicalWidth(); | |
1091 childCrossSize = child.constrainLogicalWidthByMinMax(childCrossSize, chi ldCrossSize, this) - child.scrollbarLogicalWidth() - child.borderAndPaddingLogic alWidth(); | |
1092 } else { | |
1093 LayoutUnit definiteHeight = computeDefiniteLogicalHeight(); | |
1094 if (definiteHeight == LayoutUnit(-1)) | |
1095 return definiteHeight; | |
1096 | |
1097 childCrossSize = definiteHeight - borderAndPaddingLogicalHeight() - scro llbarLogicalHeight(); | |
1098 childCrossSize = child.constrainLogicalHeightByMinMax(childCrossSize, La youtUnit(-1)) - child.scrollbarLogicalHeight() - child.borderAndPaddingLogicalHe ight(); | |
1099 } | |
1100 return childCrossSize; | |
1101 } | 1089 } |
1102 | 1090 |
1103 LayoutUnit LayoutFlexibleBox::mainSizeForPercentageResolution(const LayoutBox& c hild) | 1091 LayoutUnit LayoutFlexibleBox::mainSizeForPercentageResolution(const LayoutBox& c hild) |
1104 { | 1092 { |
1105 // This function implements section 9.8. Definite and Indefinite Sizes, case | 1093 // This function implements section 9.8. Definite and Indefinite Sizes, case |
1106 // 2) of the flexbox spec. | 1094 // 2) of the flexbox spec. |
1107 // We need to check for the flexbox to have a definite main size, and for th e | 1095 // We need to check for the flexbox to have a definite main size, and for th e |
1108 // flex item to have a definite flex basis. | 1096 // flex item to have a definite flex basis. |
1109 const Length& flexBasis = flexBasisForChild(child); | 1097 const Length& flexBasis = flexBasisForChild(child); |
1110 if (!mainAxisLengthIsDefinite(child, flexBasis)) | 1098 if (!mainAxisLengthIsDefinite(child, flexBasis)) |
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1451 prepareChildForPositionedLayout(*child, mainAxisOffset, crossAxisOff set, FlipForRowReverse); | 1439 prepareChildForPositionedLayout(*child, mainAxisOffset, crossAxisOff set, FlipForRowReverse); |
1452 continue; | 1440 continue; |
1453 } | 1441 } |
1454 | 1442 |
1455 // FIXME Investigate if this can be removed based on other flags. crbug. com/370010 | 1443 // FIXME Investigate if this can be removed based on other flags. crbug. com/370010 |
1456 child->setMayNeedPaintInvalidation(); | 1444 child->setMayNeedPaintInvalidation(); |
1457 | 1445 |
1458 LayoutUnit childPreferredSize = childSizes[i] + mainAxisBorderAndPadding ExtentForChild(*child); | 1446 LayoutUnit childPreferredSize = childSizes[i] + mainAxisBorderAndPadding ExtentForChild(*child); |
1459 setOverrideMainAxisSizeForChild(*child, childPreferredSize); | 1447 setOverrideMainAxisSizeForChild(*child, childPreferredSize); |
1460 if (childPreferredSize != mainAxisExtentForChild(*child)) { | 1448 if (childPreferredSize != mainAxisExtentForChild(*child)) { |
1461 // We will correctly handle percentage sizing even without re-laying out here, because | |
1462 // if our size was already correct, then percentage resolution was a lso correct due | |
1463 // to the way percentage sizing is defined by flexbox (ie. it requir es a definite flex basis) | |
1464 // TODO(cbiesinger): When flex-basis is used instead of width/height , this is not the case. That | |
1465 // problem is not limited to percentages. See http://crbug.com/53165 6#c11 | |
1466 child->setChildNeedsLayout(MarkOnlyThis); | 1449 child->setChildNeedsLayout(MarkOnlyThis); |
1467 } else { | 1450 } else { |
1468 // To avoid double applying margin changes in updateAutoMarginsInCro ssAxis, we reset the margins here. | 1451 // To avoid double applying margin changes in updateAutoMarginsInCro ssAxis, we reset the margins here. |
1469 resetAutoMarginsAndLogicalTopInCrossAxis(*child); | 1452 resetAutoMarginsAndLogicalTopInCrossAxis(*child); |
1470 } | 1453 } |
1471 // We may have already forced relayout for orthogonal flowing children i n computeInnerFlexBaseSizeForChild. | 1454 // We may have already forced relayout for orthogonal flowing children i n computeInnerFlexBaseSizeForChild. |
1472 bool forceChildRelayout = relayoutChildren && !childFlexBaseSizeRequires Layout(*child); | 1455 bool forceChildRelayout = relayoutChildren && !childFlexBaseSizeRequires Layout(*child); |
1456 if (child->isLayoutBlock() && toLayoutBlock(*child).hasPercentHeightDesc endants() && m_relaidOutChildren.contains(child)) { | |
1457 // Have to force another relayout even though the child is sized cor rectly, because | |
1458 // its descendants are not sized correctly yet. Our previous layout of the child was | |
1459 // done without an override height set. So, redo it here. | |
1460 forceChildRelayout = true; | |
1461 } | |
1473 updateBlockChildDirtyBitsBeforeLayout(forceChildRelayout, *child); | 1462 updateBlockChildDirtyBitsBeforeLayout(forceChildRelayout, *child); |
1474 if (!child->needsLayout()) | 1463 if (!child->needsLayout()) |
1475 child->markForPaginationRelayoutIfNeeded(layoutScope); | 1464 child->markForPaginationRelayoutIfNeeded(layoutScope); |
1465 if (child->needsLayout()) | |
1466 m_relaidOutChildren.add(child); | |
1476 child->layoutIfNeeded(); | 1467 child->layoutIfNeeded(); |
1477 | 1468 |
1478 updateAutoMarginsInMainAxis(*child, autoMarginOffset); | 1469 updateAutoMarginsInMainAxis(*child, autoMarginOffset); |
1479 | 1470 |
1480 LayoutUnit childCrossAxisMarginBoxExtent; | 1471 LayoutUnit childCrossAxisMarginBoxExtent; |
1481 if (alignmentForChild(*child) == ItemPositionBaseline && !hasAutoMargins InCrossAxis(*child)) { | 1472 if (alignmentForChild(*child) == ItemPositionBaseline && !hasAutoMargins InCrossAxis(*child)) { |
1482 LayoutUnit ascent = marginBoxAscentForChild(*child); | 1473 LayoutUnit ascent = marginBoxAscentForChild(*child); |
1483 LayoutUnit descent = (crossAxisMarginExtentForChild(*child) + crossA xisExtentForChild(*child)) - ascent; | 1474 LayoutUnit descent = (crossAxisMarginExtentForChild(*child) + crossA xisExtentForChild(*child)) - ascent; |
1484 | 1475 |
1485 maxAscent = std::max(maxAscent, ascent); | 1476 maxAscent = std::max(maxAscent, ascent); |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1723 void LayoutFlexibleBox::applyStretchAlignmentToChild(LayoutBox& child, LayoutUni t lineCrossAxisExtent) | 1714 void LayoutFlexibleBox::applyStretchAlignmentToChild(LayoutBox& child, LayoutUni t lineCrossAxisExtent) |
1724 { | 1715 { |
1725 if (!hasOrthogonalFlow(child) && child.style()->logicalHeight().isAuto()) { | 1716 if (!hasOrthogonalFlow(child) && child.style()->logicalHeight().isAuto()) { |
1726 LayoutUnit heightBeforeStretching = needToStretchChildLogicalHeight(chil d) ? constrainedChildIntrinsicContentLogicalHeight(child) : child.logicalHeight( ); | 1717 LayoutUnit heightBeforeStretching = needToStretchChildLogicalHeight(chil d) ? constrainedChildIntrinsicContentLogicalHeight(child) : child.logicalHeight( ); |
1727 LayoutUnit stretchedLogicalHeight = std::max(child.borderAndPaddingLogic alHeight(), heightBeforeStretching + availableAlignmentSpaceForChildBeforeStretc hing(lineCrossAxisExtent, child)); | 1718 LayoutUnit stretchedLogicalHeight = std::max(child.borderAndPaddingLogic alHeight(), heightBeforeStretching + availableAlignmentSpaceForChildBeforeStretc hing(lineCrossAxisExtent, child)); |
1728 ASSERT(!child.needsLayout()); | 1719 ASSERT(!child.needsLayout()); |
1729 LayoutUnit desiredLogicalHeight = child.constrainLogicalHeightByMinMax(s tretchedLogicalHeight, heightBeforeStretching - child.borderAndPaddingLogicalHei ght()); | 1720 LayoutUnit desiredLogicalHeight = child.constrainLogicalHeightByMinMax(s tretchedLogicalHeight, heightBeforeStretching - child.borderAndPaddingLogicalHei ght()); |
1730 | 1721 |
1731 // FIXME: Can avoid laying out here in some cases. See https://webkit.or g/b/87905. | 1722 // FIXME: Can avoid laying out here in some cases. See https://webkit.or g/b/87905. |
1732 bool childNeedsRelayout = desiredLogicalHeight != child.logicalHeight(); | 1723 bool childNeedsRelayout = desiredLogicalHeight != child.logicalHeight(); |
1724 if (child.isLayoutBlock() && toLayoutBlock(child).hasPercentHeightDescen dants() && m_relaidOutChildren.contains(&child)) { | |
1725 // Have to force another relayout even though the child is sized cor rectly, because | |
1726 // its descendants are not sized correctly yet. Our previous layout of the child was | |
1727 // done without an override height set. So, redo it here. | |
1728 childNeedsRelayout = true; | |
1729 } | |
1733 if (childNeedsRelayout || !child.hasOverrideLogicalContentHeight()) | 1730 if (childNeedsRelayout || !child.hasOverrideLogicalContentHeight()) |
1734 child.setOverrideLogicalContentHeight(desiredLogicalHeight - child.b orderAndPaddingLogicalHeight()); | 1731 child.setOverrideLogicalContentHeight(desiredLogicalHeight - child.b orderAndPaddingLogicalHeight()); |
1735 if (childNeedsRelayout) { | 1732 if (childNeedsRelayout) { |
1736 child.setLogicalHeight(LayoutUnit()); | 1733 child.setLogicalHeight(LayoutUnit()); |
1737 // We cache the child's intrinsic content logical height to avoid it being reset to the stretched height. | 1734 // We cache the child's intrinsic content logical height to avoid it being reset to the stretched height. |
1738 // FIXME: This is fragile. LayoutBoxes should be smart enough to det ermine their intrinsic content logical | 1735 // FIXME: This is fragile. LayoutBoxes should be smart enough to det ermine their intrinsic content logical |
1739 // height correctly even when there's an overrideHeight. | 1736 // height correctly even when there's an overrideHeight. |
1740 LayoutUnit childIntrinsicContentLogicalHeight = child.intrinsicConte ntLogicalHeight(); | 1737 LayoutUnit childIntrinsicContentLogicalHeight = child.intrinsicConte ntLogicalHeight(); |
1741 child.forceChildLayout(); | 1738 child.forceChildLayout(); |
1742 child.setIntrinsicContentLogicalHeight(childIntrinsicContentLogicalH eight); | 1739 child.setIntrinsicContentLogicalHeight(childIntrinsicContentLogicalH eight); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1778 ASSERT(child); | 1775 ASSERT(child); |
1779 LayoutUnit lineCrossAxisExtent = lineContexts[lineNumber].crossAxisE xtent; | 1776 LayoutUnit lineCrossAxisExtent = lineContexts[lineNumber].crossAxisE xtent; |
1780 LayoutUnit originalOffset = lineContexts[lineNumber].crossAxisOffset - crossAxisStartEdge; | 1777 LayoutUnit originalOffset = lineContexts[lineNumber].crossAxisOffset - crossAxisStartEdge; |
1781 LayoutUnit newOffset = contentExtent - originalOffset - lineCrossAxi sExtent; | 1778 LayoutUnit newOffset = contentExtent - originalOffset - lineCrossAxi sExtent; |
1782 adjustAlignmentForChild(*child, newOffset - originalOffset); | 1779 adjustAlignmentForChild(*child, newOffset - originalOffset); |
1783 } | 1780 } |
1784 } | 1781 } |
1785 } | 1782 } |
1786 | 1783 |
1787 } // namespace blink | 1784 } // namespace blink |
OLD | NEW |