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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 | 113 |
114 LayoutFlexibleBox* LayoutFlexibleBox::createAnonymous(Document* document) { | 114 LayoutFlexibleBox* LayoutFlexibleBox::createAnonymous(Document* document) { |
115 LayoutFlexibleBox* layoutObject = new LayoutFlexibleBox(nullptr); | 115 LayoutFlexibleBox* layoutObject = new LayoutFlexibleBox(nullptr); |
116 layoutObject->setDocumentForAnonymous(document); | 116 layoutObject->setDocumentForAnonymous(document); |
117 return layoutObject; | 117 return layoutObject; |
118 } | 118 } |
119 | 119 |
120 void LayoutFlexibleBox::computeIntrinsicLogicalWidths( | 120 void LayoutFlexibleBox::computeIntrinsicLogicalWidths( |
121 LayoutUnit& minLogicalWidth, | 121 LayoutUnit& minLogicalWidth, |
122 LayoutUnit& maxLogicalWidth) const { | 122 LayoutUnit& maxLogicalWidth) const { |
123 // FIXME: We're ignoring flex-basis here and we shouldn't. We can't start hono
ring it though until | 123 // FIXME: We're ignoring flex-basis here and we shouldn't. We can't start |
124 // the flex shorthand stops setting it to 0. | 124 // honoring it though until the flex shorthand stops setting it to 0. See |
125 // See https://bugs.webkit.org/show_bug.cgi?id=116117 and http://crbug.com/240
765. | 125 // https://bugs.webkit.org/show_bug.cgi?id=116117 and |
| 126 // https://crbug.com/240765. |
126 float previousMaxContentFlexFraction = -1; | 127 float previousMaxContentFlexFraction = -1; |
127 for (LayoutBox* child = firstChildBox(); child; | 128 for (LayoutBox* child = firstChildBox(); child; |
128 child = child->nextSiblingBox()) { | 129 child = child->nextSiblingBox()) { |
129 if (child->isOutOfFlowPositioned()) | 130 if (child->isOutOfFlowPositioned()) |
130 continue; | 131 continue; |
131 | 132 |
132 LayoutUnit margin = marginIntrinsicLogicalWidthForChild(*child); | 133 LayoutUnit margin = marginIntrinsicLogicalWidthForChild(*child); |
133 | 134 |
134 LayoutUnit minPreferredLogicalWidth; | 135 LayoutUnit minPreferredLogicalWidth; |
135 LayoutUnit maxPreferredLogicalWidth; | 136 LayoutUnit maxPreferredLogicalWidth; |
136 computeChildPreferredLogicalWidths(*child, minPreferredLogicalWidth, | 137 computeChildPreferredLogicalWidths(*child, minPreferredLogicalWidth, |
137 maxPreferredLogicalWidth); | 138 maxPreferredLogicalWidth); |
138 DCHECK_GE(minPreferredLogicalWidth, LayoutUnit()); | 139 DCHECK_GE(minPreferredLogicalWidth, LayoutUnit()); |
139 DCHECK_GE(maxPreferredLogicalWidth, LayoutUnit()); | 140 DCHECK_GE(maxPreferredLogicalWidth, LayoutUnit()); |
140 minPreferredLogicalWidth += margin; | 141 minPreferredLogicalWidth += margin; |
141 maxPreferredLogicalWidth += margin; | 142 maxPreferredLogicalWidth += margin; |
142 if (!isColumnFlow()) { | 143 if (!isColumnFlow()) { |
143 maxLogicalWidth += maxPreferredLogicalWidth; | 144 maxLogicalWidth += maxPreferredLogicalWidth; |
144 if (isMultiline()) { | 145 if (isMultiline()) { |
145 // For multiline, the min preferred width is if you put a break between
each item. | 146 // For multiline, the min preferred width is if you put a break between |
| 147 // each item. |
146 minLogicalWidth = std::max(minLogicalWidth, minPreferredLogicalWidth); | 148 minLogicalWidth = std::max(minLogicalWidth, minPreferredLogicalWidth); |
147 } else { | 149 } else { |
148 minLogicalWidth += minPreferredLogicalWidth; | 150 minLogicalWidth += minPreferredLogicalWidth; |
149 } | 151 } |
150 } else { | 152 } else { |
151 minLogicalWidth = std::max(minPreferredLogicalWidth, minLogicalWidth); | 153 minLogicalWidth = std::max(minPreferredLogicalWidth, minLogicalWidth); |
152 maxLogicalWidth = std::max(maxPreferredLogicalWidth, maxLogicalWidth); | 154 maxLogicalWidth = std::max(maxPreferredLogicalWidth, maxLogicalWidth); |
153 } | 155 } |
154 | 156 |
155 previousMaxContentFlexFraction = countIntrinsicSizeForAlgorithmChange( | 157 previousMaxContentFlexFraction = countIntrinsicSizeForAlgorithmChange( |
156 maxPreferredLogicalWidth, child, previousMaxContentFlexFraction); | 158 maxPreferredLogicalWidth, child, previousMaxContentFlexFraction); |
157 } | 159 } |
158 | 160 |
159 maxLogicalWidth = std::max(minLogicalWidth, maxLogicalWidth); | 161 maxLogicalWidth = std::max(minLogicalWidth, maxLogicalWidth); |
160 | 162 |
161 // Due to negative margins, it is possible that we calculated a negative intri
nsic width. Make sure that we | 163 // Due to negative margins, it is possible that we calculated a negative |
162 // never return a negative width. | 164 // intrinsic width. Make sure that we never return a negative width. |
163 minLogicalWidth = std::max(LayoutUnit(), minLogicalWidth); | 165 minLogicalWidth = std::max(LayoutUnit(), minLogicalWidth); |
164 maxLogicalWidth = std::max(LayoutUnit(), maxLogicalWidth); | 166 maxLogicalWidth = std::max(LayoutUnit(), maxLogicalWidth); |
165 | 167 |
166 LayoutUnit scrollbarWidth(scrollbarLogicalWidth()); | 168 LayoutUnit scrollbarWidth(scrollbarLogicalWidth()); |
167 maxLogicalWidth += scrollbarWidth; | 169 maxLogicalWidth += scrollbarWidth; |
168 minLogicalWidth += scrollbarWidth; | 170 minLogicalWidth += scrollbarWidth; |
169 } | 171 } |
170 | 172 |
171 float LayoutFlexibleBox::countIntrinsicSizeForAlgorithmChange( | 173 float LayoutFlexibleBox::countIntrinsicSizeForAlgorithmChange( |
172 LayoutUnit maxPreferredLogicalWidth, | 174 LayoutUnit maxPreferredLogicalWidth, |
173 LayoutBox* child, | 175 LayoutBox* child, |
174 float previousMaxContentFlexFraction) const { | 176 float previousMaxContentFlexFraction) const { |
175 // Determine whether the new version of the intrinsic size algorithm of the fl
exbox | 177 // Determine whether the new version of the intrinsic size algorithm of the |
176 // spec would produce a different result than our above algorithm. | 178 // flexbox spec would produce a different result than our above algorithm. |
177 // The algorithm produces a different result iff the max-content flex fraction | 179 // The algorithm produces a different result iff the max-content flex |
178 // (as defined in the new algorithm) is not identical for each flex item. | 180 // fraction (as defined in the new algorithm) is not identical for each flex |
| 181 // item. |
179 if (isColumnFlow()) | 182 if (isColumnFlow()) |
180 return previousMaxContentFlexFraction; | 183 return previousMaxContentFlexFraction; |
181 Length flexBasis = child->styleRef().flexBasis(); | 184 Length flexBasis = child->styleRef().flexBasis(); |
182 float flexGrow = child->styleRef().flexGrow(); | 185 float flexGrow = child->styleRef().flexGrow(); |
183 // A flex-basis of auto will lead to a max-content flex fraction of zero, so j
ust like | 186 // A flex-basis of auto will lead to a max-content flex fraction of zero, so |
184 // an inflexible item it would compute to a size of max-content, so we ignore
it here. | 187 // just like an inflexible item it would compute to a size of max-content, so |
| 188 // we ignore it here. |
185 if (flexBasis.isAuto() || flexGrow == 0) | 189 if (flexBasis.isAuto() || flexGrow == 0) |
186 return previousMaxContentFlexFraction; | 190 return previousMaxContentFlexFraction; |
187 flexGrow = std::max(1.0f, flexGrow); | 191 flexGrow = std::max(1.0f, flexGrow); |
188 float maxContentFlexFraction = maxPreferredLogicalWidth.toFloat() / flexGrow; | 192 float maxContentFlexFraction = maxPreferredLogicalWidth.toFloat() / flexGrow; |
189 if (previousMaxContentFlexFraction != -1 && | 193 if (previousMaxContentFlexFraction != -1 && |
190 maxContentFlexFraction != previousMaxContentFlexFraction) | 194 maxContentFlexFraction != previousMaxContentFlexFraction) |
191 UseCounter::count(document(), | 195 UseCounter::count(document(), |
192 UseCounter::FlexboxIntrinsicSizeAlgorithmIsDifferent); | 196 UseCounter::FlexboxIntrinsicSizeAlgorithmIsDifferent); |
193 return maxContentFlexFraction; | 197 return maxContentFlexFraction; |
194 } | 198 } |
(...skipping 16 matching lines...) Expand all Loading... |
211 LinePositionMode mode) const { | 215 LinePositionMode mode) const { |
212 DCHECK_EQ(mode, PositionOnContainingLine); | 216 DCHECK_EQ(mode, PositionOnContainingLine); |
213 int baseline = firstLineBoxBaseline(); | 217 int baseline = firstLineBoxBaseline(); |
214 if (baseline == -1) | 218 if (baseline == -1) |
215 baseline = synthesizedBaselineFromContentBox(*this, direction); | 219 baseline = synthesizedBaselineFromContentBox(*this, direction); |
216 | 220 |
217 return beforeMarginInLineDirection(direction) + baseline; | 221 return beforeMarginInLineDirection(direction) + baseline; |
218 } | 222 } |
219 | 223 |
220 static const StyleContentAlignmentData& contentAlignmentNormalBehavior() { | 224 static const StyleContentAlignmentData& contentAlignmentNormalBehavior() { |
221 // The justify-content property applies along the main axis, but since flexing | 225 // The justify-content property applies along the main axis, but since |
222 // in the main axis is controlled by flex, stretch behaves as flex-start (igno
ring | 226 // flexing in the main axis is controlled by flex, stretch behaves as |
223 // the specified fallback alignment, if any). | 227 // flex-start (ignoring the specified fallback alignment, if any). |
224 // https://drafts.csswg.org/css-align/#distribution-flex | 228 // https://drafts.csswg.org/css-align/#distribution-flex |
225 static const StyleContentAlignmentData normalBehavior = { | 229 static const StyleContentAlignmentData normalBehavior = { |
226 ContentPositionNormal, ContentDistributionStretch}; | 230 ContentPositionNormal, ContentDistributionStretch}; |
227 return normalBehavior; | 231 return normalBehavior; |
228 } | 232 } |
229 | 233 |
230 int LayoutFlexibleBox::firstLineBoxBaseline() const { | 234 int LayoutFlexibleBox::firstLineBoxBaseline() const { |
231 if (isWritingModeRoot() || m_numberOfInFlowChildrenOnFirstLine <= 0) | 235 if (isWritingModeRoot() || m_numberOfInFlowChildrenOnFirstLine <= 0) |
232 return -1; | 236 return -1; |
233 LayoutBox* baselineChild = nullptr; | 237 LayoutBox* baselineChild = nullptr; |
(...skipping 22 matching lines...) Expand all Loading... |
256 return (crossAxisExtentForChild(*baselineChild) + | 260 return (crossAxisExtentForChild(*baselineChild) + |
257 baselineChild->logicalTop()) | 261 baselineChild->logicalTop()) |
258 .toInt(); | 262 .toInt(); |
259 if (isColumnFlow() && !hasOrthogonalFlow(*baselineChild)) | 263 if (isColumnFlow() && !hasOrthogonalFlow(*baselineChild)) |
260 return (mainAxisExtentForChild(*baselineChild) + | 264 return (mainAxisExtentForChild(*baselineChild) + |
261 baselineChild->logicalTop()) | 265 baselineChild->logicalTop()) |
262 .toInt(); | 266 .toInt(); |
263 | 267 |
264 int baseline = baselineChild->firstLineBoxBaseline(); | 268 int baseline = baselineChild->firstLineBoxBaseline(); |
265 if (baseline == -1) { | 269 if (baseline == -1) { |
266 // FIXME: We should pass |direction| into firstLineBoxBaseline and stop bail
ing out if we're a writing mode root. | 270 // FIXME: We should pass |direction| into firstLineBoxBaseline and stop |
267 // This would also fix some cases where the flexbox is orthogonal to its con
tainer. | 271 // bailing out if we're a writing mode root. This would also fix some |
| 272 // cases where the flexbox is orthogonal to its container. |
268 LineDirectionMode direction = | 273 LineDirectionMode direction = |
269 isHorizontalWritingMode() ? HorizontalLine : VerticalLine; | 274 isHorizontalWritingMode() ? HorizontalLine : VerticalLine; |
270 return (synthesizedBaselineFromContentBox(*baselineChild, direction) + | 275 return (synthesizedBaselineFromContentBox(*baselineChild, direction) + |
271 baselineChild->logicalTop()) | 276 baselineChild->logicalTop()) |
272 .toInt(); | 277 .toInt(); |
273 } | 278 } |
274 | 279 |
275 return (baseline + baselineChild->logicalTop()).toInt(); | 280 return (baseline + baselineChild->logicalTop()).toInt(); |
276 } | 281 } |
277 | 282 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
340 return flexDirection == | 345 return flexDirection == |
341 (style()->isLeftToRightDirection() ? FlowRowReverse : FlowRow); | 346 (style()->isLeftToRightDirection() ? FlowRowReverse : FlowRow); |
342 return flexDirection == FlowColumnReverse; | 347 return flexDirection == FlowColumnReverse; |
343 } | 348 } |
344 | 349 |
345 void LayoutFlexibleBox::removeChild(LayoutObject* child) { | 350 void LayoutFlexibleBox::removeChild(LayoutObject* child) { |
346 LayoutBlock::removeChild(child); | 351 LayoutBlock::removeChild(child); |
347 m_intrinsicSizeAlongMainAxis.remove(child); | 352 m_intrinsicSizeAlongMainAxis.remove(child); |
348 } | 353 } |
349 | 354 |
350 // TODO (lajava): Is this function still needed ? Every time the flex container'
s align-items value changes we | 355 // TODO (lajava): Is this function still needed ? Every time the flex |
351 // propagate the diff to its children (see ComputedStyle::stylePropagationDiff). | 356 // container's align-items value changes we propagate the diff to its children |
| 357 // (see ComputedStyle::stylePropagationDiff). |
352 void LayoutFlexibleBox::styleDidChange(StyleDifference diff, | 358 void LayoutFlexibleBox::styleDidChange(StyleDifference diff, |
353 const ComputedStyle* oldStyle) { | 359 const ComputedStyle* oldStyle) { |
354 LayoutBlock::styleDidChange(diff, oldStyle); | 360 LayoutBlock::styleDidChange(diff, oldStyle); |
355 | 361 |
356 if (oldStyle && oldStyle->alignItemsPosition() == ItemPositionStretch && | 362 if (oldStyle && oldStyle->alignItemsPosition() == ItemPositionStretch && |
357 diff.needsFullLayout()) { | 363 diff.needsFullLayout()) { |
358 // Flex items that were previously stretching need to be relayed out so we c
an compute new available cross axis space. | 364 // Flex items that were previously stretching need to be relayed out so we |
359 // This is only necessary for stretching since other alignment values don't
change the size of the box. | 365 // can compute new available cross axis space. This is only necessary for |
| 366 // stretching since other alignment values don't change the size of the |
| 367 // box. |
360 for (LayoutBox* child = firstChildBox(); child; | 368 for (LayoutBox* child = firstChildBox(); child; |
361 child = child->nextSiblingBox()) { | 369 child = child->nextSiblingBox()) { |
362 ItemPosition previousAlignment = | 370 ItemPosition previousAlignment = |
363 child->styleRef() | 371 child->styleRef() |
364 .resolvedAlignSelf(selfAlignmentNormalBehavior(), oldStyle) | 372 .resolvedAlignSelf(selfAlignmentNormalBehavior(), oldStyle) |
365 .position(); | 373 .position(); |
366 if (previousAlignment == ItemPositionStretch && | 374 if (previousAlignment == ItemPositionStretch && |
367 previousAlignment != | 375 previousAlignment != |
368 child->styleRef() | 376 child->styleRef() |
369 .resolvedAlignSelf(selfAlignmentNormalBehavior(), style()) | 377 .resolvedAlignSelf(selfAlignmentNormalBehavior(), style()) |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 prepareOrderIteratorAndMargins(); | 412 prepareOrderIteratorAndMargins(); |
405 layoutFlexItems(true, layoutScope); | 413 layoutFlexItems(true, layoutScope); |
406 PaintLayerScrollableArea::PreventRelayoutScope::resetRelayoutNeeded(); | 414 PaintLayerScrollableArea::PreventRelayoutScope::resetRelayoutNeeded(); |
407 } | 415 } |
408 | 416 |
409 if (logicalHeight() != previousHeight) | 417 if (logicalHeight() != previousHeight) |
410 relayoutChildren = true; | 418 relayoutChildren = true; |
411 | 419 |
412 layoutPositionedObjects(relayoutChildren || isDocumentElement()); | 420 layoutPositionedObjects(relayoutChildren || isDocumentElement()); |
413 | 421 |
414 // FIXME: css3/flexbox/repaint-rtl-column.html seems to issue paint invalida
tions for more overflow than it needs to. | 422 // FIXME: css3/flexbox/repaint-rtl-column.html seems to issue paint |
| 423 // invalidations for more overflow than it needs to. |
415 computeOverflow(clientLogicalBottomAfterRepositioning()); | 424 computeOverflow(clientLogicalBottomAfterRepositioning()); |
416 } | 425 } |
417 | 426 |
418 updateLayerTransformAfterLayout(); | 427 updateLayerTransformAfterLayout(); |
419 | 428 |
420 // Update our scroll information if we're overflow:auto/scroll/hidden now that
we know if | 429 // Update our scroll information if we're overflow:auto/scroll/hidden now |
421 // we overflow or not. | 430 // that we know if we overflow or not. |
422 updateAfterLayout(); | 431 updateAfterLayout(); |
423 | 432 |
424 clearNeedsLayout(); | 433 clearNeedsLayout(); |
425 | 434 |
426 // We have to reset this, because changes to our ancestors' style | 435 // We have to reset this, because changes to our ancestors' style can affect |
427 // can affect this value. | 436 // this value. |
428 m_hasDefiniteHeight = SizeDefiniteness::Unknown; | 437 m_hasDefiniteHeight = SizeDefiniteness::Unknown; |
429 } | 438 } |
430 | 439 |
431 void LayoutFlexibleBox::paintChildren(const PaintInfo& paintInfo, | 440 void LayoutFlexibleBox::paintChildren(const PaintInfo& paintInfo, |
432 const LayoutPoint& paintOffset) const { | 441 const LayoutPoint& paintOffset) const { |
433 BlockPainter::paintChildrenOfFlexibleBox(*this, paintInfo, paintOffset); | 442 BlockPainter::paintChildrenOfFlexibleBox(*this, paintInfo, paintOffset); |
434 } | 443 } |
435 | 444 |
436 void LayoutFlexibleBox::repositionLogicalHeightDependentFlexItems( | 445 void LayoutFlexibleBox::repositionLogicalHeightDependentFlexItems( |
437 Vector<LineContext>& lineContexts, | 446 Vector<LineContext>& lineContexts, |
438 LayoutObject* childToExclude) { | 447 LayoutObject* childToExclude) { |
439 LayoutUnit crossAxisStartEdge = | 448 LayoutUnit crossAxisStartEdge = |
440 lineContexts.isEmpty() ? LayoutUnit() : lineContexts[0].crossAxisOffset; | 449 lineContexts.isEmpty() ? LayoutUnit() : lineContexts[0].crossAxisOffset; |
441 alignFlexLines(lineContexts); | 450 alignFlexLines(lineContexts); |
442 | 451 |
443 alignChildren(lineContexts, childToExclude); | 452 alignChildren(lineContexts, childToExclude); |
444 | 453 |
445 if (style()->flexWrap() == FlexWrapReverse) | 454 if (style()->flexWrap() == FlexWrapReverse) |
446 flipForWrapReverse(lineContexts, crossAxisStartEdge); | 455 flipForWrapReverse(lineContexts, crossAxisStartEdge); |
447 | 456 |
448 // direction:rtl + flex-direction:column means the cross-axis direction is fli
pped. | 457 // direction:rtl + flex-direction:column means the cross-axis direction is |
| 458 // flipped. |
449 flipForRightToLeftColumn(); | 459 flipForRightToLeftColumn(); |
450 } | 460 } |
451 | 461 |
452 DISABLE_CFI_PERF | 462 DISABLE_CFI_PERF |
453 LayoutUnit LayoutFlexibleBox::clientLogicalBottomAfterRepositioning() { | 463 LayoutUnit LayoutFlexibleBox::clientLogicalBottomAfterRepositioning() { |
454 LayoutUnit maxChildLogicalBottom; | 464 LayoutUnit maxChildLogicalBottom; |
455 for (LayoutBox* child = firstChildBox(); child; | 465 for (LayoutBox* child = firstChildBox(); child; |
456 child = child->nextSiblingBox()) { | 466 child = child->nextSiblingBox()) { |
457 if (child->isOutOfFlowPositioned()) | 467 if (child->isOutOfFlowPositioned()) |
458 continue; | 468 continue; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
527 child, childIntrinsicContentLogicalHeight); | 537 child, childIntrinsicContentLogicalHeight); |
528 } | 538 } |
529 return child.logicalHeight(); | 539 return child.logicalHeight(); |
530 } | 540 } |
531 | 541 |
532 DISABLE_CFI_PERF | 542 DISABLE_CFI_PERF |
533 LayoutUnit LayoutFlexibleBox::childIntrinsicLogicalWidth( | 543 LayoutUnit LayoutFlexibleBox::childIntrinsicLogicalWidth( |
534 const LayoutBox& child) const { | 544 const LayoutBox& child) const { |
535 // This should only be called if the logical width is the cross size | 545 // This should only be called if the logical width is the cross size |
536 DCHECK(hasOrthogonalFlow(child)); | 546 DCHECK(hasOrthogonalFlow(child)); |
537 // If our height is auto, make sure that our returned height is unaffected by
earlier layouts by | 547 // If our height is auto, make sure that our returned height is unaffected by |
538 // returning the max preferred logical width | 548 // earlier layouts by returning the max preferred logical width |
539 if (!crossAxisLengthIsDefinite(child, child.styleRef().logicalWidth())) | 549 if (!crossAxisLengthIsDefinite(child, child.styleRef().logicalWidth())) |
540 return child.maxPreferredLogicalWidth(); | 550 return child.maxPreferredLogicalWidth(); |
541 | 551 |
542 return child.logicalWidth(); | 552 return child.logicalWidth(); |
543 } | 553 } |
544 | 554 |
545 LayoutUnit LayoutFlexibleBox::crossAxisIntrinsicExtentForChild( | 555 LayoutUnit LayoutFlexibleBox::crossAxisIntrinsicExtentForChild( |
546 const LayoutBox& child) const { | 556 const LayoutBox& child) const { |
547 return hasOrthogonalFlow(child) ? childIntrinsicLogicalWidth(child) | 557 return hasOrthogonalFlow(child) ? childIntrinsicLogicalWidth(child) |
548 : childIntrinsicLogicalHeight(child); | 558 : childIntrinsicLogicalHeight(child); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
587 computedValues.m_extent - borderPaddingAndScrollbar); | 597 computedValues.m_extent - borderPaddingAndScrollbar); |
588 } | 598 } |
589 return contentLogicalWidth(); | 599 return contentLogicalWidth(); |
590 } | 600 } |
591 | 601 |
592 LayoutUnit LayoutFlexibleBox::computeMainAxisExtentForChild( | 602 LayoutUnit LayoutFlexibleBox::computeMainAxisExtentForChild( |
593 const LayoutBox& child, | 603 const LayoutBox& child, |
594 SizeType sizeType, | 604 SizeType sizeType, |
595 const Length& size) { | 605 const Length& size) { |
596 // If we have a horizontal flow, that means the main size is the width. | 606 // If we have a horizontal flow, that means the main size is the width. |
597 // That's the logical width for horizontal writing modes, and the logical heig
ht in vertical writing modes. | 607 // That's the logical width for horizontal writing modes, and the logical |
598 // For a vertical flow, main size is the height, so it's the inverse. | 608 // height in vertical writing modes. For a vertical flow, main size is the |
599 // So we need the logical width if we have a horizontal flow and horizontal wr
iting mode, or vertical flow and vertical writing mode. | 609 // height, so it's the inverse. So we need the logical width if we have a |
600 // Otherwise we need the logical height. | 610 // horizontal flow and horizontal writing mode, or vertical flow and vertical |
| 611 // writing mode. Otherwise we need the logical height. |
601 if (isHorizontalFlow() != child.styleRef().isHorizontalWritingMode()) { | 612 if (isHorizontalFlow() != child.styleRef().isHorizontalWritingMode()) { |
602 // We don't have to check for "auto" here - computeContentLogicalHeight will
just return -1 for that case anyway. | 613 // We don't have to check for "auto" here - computeContentLogicalHeight |
603 // It's safe to access scrollbarLogicalHeight here because computeNextFlexLi
ne will have already | 614 // will just return -1 for that case anyway. It's safe to access |
604 // forced layout on the child. | 615 // scrollbarLogicalHeight here because computeNextFlexLine will have |
605 // We previously layed out the child if necessary (see computeNextFlexLine a
nd the call to childHasIntrinsicMainAxisSize) | 616 // already forced layout on the child. We previously layed out the child |
606 // so we can be sure that the two height calls here will return up-to-date d
ata. | 617 // if necessary (see computeNextFlexLine and the call to |
| 618 // childHasIntrinsicMainAxisSize) so we can be sure that the two height |
| 619 // calls here will return up-to-date data. |
607 return child.computeContentLogicalHeight( | 620 return child.computeContentLogicalHeight( |
608 sizeType, size, child.intrinsicContentLogicalHeight()) + | 621 sizeType, size, child.intrinsicContentLogicalHeight()) + |
609 child.scrollbarLogicalHeight(); | 622 child.scrollbarLogicalHeight(); |
610 } | 623 } |
611 // computeLogicalWidth always re-computes the intrinsic widths. However, when
our logical width is auto, | 624 // computeLogicalWidth always re-computes the intrinsic widths. However, when |
612 // we can just use our cached value. So let's do that here. (Compare code in L
ayoutBlock::computePreferredLogicalWidths) | 625 // our logical width is auto, we can just use our cached value. So let's do |
| 626 // that here. (Compare code in LayoutBlock::computePreferredLogicalWidths) |
613 LayoutUnit borderAndPadding = child.borderAndPaddingLogicalWidth(); | 627 LayoutUnit borderAndPadding = child.borderAndPaddingLogicalWidth(); |
614 if (child.styleRef().logicalWidth().isAuto() && !hasAspectRatio(child)) { | 628 if (child.styleRef().logicalWidth().isAuto() && !hasAspectRatio(child)) { |
615 if (size.type() == MinContent) | 629 if (size.type() == MinContent) |
616 return child.minPreferredLogicalWidth() - borderAndPadding; | 630 return child.minPreferredLogicalWidth() - borderAndPadding; |
617 if (size.type() == MaxContent) | 631 if (size.type() == MaxContent) |
618 return child.maxPreferredLogicalWidth() - borderAndPadding; | 632 return child.maxPreferredLogicalWidth() - borderAndPadding; |
619 } | 633 } |
620 return child.computeLogicalWidthUsing(sizeType, size, contentLogicalWidth(), | 634 return child.computeLogicalWidthUsing(sizeType, size, contentLogicalWidth(), |
621 this) - | 635 this) - |
622 borderAndPadding; | 636 borderAndPadding; |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
869 if (hasOrthogonalFlow(child) || | 883 if (hasOrthogonalFlow(child) || |
870 m_hasDefiniteHeight == SizeDefiniteness::Definite) | 884 m_hasDefiniteHeight == SizeDefiniteness::Definite) |
871 return true; | 885 return true; |
872 if (m_hasDefiniteHeight == SizeDefiniteness::Indefinite) | 886 if (m_hasDefiniteHeight == SizeDefiniteness::Indefinite) |
873 return false; | 887 return false; |
874 bool definite = child.computePercentageLogicalHeight(length) != -1; | 888 bool definite = child.computePercentageLogicalHeight(length) != -1; |
875 m_hasDefiniteHeight = | 889 m_hasDefiniteHeight = |
876 definite ? SizeDefiniteness::Definite : SizeDefiniteness::Indefinite; | 890 definite ? SizeDefiniteness::Definite : SizeDefiniteness::Indefinite; |
877 return definite; | 891 return definite; |
878 } | 892 } |
879 // TODO(cbiesinger): Eventually we should support other types of sizes here. R
equires updating | 893 // TODO(cbiesinger): Eventually we should support other types of sizes here. |
880 // computeMainSizeFromAspectRatioUsing. | 894 // Requires updating computeMainSizeFromAspectRatioUsing. |
881 return length.isFixed(); | 895 return length.isFixed(); |
882 } | 896 } |
883 | 897 |
884 bool LayoutFlexibleBox::childFlexBaseSizeRequiresLayout( | 898 bool LayoutFlexibleBox::childFlexBaseSizeRequiresLayout( |
885 const LayoutBox& child) const { | 899 const LayoutBox& child) const { |
886 return (!mainAxisLengthIsDefinite(child, flexBasisForChild(child)) && | 900 return (!mainAxisLengthIsDefinite(child, flexBasisForChild(child)) && |
887 (hasOrthogonalFlow(child) || | 901 (hasOrthogonalFlow(child) || |
888 (crossAxisOverflowForChild(child) == OverflowAuto && | 902 (crossAxisOverflowForChild(child) == OverflowAuto && |
889 !PaintLayerScrollableArea::FreezeScrollbarsScope:: | 903 !PaintLayerScrollableArea::FreezeScrollbarsScope:: |
890 scrollbarsAreFrozen()))); | 904 scrollbarsAreFrozen()))); |
891 } | 905 } |
892 | 906 |
893 void LayoutFlexibleBox::cacheChildMainSize(const LayoutBox& child) { | 907 void LayoutFlexibleBox::cacheChildMainSize(const LayoutBox& child) { |
894 DCHECK(!child.needsLayout()); | 908 DCHECK(!child.needsLayout()); |
895 LayoutUnit mainSize; | 909 LayoutUnit mainSize; |
896 if (hasOrthogonalFlow(child)) { | 910 if (hasOrthogonalFlow(child)) { |
897 mainSize = child.logicalHeight(); | 911 mainSize = child.logicalHeight(); |
898 } else { | 912 } else { |
899 // The max preferred logical width includes the intrinsic scrollbar logical
width, which is only set for | 913 // The max preferred logical width includes the intrinsic scrollbar logical |
900 // overflow: scroll. To handle overflow: auto, we have to take scrollbarLogi
calWidth() into account, and then | 914 // width, which is only set for overflow: scroll. To handle overflow: auto, |
901 // subtract the intrinsic width again so as to not double-count overflow: sc
roll scrollbars. | 915 // we have to take scrollbarLogicalWidth() into account, and then subtract |
| 916 // the intrinsic width again so as to not double-count overflow: scroll |
| 917 // scrollbars. |
902 mainSize = child.maxPreferredLogicalWidth() + | 918 mainSize = child.maxPreferredLogicalWidth() + |
903 child.scrollbarLogicalWidth() - child.scrollbarLogicalWidth(); | 919 child.scrollbarLogicalWidth() - child.scrollbarLogicalWidth(); |
904 } | 920 } |
905 m_intrinsicSizeAlongMainAxis.set(&child, mainSize); | 921 m_intrinsicSizeAlongMainAxis.set(&child, mainSize); |
906 m_relaidOutChildren.add(&child); | 922 m_relaidOutChildren.add(&child); |
907 } | 923 } |
908 | 924 |
909 void LayoutFlexibleBox::clearCachedMainSizeForChild(const LayoutBox& child) { | 925 void LayoutFlexibleBox::clearCachedMainSizeForChild(const LayoutBox& child) { |
910 m_intrinsicSizeAlongMainAxis.remove(&child); | 926 m_intrinsicSizeAlongMainAxis.remove(&child); |
911 } | 927 } |
(...skipping 23 matching lines...) Expand all Loading... |
935 | 951 |
936 updateBlockChildDirtyBitsBeforeLayout(childLayoutType == ForceLayout, | 952 updateBlockChildDirtyBitsBeforeLayout(childLayoutType == ForceLayout, |
937 child); | 953 child); |
938 if (child.needsLayout() || childLayoutType == ForceLayout || | 954 if (child.needsLayout() || childLayoutType == ForceLayout || |
939 !m_intrinsicSizeAlongMainAxis.contains(&child)) { | 955 !m_intrinsicSizeAlongMainAxis.contains(&child)) { |
940 child.forceChildLayout(); | 956 child.forceChildLayout(); |
941 cacheChildMainSize(child); | 957 cacheChildMainSize(child); |
942 } | 958 } |
943 mainAxisExtent = m_intrinsicSizeAlongMainAxis.get(&child); | 959 mainAxisExtent = m_intrinsicSizeAlongMainAxis.get(&child); |
944 } else { | 960 } else { |
945 // We don't need to add scrollbarLogicalWidth here. For overflow: scroll, th
e preferred width | 961 // We don't need to add scrollbarLogicalWidth here. For overflow: scroll, |
946 // already includes the scrollbar size (via scrollbarLogicalWidth()). For ov
erflow: auto, | 962 // the preferred width already includes the scrollbar size (via |
947 // childFlexBaseSizeRequiresLayout returns true and we handle that via the o
ther branch | 963 // scrollbarLogicalWidth()). For overflow: auto, |
948 // of this if. | 964 // childFlexBaseSizeRequiresLayout returns true and we handle that via the |
| 965 // other branch of this if. |
949 mainAxisExtent = child.maxPreferredLogicalWidth(); | 966 mainAxisExtent = child.maxPreferredLogicalWidth(); |
950 } | 967 } |
951 DCHECK_GE(mainAxisExtent - mainAxisBorderAndPadding, LayoutUnit()) | 968 DCHECK_GE(mainAxisExtent - mainAxisBorderAndPadding, LayoutUnit()) |
952 << mainAxisExtent << " - " << mainAxisBorderAndPadding; | 969 << mainAxisExtent << " - " << mainAxisBorderAndPadding; |
953 return mainAxisExtent - mainAxisBorderAndPadding; | 970 return mainAxisExtent - mainAxisBorderAndPadding; |
954 } | 971 } |
955 | 972 |
956 void LayoutFlexibleBox::layoutFlexItems(bool relayoutChildren, | 973 void LayoutFlexibleBox::layoutFlexItems(bool relayoutChildren, |
957 SubtreeLayoutScope& layoutScope) { | 974 SubtreeLayoutScope& layoutScope) { |
958 Vector<LineContext> lineContexts; | 975 Vector<LineContext> lineContexts; |
959 OrderedFlexItemList orderedChildren; | 976 OrderedFlexItemList orderedChildren; |
960 LayoutUnit sumFlexBaseSize; | 977 LayoutUnit sumFlexBaseSize; |
961 double totalFlexGrow; | 978 double totalFlexGrow; |
962 double totalFlexShrink; | 979 double totalFlexShrink; |
963 double totalWeightedFlexShrink; | 980 double totalWeightedFlexShrink; |
964 LayoutUnit sumHypotheticalMainSize; | 981 LayoutUnit sumHypotheticalMainSize; |
965 | 982 |
966 PaintLayerScrollableArea::PreventRelayoutScope preventRelayoutScope( | 983 PaintLayerScrollableArea::PreventRelayoutScope preventRelayoutScope( |
967 layoutScope); | 984 layoutScope); |
968 | 985 |
969 // Fieldsets need to find their legend and position it inside the border of th
e object. | 986 // Fieldsets need to find their legend and position it inside the border of |
970 // The legend then gets skipped during normal layout. | 987 // the object. The legend then gets skipped during normal layout. It |
971 // It doesn't get included in the normal layout process but is instead skipped
. | 988 // doesn't get included in the normal layout process but is instead skipped. |
972 LayoutObject* childToExclude = | 989 LayoutObject* childToExclude = |
973 layoutSpecialExcludedChild(relayoutChildren, layoutScope); | 990 layoutSpecialExcludedChild(relayoutChildren, layoutScope); |
974 | 991 |
975 m_orderIterator.first(); | 992 m_orderIterator.first(); |
976 LayoutUnit crossAxisOffset = | 993 LayoutUnit crossAxisOffset = |
977 flowAwareBorderBefore() + flowAwarePaddingBefore(); | 994 flowAwareBorderBefore() + flowAwarePaddingBefore(); |
978 while (computeNextFlexLine(orderedChildren, sumFlexBaseSize, totalFlexGrow, | 995 while (computeNextFlexLine(orderedChildren, sumFlexBaseSize, totalFlexGrow, |
979 totalFlexShrink, totalWeightedFlexShrink, | 996 totalFlexShrink, totalWeightedFlexShrink, |
980 sumHypotheticalMainSize, relayoutChildren, | 997 sumHypotheticalMainSize, relayoutChildren, |
981 childToExclude)) { | 998 childToExclude)) { |
982 LayoutUnit containerMainInnerSize = | 999 LayoutUnit containerMainInnerSize = |
983 mainAxisContentExtent(sumHypotheticalMainSize); | 1000 mainAxisContentExtent(sumHypotheticalMainSize); |
984 // availableFreeSpace is the initial amount of free space in this flexbox. | 1001 // availableFreeSpace is the initial amount of free space in this flexbox. |
985 // remainingFreeSpace starts out at the same value but as we place and lay o
ut | 1002 // remainingFreeSpace starts out at the same value but as we place and lay |
986 // flex items we subtract from it. Note that both values can be negative. | 1003 // out flex items we subtract from it. Note that both values can be |
| 1004 // negative. |
987 LayoutUnit remainingFreeSpace = containerMainInnerSize - sumFlexBaseSize; | 1005 LayoutUnit remainingFreeSpace = containerMainInnerSize - sumFlexBaseSize; |
988 FlexSign flexSign = (sumHypotheticalMainSize < containerMainInnerSize) | 1006 FlexSign flexSign = (sumHypotheticalMainSize < containerMainInnerSize) |
989 ? PositiveFlexibility | 1007 ? PositiveFlexibility |
990 : NegativeFlexibility; | 1008 : NegativeFlexibility; |
991 freezeInflexibleItems(flexSign, orderedChildren, remainingFreeSpace, | 1009 freezeInflexibleItems(flexSign, orderedChildren, remainingFreeSpace, |
992 totalFlexGrow, totalFlexShrink, | 1010 totalFlexGrow, totalFlexShrink, |
993 totalWeightedFlexShrink); | 1011 totalWeightedFlexShrink); |
994 // The initial free space gets calculated after freezing inflexible items. h
ttps://drafts.csswg.org/css-flexbox/#resolve-flexible-lengths step 3 | 1012 // The initial free space gets calculated after freezing inflexible items. |
| 1013 // https://drafts.csswg.org/css-flexbox/#resolve-flexible-lengths step 3 |
995 const LayoutUnit initialFreeSpace = remainingFreeSpace; | 1014 const LayoutUnit initialFreeSpace = remainingFreeSpace; |
996 while (!resolveFlexibleLengths(flexSign, orderedChildren, initialFreeSpace, | 1015 while (!resolveFlexibleLengths(flexSign, orderedChildren, initialFreeSpace, |
997 remainingFreeSpace, totalFlexGrow, | 1016 remainingFreeSpace, totalFlexGrow, |
998 totalFlexShrink, totalWeightedFlexShrink)) { | 1017 totalFlexShrink, totalWeightedFlexShrink)) { |
999 DCHECK_GE(totalFlexGrow, 0); | 1018 DCHECK_GE(totalFlexGrow, 0); |
1000 DCHECK_GE(totalWeightedFlexShrink, 0); | 1019 DCHECK_GE(totalWeightedFlexShrink, 0); |
1001 } | 1020 } |
1002 | 1021 |
1003 // Recalculate the remaining free space. The adjustment for flex factors bet
ween 0..1 means we can't just | 1022 // Recalculate the remaining free space. The adjustment for flex factors |
1004 // use remainingFreeSpace here. | 1023 // between 0..1 means we can't just use remainingFreeSpace here. |
1005 remainingFreeSpace = containerMainInnerSize; | 1024 remainingFreeSpace = containerMainInnerSize; |
1006 for (size_t i = 0; i < orderedChildren.size(); ++i) { | 1025 for (size_t i = 0; i < orderedChildren.size(); ++i) { |
1007 FlexItem& flexItem = orderedChildren[i]; | 1026 FlexItem& flexItem = orderedChildren[i]; |
1008 LayoutBox* child = orderedChildren[i].box; | 1027 LayoutBox* child = orderedChildren[i].box; |
1009 if (child->isOutOfFlowPositioned()) | 1028 if (child->isOutOfFlowPositioned()) |
1010 continue; | 1029 continue; |
1011 remainingFreeSpace -= orderedChildren[i].flexedContentSize + | 1030 remainingFreeSpace -= orderedChildren[i].flexedContentSize + |
1012 flexItem.mainAxisBorderAndPadding + | 1031 flexItem.mainAxisBorderAndPadding + |
1013 flexItem.mainAxisMargin; | 1032 flexItem.mainAxisMargin; |
1014 } | 1033 } |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1123 child.setMarginTop(availableAlignmentSpace / 2); | 1142 child.setMarginTop(availableAlignmentSpace / 2); |
1124 child.setMarginBottom(availableAlignmentSpace / 2); | 1143 child.setMarginBottom(availableAlignmentSpace / 2); |
1125 } else { | 1144 } else { |
1126 child.setMarginLeft(availableAlignmentSpace / 2); | 1145 child.setMarginLeft(availableAlignmentSpace / 2); |
1127 child.setMarginRight(availableAlignmentSpace / 2); | 1146 child.setMarginRight(availableAlignmentSpace / 2); |
1128 } | 1147 } |
1129 return true; | 1148 return true; |
1130 } | 1149 } |
1131 bool shouldAdjustTopOrLeft = true; | 1150 bool shouldAdjustTopOrLeft = true; |
1132 if (isColumnFlow() && !child.style()->isLeftToRightDirection()) { | 1151 if (isColumnFlow() && !child.style()->isLeftToRightDirection()) { |
1133 // For column flows, only make this adjustment if topOrLeft corresponds to t
he "before" margin, | 1152 // For column flows, only make this adjustment if topOrLeft corresponds to |
1134 // so that flipForRightToLeftColumn will do the right thing. | 1153 // the "before" margin, so that flipForRightToLeftColumn will do the right |
| 1154 // thing. |
1135 shouldAdjustTopOrLeft = false; | 1155 shouldAdjustTopOrLeft = false; |
1136 } | 1156 } |
1137 if (!isColumnFlow() && child.style()->isFlippedBlocksWritingMode()) { | 1157 if (!isColumnFlow() && child.style()->isFlippedBlocksWritingMode()) { |
1138 // If we are a flipped writing mode, we need to adjust the opposite side. Th
is is only needed | 1158 // If we are a flipped writing mode, we need to adjust the opposite side. |
1139 // for row flows because this only affects the block-direction axis. | 1159 // This is only needed for row flows because this only affects the |
| 1160 // block-direction axis. |
1140 shouldAdjustTopOrLeft = false; | 1161 shouldAdjustTopOrLeft = false; |
1141 } | 1162 } |
1142 | 1163 |
1143 if (topOrLeft.isAuto()) { | 1164 if (topOrLeft.isAuto()) { |
1144 if (shouldAdjustTopOrLeft) | 1165 if (shouldAdjustTopOrLeft) |
1145 adjustAlignmentForChild(child, availableAlignmentSpace); | 1166 adjustAlignmentForChild(child, availableAlignmentSpace); |
1146 | 1167 |
1147 if (isHorizontal) | 1168 if (isHorizontal) |
1148 child.setMarginTop(availableAlignmentSpace); | 1169 child.setMarginTop(availableAlignmentSpace); |
1149 else | 1170 else |
(...skipping 15 matching lines...) Expand all Loading... |
1165 | 1186 |
1166 DISABLE_CFI_PERF | 1187 DISABLE_CFI_PERF |
1167 LayoutUnit LayoutFlexibleBox::marginBoxAscentForChild(const LayoutBox& child) { | 1188 LayoutUnit LayoutFlexibleBox::marginBoxAscentForChild(const LayoutBox& child) { |
1168 LayoutUnit ascent(child.firstLineBoxBaseline()); | 1189 LayoutUnit ascent(child.firstLineBoxBaseline()); |
1169 if (ascent == -1) | 1190 if (ascent == -1) |
1170 ascent = crossAxisExtentForChild(child); | 1191 ascent = crossAxisExtentForChild(child); |
1171 return ascent + flowAwareMarginBeforeForChild(child); | 1192 return ascent + flowAwareMarginBeforeForChild(child); |
1172 } | 1193 } |
1173 | 1194 |
1174 LayoutUnit LayoutFlexibleBox::computeChildMarginValue(Length margin) { | 1195 LayoutUnit LayoutFlexibleBox::computeChildMarginValue(Length margin) { |
1175 // When resolving the margins, we use the content size for resolving percent a
nd calc (for percents in calc expressions) margins. | 1196 // When resolving the margins, we use the content size for resolving percent |
1176 // Fortunately, percent margins are always computed with respect to the block'
s width, even for margin-top and margin-bottom. | 1197 // and calc (for percents in calc expressions) margins. Fortunately, percent |
| 1198 // margins are always computed with respect to the block's width, even for |
| 1199 // margin-top and margin-bottom. |
1177 LayoutUnit availableSize = contentLogicalWidth(); | 1200 LayoutUnit availableSize = contentLogicalWidth(); |
1178 return minimumValueForLength(margin, availableSize); | 1201 return minimumValueForLength(margin, availableSize); |
1179 } | 1202 } |
1180 | 1203 |
1181 void LayoutFlexibleBox::prepareOrderIteratorAndMargins() { | 1204 void LayoutFlexibleBox::prepareOrderIteratorAndMargins() { |
1182 OrderIteratorPopulator populator(m_orderIterator); | 1205 OrderIteratorPopulator populator(m_orderIterator); |
1183 | 1206 |
1184 for (LayoutBox* child = firstChildBox(); child; | 1207 for (LayoutBox* child = firstChildBox(); child; |
1185 child = child->nextSiblingBox()) { | 1208 child = child->nextSiblingBox()) { |
1186 populator.collectChild(child); | 1209 populator.collectChild(child); |
1187 | 1210 |
1188 if (child->isOutOfFlowPositioned()) | 1211 if (child->isOutOfFlowPositioned()) |
1189 continue; | 1212 continue; |
1190 | 1213 |
1191 // Before running the flex algorithm, 'auto' has a margin of 0. | 1214 // Before running the flex algorithm, 'auto' has a margin of 0. |
1192 // Also, if we're not auto sizing, we don't do a layout that computes the st
art/end margins. | 1215 // Also, if we're not auto sizing, we don't do a layout that computes the |
| 1216 // start/end margins. |
1193 if (isHorizontalFlow()) { | 1217 if (isHorizontalFlow()) { |
1194 child->setMarginLeft( | 1218 child->setMarginLeft( |
1195 computeChildMarginValue(child->style()->marginLeft())); | 1219 computeChildMarginValue(child->style()->marginLeft())); |
1196 child->setMarginRight( | 1220 child->setMarginRight( |
1197 computeChildMarginValue(child->style()->marginRight())); | 1221 computeChildMarginValue(child->style()->marginRight())); |
1198 } else { | 1222 } else { |
1199 child->setMarginTop(computeChildMarginValue(child->style()->marginTop())); | 1223 child->setMarginTop(computeChildMarginValue(child->style()->marginTop())); |
1200 child->setMarginBottom( | 1224 child->setMarginBottom( |
1201 computeChildMarginValue(child->style()->marginBottom())); | 1225 computeChildMarginValue(child->style()->marginBottom())); |
1202 } | 1226 } |
(...skipping 12 matching lines...) Expand all Loading... |
1215 DCHECK_GE(maxExtent, LayoutUnit(-1)); | 1239 DCHECK_GE(maxExtent, LayoutUnit(-1)); |
1216 if (maxExtent != -1 && childSize > maxExtent) | 1240 if (maxExtent != -1 && childSize > maxExtent) |
1217 childSize = maxExtent; | 1241 childSize = maxExtent; |
1218 } | 1242 } |
1219 | 1243 |
1220 Length min = isHorizontalFlow() ? child.style()->minWidth() | 1244 Length min = isHorizontalFlow() ? child.style()->minWidth() |
1221 : child.style()->minHeight(); | 1245 : child.style()->minHeight(); |
1222 LayoutUnit minExtent; | 1246 LayoutUnit minExtent; |
1223 if (min.isSpecifiedOrIntrinsic()) { | 1247 if (min.isSpecifiedOrIntrinsic()) { |
1224 minExtent = computeMainAxisExtentForChild(child, MinSize, min); | 1248 minExtent = computeMainAxisExtentForChild(child, MinSize, min); |
1225 // computeMainAxisExtentForChild can return -1 when the child has a percenta
ge | 1249 // computeMainAxisExtentForChild can return -1 when the child has a |
1226 // min size, but we have an indefinite size in that axis. | 1250 // percentage min size, but we have an indefinite size in that axis. |
1227 minExtent = std::max(LayoutUnit(), minExtent); | 1251 minExtent = std::max(LayoutUnit(), minExtent); |
1228 } else if (min.isAuto() && !child.styleRef().containsSize() && | 1252 } else if (min.isAuto() && !child.styleRef().containsSize() && |
1229 mainAxisOverflowForChild(child) == OverflowVisible && | 1253 mainAxisOverflowForChild(child) == OverflowVisible && |
1230 !(isColumnFlow() && child.isFlexibleBox())) { | 1254 !(isColumnFlow() && child.isFlexibleBox())) { |
1231 // TODO(cbiesinger): For now, we do not handle min-height: auto for nested c
olumn flexboxes. We need | 1255 // TODO(cbiesinger): For now, we do not handle min-height: auto for nested |
1232 // to implement https://drafts.csswg.org/css-flexbox/#intrinsic-sizes before
that produces | 1256 // column flexboxes. We need to implement |
1233 // reasonable results. Tracking bug: https://crbug.com/581553 | 1257 // https://drafts.csswg.org/css-flexbox/#intrinsic-sizes before that |
| 1258 // produces reasonable results. Tracking bug: https://crbug.com/581553 |
1234 // css-flexbox section 4.5 | 1259 // css-flexbox section 4.5 |
1235 LayoutUnit contentSize = | 1260 LayoutUnit contentSize = |
1236 computeMainAxisExtentForChild(child, MinSize, Length(MinContent)); | 1261 computeMainAxisExtentForChild(child, MinSize, Length(MinContent)); |
1237 DCHECK_GE(contentSize, LayoutUnit()); | 1262 DCHECK_GE(contentSize, LayoutUnit()); |
1238 if (hasAspectRatio(child) && child.intrinsicSize().height() > 0) | 1263 if (hasAspectRatio(child) && child.intrinsicSize().height() > 0) |
1239 contentSize = | 1264 contentSize = |
1240 adjustChildSizeForAspectRatioCrossAxisMinAndMax(child, contentSize); | 1265 adjustChildSizeForAspectRatioCrossAxisMinAndMax(child, contentSize); |
1241 if (maxExtent != -1 && contentSize > maxExtent) | 1266 if (maxExtent != -1 && contentSize > maxExtent) |
1242 contentSize = maxExtent; | 1267 contentSize = maxExtent; |
1243 | 1268 |
(...skipping 28 matching lines...) Expand all Loading... |
1272 const LayoutBox& child) { | 1297 const LayoutBox& child) { |
1273 if (alignmentForChild(child) != ItemPositionStretch) | 1298 if (alignmentForChild(child) != ItemPositionStretch) |
1274 return LayoutUnit(-1); | 1299 return LayoutUnit(-1); |
1275 | 1300 |
1276 // Here we implement https://drafts.csswg.org/css-flexbox/#algo-stretch | 1301 // Here we implement https://drafts.csswg.org/css-flexbox/#algo-stretch |
1277 if (hasOrthogonalFlow(child) && child.hasOverrideLogicalContentWidth()) | 1302 if (hasOrthogonalFlow(child) && child.hasOverrideLogicalContentWidth()) |
1278 return child.overrideLogicalContentWidth(); | 1303 return child.overrideLogicalContentWidth(); |
1279 if (!hasOrthogonalFlow(child) && child.hasOverrideLogicalContentHeight()) | 1304 if (!hasOrthogonalFlow(child) && child.hasOverrideLogicalContentHeight()) |
1280 return child.overrideLogicalContentHeight(); | 1305 return child.overrideLogicalContentHeight(); |
1281 | 1306 |
1282 // We don't currently implement the optimization from https://drafts.csswg.org
/css-flexbox/#definite-sizes | 1307 // We don't currently implement the optimization from |
1283 // case 1. While that could speed up a specialized case, it requires determini
ng if we have a definite | 1308 // https://drafts.csswg.org/css-flexbox/#definite-sizes case 1. While that |
1284 // size, which itself is not cheap. We can consider implementing it at a later
time. | 1309 // could speed up a specialized case, it requires determining if we have a |
1285 // (The correctness is ensured by redoing layout in applyStretchAlignmentToChi
ld) | 1310 // definite size, which itself is not cheap. We can consider implementing it |
| 1311 // at a later time. (The correctness is ensured by redoing layout in |
| 1312 // applyStretchAlignmentToChild) |
1286 return LayoutUnit(-1); | 1313 return LayoutUnit(-1); |
1287 } | 1314 } |
1288 | 1315 |
1289 LayoutUnit LayoutFlexibleBox::mainSizeForPercentageResolution( | 1316 LayoutUnit LayoutFlexibleBox::mainSizeForPercentageResolution( |
1290 const LayoutBox& child) { | 1317 const LayoutBox& child) { |
1291 // This function implements section 9.8. Definite and Indefinite Sizes, case | 1318 // This function implements section 9.8. Definite and Indefinite Sizes, case |
1292 // 2) of the flexbox spec. | 1319 // 2) of the flexbox spec. |
1293 // We need to check for the flexbox to have a definite main size, and for the | 1320 // We need to check for the flexbox to have a definite main size, and for the |
1294 // flex item to have a definite flex basis. | 1321 // flex item to have a definite flex basis. |
1295 const Length& flexBasis = flexBasisForChild(child); | 1322 const Length& flexBasis = flexBasisForChild(child); |
1296 if (!mainAxisLengthIsDefinite(child, flexBasis)) | 1323 if (!mainAxisLengthIsDefinite(child, flexBasis)) |
1297 return LayoutUnit(-1); | 1324 return LayoutUnit(-1); |
1298 if (!flexBasis.isPercentOrCalc()) { | 1325 if (!flexBasis.isPercentOrCalc()) { |
1299 // If flex basis had a percentage, our size is guaranteed to be definite or
the flex item's | 1326 // If flex basis had a percentage, our size is guaranteed to be definite or |
1300 // size could not be definite. | 1327 // the flex item's size could not be definite. Otherwise, we make up a |
1301 // Otherwise, we make up a percentage to check whether we have a definite si
ze. | 1328 // percentage to check whether we have a definite size. |
1302 if (!mainAxisLengthIsDefinite(child, Length(0, Percent))) | 1329 if (!mainAxisLengthIsDefinite(child, Length(0, Percent))) |
1303 return LayoutUnit(-1); | 1330 return LayoutUnit(-1); |
1304 } | 1331 } |
1305 | 1332 |
1306 if (hasOrthogonalFlow(child)) | 1333 if (hasOrthogonalFlow(child)) |
1307 return child.hasOverrideLogicalContentHeight() | 1334 return child.hasOverrideLogicalContentHeight() |
1308 ? child.overrideLogicalContentHeight() | 1335 ? child.overrideLogicalContentHeight() |
1309 : LayoutUnit(-1); | 1336 : LayoutUnit(-1); |
1310 return child.hasOverrideLogicalContentWidth() | 1337 return child.hasOverrideLogicalContentWidth() |
1311 ? child.overrideLogicalContentWidth() | 1338 ? child.overrideLogicalContentWidth() |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1374 if (!m_orderIterator.currentChild()) | 1401 if (!m_orderIterator.currentChild()) |
1375 return false; | 1402 return false; |
1376 | 1403 |
1377 LayoutUnit lineBreakLength = mainAxisContentExtent(LayoutUnit::max()); | 1404 LayoutUnit lineBreakLength = mainAxisContentExtent(LayoutUnit::max()); |
1378 | 1405 |
1379 bool lineHasInFlowItem = false; | 1406 bool lineHasInFlowItem = false; |
1380 | 1407 |
1381 for (LayoutBox* child = m_orderIterator.currentChild(); child; | 1408 for (LayoutBox* child = m_orderIterator.currentChild(); child; |
1382 child = m_orderIterator.next()) { | 1409 child = m_orderIterator.next()) { |
1383 if (childToExclude == child) | 1410 if (childToExclude == child) |
1384 continue; // Skip this child, since it will be positioned by the speciali
zed subclass (fieldsets runs). | 1411 continue; // Skip this child, since it will be positioned by the |
| 1412 // specialized subclass (fieldsets runs). |
1385 | 1413 |
1386 if (child->isOutOfFlowPositioned()) { | 1414 if (child->isOutOfFlowPositioned()) { |
1387 orderedChildren.append(FlexItem(child)); | 1415 orderedChildren.append(FlexItem(child)); |
1388 continue; | 1416 continue; |
1389 } | 1417 } |
1390 | 1418 |
1391 ChildLayoutType layoutType = | 1419 ChildLayoutType layoutType = |
1392 relayoutChildren ? ForceLayout : LayoutIfNeeded; | 1420 relayoutChildren ? ForceLayout : LayoutIfNeeded; |
1393 | 1421 |
1394 // If this condition is true, then computeMainAxisExtentForChild will call c
hild.intrinsicContentLogicalHeight() | 1422 // If this condition is true, then computeMainAxisExtentForChild will call |
1395 // and child.scrollbarLogicalHeight(), so if the child has intrinsic min/max
/preferred size, | 1423 // child.intrinsicContentLogicalHeight() and |
1396 // run layout on it now to make sure its logical height and scroll bars are
up to date. | 1424 // child.scrollbarLogicalHeight(), so if the child has intrinsic |
| 1425 // min/max/preferred size, run layout on it now to make sure its logical |
| 1426 // height and scroll bars are up to date. |
1397 if (childHasIntrinsicMainAxisSize(*child) && child->needsLayout()) { | 1427 if (childHasIntrinsicMainAxisSize(*child) && child->needsLayout()) { |
1398 child->clearOverrideSize(); | 1428 child->clearOverrideSize(); |
1399 child->forceChildLayout(); | 1429 child->forceChildLayout(); |
1400 cacheChildMainSize(*child); | 1430 cacheChildMainSize(*child); |
1401 layoutType = LayoutIfNeeded; | 1431 layoutType = LayoutIfNeeded; |
1402 } | 1432 } |
1403 | 1433 |
1404 FlexItem flexItem = constructFlexItem(*child, layoutType); | 1434 FlexItem flexItem = constructFlexItem(*child, layoutType); |
1405 if (isMultiline() && | 1435 if (isMultiline() && |
1406 sumHypotheticalMainSize + flexItem.hypotheticalMainAxisMarginBoxSize() > | 1436 sumHypotheticalMainSize + flexItem.hypotheticalMainAxisMarginBoxSize() > |
(...skipping 19 matching lines...) Expand all Loading... |
1426 double& totalWeightedFlexShrink) { | 1456 double& totalWeightedFlexShrink) { |
1427 for (size_t i = 0; i < violations.size(); ++i) { | 1457 for (size_t i = 0; i < violations.size(); ++i) { |
1428 DCHECK(!violations[i]->frozen) << i; | 1458 DCHECK(!violations[i]->frozen) << i; |
1429 LayoutBox* child = violations[i]->box; | 1459 LayoutBox* child = violations[i]->box; |
1430 LayoutUnit childSize = violations[i]->flexedContentSize; | 1460 LayoutUnit childSize = violations[i]->flexedContentSize; |
1431 availableFreeSpace -= childSize - violations[i]->flexBaseContentSize; | 1461 availableFreeSpace -= childSize - violations[i]->flexBaseContentSize; |
1432 totalFlexGrow -= child->style()->flexGrow(); | 1462 totalFlexGrow -= child->style()->flexGrow(); |
1433 totalFlexShrink -= child->style()->flexShrink(); | 1463 totalFlexShrink -= child->style()->flexShrink(); |
1434 totalWeightedFlexShrink -= | 1464 totalWeightedFlexShrink -= |
1435 child->style()->flexShrink() * violations[i]->flexBaseContentSize; | 1465 child->style()->flexShrink() * violations[i]->flexBaseContentSize; |
1436 // totalWeightedFlexShrink can be negative when we exceed the precision of a
double when we initially | 1466 // totalWeightedFlexShrink can be negative when we exceed the precision of |
1437 // calcuate totalWeightedFlexShrink. We then subtract each child's weighted
flex shrink with full precision, | 1467 // a double when we initially calcuate totalWeightedFlexShrink. We then |
1438 // now leading to a negative result. See css3/flexbox/large-flex-shrink-asse
rt.html | 1468 // subtract each child's weighted flex shrink with full precision, now |
| 1469 // leading to a negative result. See |
| 1470 // css3/flexbox/large-flex-shrink-assert.html |
1439 totalWeightedFlexShrink = std::max(totalWeightedFlexShrink, 0.0); | 1471 totalWeightedFlexShrink = std::max(totalWeightedFlexShrink, 0.0); |
1440 violations[i]->frozen = true; | 1472 violations[i]->frozen = true; |
1441 } | 1473 } |
1442 } | 1474 } |
1443 | 1475 |
1444 void LayoutFlexibleBox::freezeInflexibleItems(FlexSign flexSign, | 1476 void LayoutFlexibleBox::freezeInflexibleItems(FlexSign flexSign, |
1445 OrderedFlexItemList& children, | 1477 OrderedFlexItemList& children, |
1446 LayoutUnit& remainingFreeSpace, | 1478 LayoutUnit& remainingFreeSpace, |
1447 double& totalFlexGrow, | 1479 double& totalFlexGrow, |
1448 double& totalFlexShrink, | 1480 double& totalFlexShrink, |
1449 double& totalWeightedFlexShrink) { | 1481 double& totalWeightedFlexShrink) { |
1450 // Per https://drafts.csswg.org/css-flexbox/#resolve-flexible-lengths step 2, | 1482 // Per https://drafts.csswg.org/css-flexbox/#resolve-flexible-lengths step 2, |
1451 // we freeze all items with a flex factor of 0 as well as this with a min/max
size violation. | 1483 // we freeze all items with a flex factor of 0 as well as those with a min/max |
| 1484 // size violation. |
1452 Vector<FlexItem*> newInflexibleItems; | 1485 Vector<FlexItem*> newInflexibleItems; |
1453 for (size_t i = 0; i < children.size(); ++i) { | 1486 for (size_t i = 0; i < children.size(); ++i) { |
1454 FlexItem& flexItem = children[i]; | 1487 FlexItem& flexItem = children[i]; |
1455 LayoutBox* child = flexItem.box; | 1488 LayoutBox* child = flexItem.box; |
1456 if (child->isOutOfFlowPositioned()) | 1489 if (child->isOutOfFlowPositioned()) |
1457 continue; | 1490 continue; |
1458 DCHECK(!flexItem.frozen) << i; | 1491 DCHECK(!flexItem.frozen) << i; |
1459 float flexFactor = (flexSign == PositiveFlexibility) | 1492 float flexFactor = (flexSign == PositiveFlexibility) |
1460 ? child->style()->flexGrow() | 1493 ? child->style()->flexGrow() |
1461 : child->style()->flexShrink(); | 1494 : child->style()->flexShrink(); |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1578 ItemPosition position, | 1611 ItemPosition position, |
1579 LayoutUnit ascent, | 1612 LayoutUnit ascent, |
1580 LayoutUnit maxAscent, | 1613 LayoutUnit maxAscent, |
1581 bool isWrapReverse) { | 1614 bool isWrapReverse) { |
1582 switch (position) { | 1615 switch (position) { |
1583 case ItemPositionAuto: | 1616 case ItemPositionAuto: |
1584 case ItemPositionNormal: | 1617 case ItemPositionNormal: |
1585 NOTREACHED(); | 1618 NOTREACHED(); |
1586 break; | 1619 break; |
1587 case ItemPositionStretch: | 1620 case ItemPositionStretch: |
1588 // Actual stretching must be handled by the caller. | 1621 // Actual stretching must be handled by the caller. Since wrap-reverse |
1589 // Since wrap-reverse flips cross start and cross end, stretch children sh
ould be aligned with the cross end. | 1622 // flips cross start and cross end, stretch children should be aligned |
1590 // This matters because applyStretchAlignment doesn't always stretch or st
retch fully (explicit cross size given, | 1623 // with the cross end. This matters because applyStretchAlignment |
1591 // or stretching constrained by max-height/max-width). | 1624 // doesn't always stretch or stretch fully (explicit cross size given, or |
1592 // For flex-start and flex-end this is handled by alignmentForChild(). | 1625 // stretching constrained by max-height/max-width). For flex-start and |
| 1626 // flex-end this is handled by alignmentForChild(). |
1593 if (isWrapReverse) | 1627 if (isWrapReverse) |
1594 return availableFreeSpace; | 1628 return availableFreeSpace; |
1595 break; | 1629 break; |
1596 case ItemPositionFlexStart: | 1630 case ItemPositionFlexStart: |
1597 break; | 1631 break; |
1598 case ItemPositionFlexEnd: | 1632 case ItemPositionFlexEnd: |
1599 return availableFreeSpace; | 1633 return availableFreeSpace; |
1600 case ItemPositionCenter: | 1634 case ItemPositionCenter: |
1601 return availableFreeSpace / 2; | 1635 return availableFreeSpace / 2; |
1602 case ItemPositionBaseline: | 1636 case ItemPositionBaseline: |
1603 // FIXME: If we get here in columns, we want the use the descent, except w
e currently can't get the ascent/descent of orthogonal children. | 1637 // FIXME: If we get here in columns, we want the use the descent, except |
| 1638 // we currently can't get the ascent/descent of orthogonal children. |
1604 // https://bugs.webkit.org/show_bug.cgi?id=98076 | 1639 // https://bugs.webkit.org/show_bug.cgi?id=98076 |
1605 return maxAscent - ascent; | 1640 return maxAscent - ascent; |
1606 case ItemPositionLastBaseline: | 1641 case ItemPositionLastBaseline: |
1607 case ItemPositionSelfStart: | 1642 case ItemPositionSelfStart: |
1608 case ItemPositionSelfEnd: | 1643 case ItemPositionSelfEnd: |
1609 case ItemPositionStart: | 1644 case ItemPositionStart: |
1610 case ItemPositionEnd: | 1645 case ItemPositionEnd: |
1611 case ItemPositionLeft: | 1646 case ItemPositionLeft: |
1612 case ItemPositionRight: | 1647 case ItemPositionRight: |
1613 // FIXME: Implement these (https://crbug.com/507690). The extended grammar | 1648 // FIXME: Implement these (https://crbug.com/507690). The extended grammar |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1761 if (child.style()->marginLeft().isAuto()) | 1796 if (child.style()->marginLeft().isAuto()) |
1762 child.setMarginLeft(LayoutUnit()); | 1797 child.setMarginLeft(LayoutUnit()); |
1763 if (child.style()->marginRight().isAuto()) | 1798 if (child.style()->marginRight().isAuto()) |
1764 child.setMarginRight(LayoutUnit()); | 1799 child.setMarginRight(LayoutUnit()); |
1765 } | 1800 } |
1766 } | 1801 } |
1767 } | 1802 } |
1768 | 1803 |
1769 bool LayoutFlexibleBox::needToStretchChildLogicalHeight( | 1804 bool LayoutFlexibleBox::needToStretchChildLogicalHeight( |
1770 const LayoutBox& child) const { | 1805 const LayoutBox& child) const { |
1771 // This function is a little bit magical. It relies on the fact that blocks in
trinsically | 1806 // This function is a little bit magical. It relies on the fact that blocks |
1772 // "stretch" themselves in their inline axis, i.e. a <div> has an implicit wid
th: 100%. | 1807 // intrinsically "stretch" themselves in their inline axis, i.e. a <div> has |
1773 // So the child will automatically stretch if our cross axis is the child's in
line axis. That's the case if: | 1808 // an implicit width: 100%. So the child will automatically stretch if our |
| 1809 // cross axis is the child's inline axis. That's the case if: |
1774 // - We are horizontal and the child is in vertical writing mode | 1810 // - We are horizontal and the child is in vertical writing mode |
1775 // - We are vertical and the child is in horizontal writing mode | 1811 // - We are vertical and the child is in horizontal writing mode |
1776 // Otherwise, we need to stretch if the cross axis size is auto. | 1812 // Otherwise, we need to stretch if the cross axis size is auto. |
1777 if (alignmentForChild(child) != ItemPositionStretch) | 1813 if (alignmentForChild(child) != ItemPositionStretch) |
1778 return false; | 1814 return false; |
1779 | 1815 |
1780 if (isHorizontalFlow() != child.styleRef().isHorizontalWritingMode()) | 1816 if (isHorizontalFlow() != child.styleRef().isHorizontalWritingMode()) |
1781 return false; | 1817 return false; |
1782 | 1818 |
1783 return child.styleRef().logicalHeight().isAuto(); | 1819 return child.styleRef().logicalHeight().isAuto(); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1860 child->setMayNeedPaintInvalidation(); | 1896 child->setMayNeedPaintInvalidation(); |
1861 | 1897 |
1862 setOverrideMainAxisContentSizeForChild(*child, flexItem.flexedContentSize); | 1898 setOverrideMainAxisContentSizeForChild(*child, flexItem.flexedContentSize); |
1863 // The flexed content size and the override size include the scrollbar | 1899 // The flexed content size and the override size include the scrollbar |
1864 // width, so we need to compare to the size including the scrollbar. | 1900 // width, so we need to compare to the size including the scrollbar. |
1865 // TODO(cbiesinger): Should it include the scrollbar? | 1901 // TODO(cbiesinger): Should it include the scrollbar? |
1866 if (flexItem.flexedContentSize != | 1902 if (flexItem.flexedContentSize != |
1867 mainAxisContentExtentForChildIncludingScrollbar(*child)) { | 1903 mainAxisContentExtentForChildIncludingScrollbar(*child)) { |
1868 child->setChildNeedsLayout(MarkOnlyThis); | 1904 child->setChildNeedsLayout(MarkOnlyThis); |
1869 } else { | 1905 } else { |
1870 // To avoid double applying margin changes in updateAutoMarginsInCrossAxis
, we reset the margins here. | 1906 // To avoid double applying margin changes in |
| 1907 // updateAutoMarginsInCrossAxis, we reset the margins here. |
1871 resetAutoMarginsAndLogicalTopInCrossAxis(*child); | 1908 resetAutoMarginsAndLogicalTopInCrossAxis(*child); |
1872 } | 1909 } |
1873 // We may have already forced relayout for orthogonal flowing children in co
mputeInnerFlexBaseSizeForChild. | 1910 // We may have already forced relayout for orthogonal flowing children in |
| 1911 // computeInnerFlexBaseSizeForChild. |
1874 bool forceChildRelayout = | 1912 bool forceChildRelayout = |
1875 relayoutChildren && !m_relaidOutChildren.contains(child); | 1913 relayoutChildren && !m_relaidOutChildren.contains(child); |
1876 if (child->isLayoutBlock() && | 1914 if (child->isLayoutBlock() && |
1877 toLayoutBlock(*child).hasPercentHeightDescendants()) { | 1915 toLayoutBlock(*child).hasPercentHeightDescendants()) { |
1878 // Have to force another relayout even though the child is sized correctly
, because | 1916 // Have to force another relayout even though the child is sized |
1879 // its descendants are not sized correctly yet. Our previous layout of the
child was | 1917 // correctly, because its descendants are not sized correctly yet. Our |
1880 // done without an override height set. So, redo it here. | 1918 // previous layout of the child was done without an override height set. |
| 1919 // So, redo it here. |
1881 forceChildRelayout = true; | 1920 forceChildRelayout = true; |
1882 } | 1921 } |
1883 updateBlockChildDirtyBitsBeforeLayout(forceChildRelayout, *child); | 1922 updateBlockChildDirtyBitsBeforeLayout(forceChildRelayout, *child); |
1884 if (!child->needsLayout()) | 1923 if (!child->needsLayout()) |
1885 markChildForPaginationRelayoutIfNeeded(*child, layoutScope); | 1924 markChildForPaginationRelayoutIfNeeded(*child, layoutScope); |
1886 if (child->needsLayout()) | 1925 if (child->needsLayout()) |
1887 m_relaidOutChildren.add(child); | 1926 m_relaidOutChildren.add(child); |
1888 child->layoutIfNeeded(); | 1927 child->layoutIfNeeded(); |
1889 | 1928 |
1890 updateAutoMarginsInMainAxis(*child, autoMarginOffset); | 1929 updateAutoMarginsInMainAxis(*child, autoMarginOffset); |
(...skipping 20 matching lines...) Expand all Loading... |
1911 setLogicalHeight(std::max( | 1950 setLogicalHeight(std::max( |
1912 logicalHeight(), | 1951 logicalHeight(), |
1913 crossAxisOffset + flowAwareBorderAfter() + flowAwarePaddingAfter() + | 1952 crossAxisOffset + flowAwareBorderAfter() + flowAwarePaddingAfter() + |
1914 childCrossAxisMarginBoxExtent + crossAxisScrollbarExtent())); | 1953 childCrossAxisMarginBoxExtent + crossAxisScrollbarExtent())); |
1915 maxChildCrossAxisExtent = | 1954 maxChildCrossAxisExtent = |
1916 std::max(maxChildCrossAxisExtent, childCrossAxisMarginBoxExtent); | 1955 std::max(maxChildCrossAxisExtent, childCrossAxisMarginBoxExtent); |
1917 | 1956 |
1918 mainAxisOffset += flowAwareMarginStartForChild(*child); | 1957 mainAxisOffset += flowAwareMarginStartForChild(*child); |
1919 | 1958 |
1920 LayoutUnit childMainExtent = mainAxisExtentForChild(*child); | 1959 LayoutUnit childMainExtent = mainAxisExtentForChild(*child); |
1921 // In an RTL column situation, this will apply the margin-right/margin-end o
n the left. | 1960 // In an RTL column situation, this will apply the margin-right/margin-end |
1922 // This will be fixed later in flipForRightToLeftColumn. | 1961 // on the left. This will be fixed later in flipForRightToLeftColumn. |
1923 LayoutPoint childLocation( | 1962 LayoutPoint childLocation( |
1924 shouldFlipMainAxis ? totalMainExtent - mainAxisOffset - childMainExtent | 1963 shouldFlipMainAxis ? totalMainExtent - mainAxisOffset - childMainExtent |
1925 : mainAxisOffset, | 1964 : mainAxisOffset, |
1926 crossAxisOffset + flowAwareMarginBeforeForChild(*child)); | 1965 crossAxisOffset + flowAwareMarginBeforeForChild(*child)); |
1927 setFlowAwareLocationForChild(*child, childLocation); | 1966 setFlowAwareLocationForChild(*child, childLocation); |
1928 mainAxisOffset += childMainExtent + flowAwareMarginEndForChild(*child); | 1967 mainAxisOffset += childMainExtent + flowAwareMarginEndForChild(*child); |
1929 | 1968 |
1930 ++seenInFlowPositionedChildren; | 1969 ++seenInFlowPositionedChildren; |
1931 if (seenInFlowPositionedChildren < numberOfChildrenForJustifyContent) | 1970 if (seenInFlowPositionedChildren < numberOfChildrenForJustifyContent) |
1932 mainAxisOffset += justifyContentSpaceBetweenChildren( | 1971 mainAxisOffset += justifyContentSpaceBetweenChildren( |
1933 availableFreeSpace, distribution, numberOfChildrenForJustifyContent); | 1972 availableFreeSpace, distribution, numberOfChildrenForJustifyContent); |
1934 } | 1973 } |
1935 | 1974 |
1936 if (isColumnFlow()) | 1975 if (isColumnFlow()) |
1937 setLogicalHeight(std::max( | 1976 setLogicalHeight(std::max( |
1938 logicalHeight(), mainAxisOffset + flowAwareBorderEnd() + | 1977 logicalHeight(), mainAxisOffset + flowAwareBorderEnd() + |
1939 flowAwarePaddingEnd() + scrollbarLogicalHeight())); | 1978 flowAwarePaddingEnd() + scrollbarLogicalHeight())); |
1940 | 1979 |
1941 if (style()->flexDirection() == FlowColumnReverse) { | 1980 if (style()->flexDirection() == FlowColumnReverse) { |
1942 // We have to do an extra pass for column-reverse to reposition the flex ite
ms since the start depends | 1981 // We have to do an extra pass for column-reverse to reposition the flex |
1943 // on the height of the flexbox, which we only know after we've positioned a
ll the flex items. | 1982 // items since the start depends on the height of the flexbox, which we |
| 1983 // only know after we've positioned all the flex items. |
1944 updateLogicalHeight(); | 1984 updateLogicalHeight(); |
1945 layoutColumnReverse(children, crossAxisOffset, availableFreeSpace); | 1985 layoutColumnReverse(children, crossAxisOffset, availableFreeSpace); |
1946 } | 1986 } |
1947 | 1987 |
1948 if (m_numberOfInFlowChildrenOnFirstLine == -1) | 1988 if (m_numberOfInFlowChildrenOnFirstLine == -1) |
1949 m_numberOfInFlowChildrenOnFirstLine = seenInFlowPositionedChildren; | 1989 m_numberOfInFlowChildrenOnFirstLine = seenInFlowPositionedChildren; |
1950 lineContexts.append(LineContext(crossAxisOffset, maxChildCrossAxisExtent, | 1990 lineContexts.append(LineContext(crossAxisOffset, maxChildCrossAxisExtent, |
1951 children.size(), maxAscent)); | 1991 children.size(), maxAscent)); |
1952 crossAxisOffset += maxChildCrossAxisExtent; | 1992 crossAxisOffset += maxChildCrossAxisExtent; |
1953 } | 1993 } |
1954 | 1994 |
1955 void LayoutFlexibleBox::layoutColumnReverse(const OrderedFlexItemList& children, | 1995 void LayoutFlexibleBox::layoutColumnReverse(const OrderedFlexItemList& children, |
1956 LayoutUnit crossAxisOffset, | 1996 LayoutUnit crossAxisOffset, |
1957 LayoutUnit availableFreeSpace) { | 1997 LayoutUnit availableFreeSpace) { |
1958 ContentPosition position = styleRef().resolvedJustifyContentPosition( | 1998 ContentPosition position = styleRef().resolvedJustifyContentPosition( |
1959 contentAlignmentNormalBehavior()); | 1999 contentAlignmentNormalBehavior()); |
1960 ContentDistributionType distribution = | 2000 ContentDistributionType distribution = |
1961 styleRef().resolvedJustifyContentDistribution( | 2001 styleRef().resolvedJustifyContentDistribution( |
1962 contentAlignmentNormalBehavior()); | 2002 contentAlignmentNormalBehavior()); |
1963 | 2003 |
1964 // This is similar to the logic in layoutAndPlaceChildren, except we place the
children | 2004 // This is similar to the logic in layoutAndPlaceChildren, except we place |
1965 // starting from the end of the flexbox. We also don't need to layout anything
since we're | 2005 // the children starting from the end of the flexbox. We also don't need to |
1966 // just moving the children to a new position. | 2006 // layout anything since we're just moving the children to a new position. |
1967 size_t numberOfChildrenForJustifyContent = | 2007 size_t numberOfChildrenForJustifyContent = |
1968 numberOfInFlowPositionedChildren(children); | 2008 numberOfInFlowPositionedChildren(children); |
1969 LayoutUnit mainAxisOffset = | 2009 LayoutUnit mainAxisOffset = |
1970 logicalHeight() - flowAwareBorderEnd() - flowAwarePaddingEnd(); | 2010 logicalHeight() - flowAwareBorderEnd() - flowAwarePaddingEnd(); |
1971 mainAxisOffset -= | 2011 mainAxisOffset -= |
1972 initialJustifyContentOffset(availableFreeSpace, position, distribution, | 2012 initialJustifyContentOffset(availableFreeSpace, position, distribution, |
1973 numberOfChildrenForJustifyContent); | 2013 numberOfChildrenForJustifyContent); |
1974 mainAxisOffset -= isHorizontalFlow() ? verticalScrollbarWidth() | 2014 mainAxisOffset -= isHorizontalFlow() ? verticalScrollbarWidth() |
1975 : horizontalScrollbarHeight(); | 2015 : horizontalScrollbarHeight(); |
1976 | 2016 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2032 return LayoutUnit(); | 2072 return LayoutUnit(); |
2033 } | 2073 } |
2034 | 2074 |
2035 void LayoutFlexibleBox::alignFlexLines(Vector<LineContext>& lineContexts) { | 2075 void LayoutFlexibleBox::alignFlexLines(Vector<LineContext>& lineContexts) { |
2036 ContentPosition position = | 2076 ContentPosition position = |
2037 styleRef().resolvedAlignContentPosition(contentAlignmentNormalBehavior()); | 2077 styleRef().resolvedAlignContentPosition(contentAlignmentNormalBehavior()); |
2038 ContentDistributionType distribution = | 2078 ContentDistributionType distribution = |
2039 styleRef().resolvedAlignContentDistribution( | 2079 styleRef().resolvedAlignContentDistribution( |
2040 contentAlignmentNormalBehavior()); | 2080 contentAlignmentNormalBehavior()); |
2041 | 2081 |
2042 // If we have a single line flexbox or a multiline line flexbox with only one
flex line, | 2082 // If we have a single line flexbox or a multiline line flexbox with only one |
2043 // the line height is all the available space. | 2083 // flex line, the line height is all the available space. For |
2044 // For flex-direction: row, this means we need to use the height, so we do thi
s after calling updateLogicalHeight. | 2084 // flex-direction: row, this means we need to use the height, so we do this |
| 2085 // after calling updateLogicalHeight. |
2045 if (lineContexts.size() == 1) { | 2086 if (lineContexts.size() == 1) { |
2046 lineContexts[0].crossAxisExtent = crossAxisContentExtent(); | 2087 lineContexts[0].crossAxisExtent = crossAxisContentExtent(); |
2047 return; | 2088 return; |
2048 } | 2089 } |
2049 | 2090 |
2050 if (position == ContentPositionFlexStart) | 2091 if (position == ContentPositionFlexStart) |
2051 return; | 2092 return; |
2052 | 2093 |
2053 LayoutUnit availableCrossAxisSpace = crossAxisContentExtent(); | 2094 LayoutUnit availableCrossAxisSpace = crossAxisContentExtent(); |
2054 for (size_t i = 0; i < lineContexts.size(); ++i) | 2095 for (size_t i = 0; i < lineContexts.size(); ++i) |
(...skipping 24 matching lines...) Expand all Loading... |
2079 LayoutUnit delta) { | 2120 LayoutUnit delta) { |
2080 if (child.isOutOfFlowPositioned()) | 2121 if (child.isOutOfFlowPositioned()) |
2081 return; | 2122 return; |
2082 | 2123 |
2083 setFlowAwareLocationForChild(child, flowAwareLocationForChild(child) + | 2124 setFlowAwareLocationForChild(child, flowAwareLocationForChild(child) + |
2084 LayoutSize(LayoutUnit(), delta)); | 2125 LayoutSize(LayoutUnit(), delta)); |
2085 } | 2126 } |
2086 | 2127 |
2087 void LayoutFlexibleBox::alignChildren(const Vector<LineContext>& lineContexts, | 2128 void LayoutFlexibleBox::alignChildren(const Vector<LineContext>& lineContexts, |
2088 LayoutObject* childToExclude) { | 2129 LayoutObject* childToExclude) { |
2089 // Keep track of the space between the baseline edge and the after edge of the
box for each line. | 2130 // Keep track of the space between the baseline edge and the after edge of |
| 2131 // the box for each line. |
2090 Vector<LayoutUnit> minMarginAfterBaselines; | 2132 Vector<LayoutUnit> minMarginAfterBaselines; |
2091 | 2133 |
2092 LayoutBox* child = m_orderIterator.first(); | 2134 LayoutBox* child = m_orderIterator.first(); |
2093 for (size_t lineNumber = 0; lineNumber < lineContexts.size(); ++lineNumber) { | 2135 for (size_t lineNumber = 0; lineNumber < lineContexts.size(); ++lineNumber) { |
2094 LayoutUnit minMarginAfterBaseline = LayoutUnit::max(); | 2136 LayoutUnit minMarginAfterBaseline = LayoutUnit::max(); |
2095 LayoutUnit lineCrossAxisExtent = lineContexts[lineNumber].crossAxisExtent; | 2137 LayoutUnit lineCrossAxisExtent = lineContexts[lineNumber].crossAxisExtent; |
2096 LayoutUnit maxAscent = lineContexts[lineNumber].maxAscent; | 2138 LayoutUnit maxAscent = lineContexts[lineNumber].maxAscent; |
2097 | 2139 |
2098 for (size_t childNumber = 0; | 2140 for (size_t childNumber = 0; |
2099 childNumber < lineContexts[lineNumber].numberOfChildren; | 2141 childNumber < lineContexts[lineNumber].numberOfChildren; |
(...skipping 27 matching lines...) Expand all Loading... |
2127 minMarginAfterBaseline, | 2169 minMarginAfterBaseline, |
2128 availableAlignmentSpaceForChild(lineCrossAxisExtent, *child) - | 2170 availableAlignmentSpaceForChild(lineCrossAxisExtent, *child) - |
2129 offset); | 2171 offset); |
2130 } | 2172 } |
2131 minMarginAfterBaselines.append(minMarginAfterBaseline); | 2173 minMarginAfterBaselines.append(minMarginAfterBaseline); |
2132 } | 2174 } |
2133 | 2175 |
2134 if (style()->flexWrap() != FlexWrapReverse) | 2176 if (style()->flexWrap() != FlexWrapReverse) |
2135 return; | 2177 return; |
2136 | 2178 |
2137 // wrap-reverse flips the cross axis start and end. For baseline alignment, th
is means we | 2179 // wrap-reverse flips the cross axis start and end. For baseline alignment, |
2138 // need to align the after edge of baseline elements with the after edge of th
e flex line. | 2180 // this means we need to align the after edge of baseline elements with the |
| 2181 // after edge of the flex line. |
2139 child = m_orderIterator.first(); | 2182 child = m_orderIterator.first(); |
2140 for (size_t lineNumber = 0; lineNumber < lineContexts.size(); ++lineNumber) { | 2183 for (size_t lineNumber = 0; lineNumber < lineContexts.size(); ++lineNumber) { |
2141 LayoutUnit minMarginAfterBaseline = minMarginAfterBaselines[lineNumber]; | 2184 LayoutUnit minMarginAfterBaseline = minMarginAfterBaselines[lineNumber]; |
2142 for (size_t childNumber = 0; | 2185 for (size_t childNumber = 0; |
2143 childNumber < lineContexts[lineNumber].numberOfChildren; | 2186 childNumber < lineContexts[lineNumber].numberOfChildren; |
2144 ++childNumber, child = m_orderIterator.next()) { | 2187 ++childNumber, child = m_orderIterator.next()) { |
2145 DCHECK(child); | 2188 DCHECK(child); |
2146 if (alignmentForChild(*child) == ItemPositionBaseline && | 2189 if (alignmentForChild(*child) == ItemPositionBaseline && |
2147 !hasAutoMarginsInCrossAxis(*child) && minMarginAfterBaseline) | 2190 !hasAutoMarginsInCrossAxis(*child) && minMarginAfterBaseline) |
2148 adjustAlignmentForChild(*child, minMarginAfterBaseline); | 2191 adjustAlignmentForChild(*child, minMarginAfterBaseline); |
2149 } | 2192 } |
2150 } | 2193 } |
2151 } | 2194 } |
2152 | 2195 |
2153 void LayoutFlexibleBox::applyStretchAlignmentToChild( | 2196 void LayoutFlexibleBox::applyStretchAlignmentToChild( |
2154 LayoutBox& child, | 2197 LayoutBox& child, |
2155 LayoutUnit lineCrossAxisExtent) { | 2198 LayoutUnit lineCrossAxisExtent) { |
2156 if (!hasOrthogonalFlow(child) && child.style()->logicalHeight().isAuto()) { | 2199 if (!hasOrthogonalFlow(child) && child.style()->logicalHeight().isAuto()) { |
2157 LayoutUnit heightBeforeStretching = childIntrinsicLogicalHeight(child); | 2200 LayoutUnit heightBeforeStretching = childIntrinsicLogicalHeight(child); |
2158 LayoutUnit stretchedLogicalHeight = | 2201 LayoutUnit stretchedLogicalHeight = |
2159 std::max(child.borderAndPaddingLogicalHeight(), | 2202 std::max(child.borderAndPaddingLogicalHeight(), |
2160 heightBeforeStretching + | 2203 heightBeforeStretching + |
2161 availableAlignmentSpaceForChildBeforeStretching( | 2204 availableAlignmentSpaceForChildBeforeStretching( |
2162 lineCrossAxisExtent, child)); | 2205 lineCrossAxisExtent, child)); |
2163 DCHECK(!child.needsLayout()); | 2206 DCHECK(!child.needsLayout()); |
2164 LayoutUnit desiredLogicalHeight = child.constrainLogicalHeightByMinMax( | 2207 LayoutUnit desiredLogicalHeight = child.constrainLogicalHeightByMinMax( |
2165 stretchedLogicalHeight, | 2208 stretchedLogicalHeight, |
2166 heightBeforeStretching - child.borderAndPaddingLogicalHeight()); | 2209 heightBeforeStretching - child.borderAndPaddingLogicalHeight()); |
2167 | 2210 |
2168 // FIXME: Can avoid laying out here in some cases. See https://webkit.org/b/
87905. | 2211 // FIXME: Can avoid laying out here in some cases. See |
| 2212 // https://webkit.org/b/87905. |
2169 bool childNeedsRelayout = desiredLogicalHeight != child.logicalHeight(); | 2213 bool childNeedsRelayout = desiredLogicalHeight != child.logicalHeight(); |
2170 if (child.isLayoutBlock() && | 2214 if (child.isLayoutBlock() && |
2171 toLayoutBlock(child).hasPercentHeightDescendants() && | 2215 toLayoutBlock(child).hasPercentHeightDescendants() && |
2172 m_relaidOutChildren.contains(&child)) { | 2216 m_relaidOutChildren.contains(&child)) { |
2173 // Have to force another relayout even though the child is sized correctly
, because | 2217 // Have to force another relayout even though the child is sized |
2174 // its descendants are not sized correctly yet. Our previous layout of the
child was | 2218 // correctly, because its descendants are not sized correctly yet. Our |
2175 // done without an override height set. So, redo it here. | 2219 // previous layout of the child was done without an override height set. |
| 2220 // So, redo it here. |
2176 childNeedsRelayout = true; | 2221 childNeedsRelayout = true; |
2177 } | 2222 } |
2178 if (childNeedsRelayout || !child.hasOverrideLogicalContentHeight()) | 2223 if (childNeedsRelayout || !child.hasOverrideLogicalContentHeight()) |
2179 child.setOverrideLogicalContentHeight( | 2224 child.setOverrideLogicalContentHeight( |
2180 desiredLogicalHeight - child.borderAndPaddingLogicalHeight()); | 2225 desiredLogicalHeight - child.borderAndPaddingLogicalHeight()); |
2181 if (childNeedsRelayout) { | 2226 if (childNeedsRelayout) { |
2182 child.setLogicalHeight(LayoutUnit()); | 2227 child.setLogicalHeight(LayoutUnit()); |
2183 // We cache the child's intrinsic content logical height to avoid it being
reset to the stretched height. | 2228 // We cache the child's intrinsic content logical height to avoid it being |
2184 // FIXME: This is fragile. LayoutBoxes should be smart enough to determine
their intrinsic content logical | 2229 // reset to the stretched height. |
2185 // height correctly even when there's an overrideHeight. | 2230 // FIXME: This is fragile. LayoutBoxes should be smart enough to |
| 2231 // determine their intrinsic content logical height correctly even when |
| 2232 // there's an overrideHeight. |
2186 LayoutUnit childIntrinsicContentLogicalHeight = | 2233 LayoutUnit childIntrinsicContentLogicalHeight = |
2187 child.intrinsicContentLogicalHeight(); | 2234 child.intrinsicContentLogicalHeight(); |
2188 child.forceChildLayout(); | 2235 child.forceChildLayout(); |
2189 child.setIntrinsicContentLogicalHeight( | 2236 child.setIntrinsicContentLogicalHeight( |
2190 childIntrinsicContentLogicalHeight); | 2237 childIntrinsicContentLogicalHeight); |
2191 } | 2238 } |
2192 } else if (hasOrthogonalFlow(child) && | 2239 } else if (hasOrthogonalFlow(child) && |
2193 child.style()->logicalWidth().isAuto()) { | 2240 child.style()->logicalWidth().isAuto()) { |
2194 LayoutUnit childWidth = | 2241 LayoutUnit childWidth = |
2195 (lineCrossAxisExtent - crossAxisMarginExtentForChild(child)) | 2242 (lineCrossAxisExtent - crossAxisMarginExtentForChild(child)) |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2238 LayoutUnit originalOffset = | 2285 LayoutUnit originalOffset = |
2239 lineContexts[lineNumber].crossAxisOffset - crossAxisStartEdge; | 2286 lineContexts[lineNumber].crossAxisOffset - crossAxisStartEdge; |
2240 LayoutUnit newOffset = | 2287 LayoutUnit newOffset = |
2241 contentExtent - originalOffset - lineCrossAxisExtent; | 2288 contentExtent - originalOffset - lineCrossAxisExtent; |
2242 adjustAlignmentForChild(*child, newOffset - originalOffset); | 2289 adjustAlignmentForChild(*child, newOffset - originalOffset); |
2243 } | 2290 } |
2244 } | 2291 } |
2245 } | 2292 } |
2246 | 2293 |
2247 } // namespace blink | 2294 } // namespace blink |
OLD | NEW |