Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 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 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 396 ASSERT(isInlineBlockOrInlineTable() || !isInline()); | 396 ASSERT(isInlineBlockOrInlineTable() || !isInline()); |
| 397 | 397 |
| 398 if (!relayoutChildren && simplifiedLayout()) | 398 if (!relayoutChildren && simplifiedLayout()) |
| 399 return; | 399 return; |
| 400 | 400 |
| 401 LayoutAnalyzer::BlockScope analyzer(*this); | 401 LayoutAnalyzer::BlockScope analyzer(*this); |
| 402 SubtreeLayoutScope layoutScope(*this); | 402 SubtreeLayoutScope layoutScope(*this); |
| 403 | 403 |
| 404 // Multiple passes might be required for column based layout. | 404 // Multiple passes might be required for column based layout. |
| 405 // The number of passes could be as high as the number of columns. | 405 // The number of passes could be as high as the number of columns. |
| 406 bool done = false; | 406 LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread(); |
| 407 while (!done) | 407 do { |
| 408 done = layoutBlockFlow(relayoutChildren, layoutScope); | 408 layoutBlockFlow(relayoutChildren, layoutScope); |
| 409 | |
| 410 if (flowThread && flowThread->columnHeightsChanged()) { | |
| 411 setChildNeedsLayout(MarkOnlyThis); | |
| 412 continue; | |
| 413 } | |
| 414 | |
| 415 if (shouldBreakAtLineToAvoidWidow()) { | |
| 416 setEverHadLayout(); | |
| 417 continue; | |
| 418 } | |
| 419 break; | |
| 420 } while (true); | |
| 409 | 421 |
| 410 updateLayerTransformAfterLayout(); | 422 updateLayerTransformAfterLayout(); |
| 411 | 423 |
| 412 updateAfterLayout(); | 424 updateAfterLayout(); |
| 413 | 425 |
| 414 if (isHTMLDialogElement(node()) && isOutOfFlowPositioned()) | 426 if (isHTMLDialogElement(node()) && isOutOfFlowPositioned()) |
| 415 positionDialog(); | 427 positionDialog(); |
| 416 | 428 |
| 417 clearNeedsLayout(); | 429 clearNeedsLayout(); |
| 418 updateIsSelfCollapsing(); | 430 updateIsSelfCollapsing(); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 455 // exists *between* in-flow siblings (i.e. not before the first child and | 467 // exists *between* in-flow siblings (i.e. not before the first child and |
| 456 // not after the last child). | 468 // not after the last child). |
| 457 // | 469 // |
| 458 // [1] https://drafts.csswg.org/css-break/#possible-breaks | 470 // [1] https://drafts.csswg.org/css-break/#possible-breaks |
| 459 setBreakBefore(LayoutBlock::breakBefore()); | 471 setBreakBefore(LayoutBlock::breakBefore()); |
| 460 setBreakAfter(LayoutBlock::breakAfter()); | 472 setBreakAfter(LayoutBlock::breakAfter()); |
| 461 } | 473 } |
| 462 } | 474 } |
| 463 | 475 |
| 464 DISABLE_CFI_PERF | 476 DISABLE_CFI_PERF |
| 465 inline bool LayoutBlockFlow::layoutBlockFlow(bool relayoutChildren, | 477 inline void LayoutBlockFlow::layoutBlockFlow(bool relayoutChildren, |
| 466 SubtreeLayoutScope& layoutScope) { | 478 SubtreeLayoutScope& layoutScope) { |
| 467 LayoutUnit oldLeft = logicalLeft(); | 479 LayoutUnit oldLeft = logicalLeft(); |
| 468 bool logicalWidthChanged = updateLogicalWidthAndColumnWidth(); | 480 bool logicalWidthChanged = updateLogicalWidthAndColumnWidth(); |
| 469 relayoutChildren |= logicalWidthChanged; | 481 relayoutChildren |= logicalWidthChanged; |
| 470 | 482 |
| 471 LayoutState state(*this, logicalWidthChanged); | 483 LayoutState state(*this, logicalWidthChanged); |
| 472 | 484 |
| 473 if (m_paginationStateChanged) { | 485 if (m_paginationStateChanged) { |
| 474 // We now need a deep layout to clean up struts after pagination, if we | 486 // We now need a deep layout to clean up struts after pagination, if we |
| 475 // just ceased to be paginated, or, if we just became paginated on the | 487 // just ceased to be paginated, or, if we just became paginated on the |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 496 layoutBlockChildren(relayoutChildren, layoutScope, beforeEdge, afterEdge); | 508 layoutBlockChildren(relayoutChildren, layoutScope, beforeEdge, afterEdge); |
| 497 | 509 |
| 498 bool preferredLogicalWidthsBecameDirty = | 510 bool preferredLogicalWidthsBecameDirty = |
| 499 !preferredLogicalWidthsWereDirty && preferredLogicalWidthsDirty(); | 511 !preferredLogicalWidthsWereDirty && preferredLogicalWidthsDirty(); |
| 500 if (preferredLogicalWidthsBecameDirty) { | 512 if (preferredLogicalWidthsBecameDirty) { |
| 501 // The only thing that should dirty preferred widths at this point is the | 513 // The only thing that should dirty preferred widths at this point is the |
| 502 // addition of overflow:auto scrollbars in a descendant. To avoid a | 514 // addition of overflow:auto scrollbars in a descendant. To avoid a |
| 503 // potential infinite loop, run layout again with auto scrollbars frozen in | 515 // potential infinite loop, run layout again with auto scrollbars frozen in |
| 504 // their current state. | 516 // their current state. |
| 505 PaintLayerScrollableArea::FreezeScrollbarsScope freezeScrollbars; | 517 PaintLayerScrollableArea::FreezeScrollbarsScope freezeScrollbars; |
| 506 return layoutBlockFlow(relayoutChildren, layoutScope); | 518 layoutBlockFlow(relayoutChildren, layoutScope); |
|
szager1
2016/12/01 17:43:24
Please add:
DCHECK(preferredLogicalWidthsWereDirt
mstensho (USE GERRIT)
2016/12/01 18:11:47
We can be pretty sure that !preferredLogicalWidths
mstensho (USE GERRIT)
2016/12/01 19:15:34
Hmm... scrollbars/overflow-auto-infinite-loop.html
szager1
2016/12/01 20:30:12
There's a reason why I added preferredLogicalWidth
mstensho (USE GERRIT)
2016/12/01 20:36:10
But we only get here if preferredLogicalWidthsBeca
| |
| 519 return; | |
| 507 } | 520 } |
| 508 | 521 |
| 509 // Expand our intrinsic height to encompass floats. | 522 // Expand our intrinsic height to encompass floats. |
| 510 if (lowestFloatLogicalBottom() > (logicalHeight() - afterEdge) && | 523 if (lowestFloatLogicalBottom() > (logicalHeight() - afterEdge) && |
| 511 createsNewFormattingContext()) | 524 createsNewFormattingContext()) |
| 512 setLogicalHeight(lowestFloatLogicalBottom() + afterEdge); | 525 setLogicalHeight(lowestFloatLogicalBottom() + afterEdge); |
| 513 | 526 |
| 514 if (LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread()) { | |
| 515 if (flowThread->columnHeightsChanged()) { | |
| 516 setChildNeedsLayout(MarkOnlyThis); | |
| 517 return false; | |
| 518 } | |
| 519 } | |
| 520 | |
| 521 if (shouldBreakAtLineToAvoidWidow()) { | |
| 522 setEverHadLayout(); | |
| 523 return false; | |
| 524 } | |
| 525 | |
| 526 // Remember the automatic logical height we got from laying out the children. | 527 // Remember the automatic logical height we got from laying out the children. |
| 527 LayoutUnit unconstrainedHeight = logicalHeight(); | 528 LayoutUnit unconstrainedHeight = logicalHeight(); |
| 528 LayoutUnit unconstrainedClientAfterEdge = clientLogicalBottom(); | 529 LayoutUnit unconstrainedClientAfterEdge = clientLogicalBottom(); |
| 529 | 530 |
| 530 // Adjust logical height to satisfy whatever computed style requires. | 531 // Adjust logical height to satisfy whatever computed style requires. |
| 531 updateLogicalHeight(); | 532 updateLogicalHeight(); |
| 532 | 533 |
| 533 if (!childrenInline()) | 534 if (!childrenInline()) |
| 534 addOverhangingFloatsFromChildren(unconstrainedHeight); | 535 addOverhangingFloatsFromChildren(unconstrainedHeight); |
| 535 | 536 |
| 536 if (previousHeight != logicalHeight() || isDocumentElement()) | 537 if (previousHeight != logicalHeight() || isDocumentElement()) |
| 537 relayoutChildren = true; | 538 relayoutChildren = true; |
| 538 | 539 |
| 539 PositionedLayoutBehavior behavior = DefaultLayout; | 540 PositionedLayoutBehavior behavior = DefaultLayout; |
| 540 if (oldLeft != logicalLeft()) | 541 if (oldLeft != logicalLeft()) |
| 541 behavior = ForcedLayoutAfterContainingBlockMoved; | 542 behavior = ForcedLayoutAfterContainingBlockMoved; |
| 542 layoutPositionedObjects(relayoutChildren, behavior); | 543 layoutPositionedObjects(relayoutChildren, behavior); |
| 543 | 544 |
| 544 // Add overflow from children (unless we're multi-column, since in that case | 545 // Add overflow from children (unless we're multi-column, since in that case |
| 545 // all our child overflow is clipped anyway). | 546 // all our child overflow is clipped anyway). |
| 546 computeOverflow(unconstrainedClientAfterEdge); | 547 computeOverflow(unconstrainedClientAfterEdge); |
| 547 | 548 |
| 548 m_descendantsWithFloatsMarkedForLayout = false; | 549 m_descendantsWithFloatsMarkedForLayout = false; |
| 549 return true; | |
| 550 } | 550 } |
| 551 | 551 |
| 552 void LayoutBlockFlow::addOverhangingFloatsFromChildren( | 552 void LayoutBlockFlow::addOverhangingFloatsFromChildren( |
| 553 LayoutUnit unconstrainedHeight) { | 553 LayoutUnit unconstrainedHeight) { |
| 554 LayoutBlockFlow* lowestBlock = nullptr; | 554 LayoutBlockFlow* lowestBlock = nullptr; |
| 555 bool addedOverhangingFloats = false; | 555 bool addedOverhangingFloats = false; |
| 556 // One of our children's floats may have become an overhanging float for us. | 556 // One of our children's floats may have become an overhanging float for us. |
| 557 for (LayoutObject* child = lastChild(); child; | 557 for (LayoutObject* child = lastChild(); child; |
| 558 child = child->previousSibling()) { | 558 child = child->previousSibling()) { |
| 559 // TODO(robhogan): We should exclude blocks that create formatting | 559 // TODO(robhogan): We should exclude blocks that create formatting |
| (...skipping 3981 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4541 return LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState); | 4541 return LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState); |
| 4542 } | 4542 } |
| 4543 | 4543 |
| 4544 void LayoutBlockFlow::invalidateDisplayItemClients( | 4544 void LayoutBlockFlow::invalidateDisplayItemClients( |
| 4545 PaintInvalidationReason invalidationReason) const { | 4545 PaintInvalidationReason invalidationReason) const { |
| 4546 BlockFlowPaintInvalidator(*this).invalidateDisplayItemClients( | 4546 BlockFlowPaintInvalidator(*this).invalidateDisplayItemClients( |
| 4547 invalidationReason); | 4547 invalidationReason); |
| 4548 } | 4548 } |
| 4549 | 4549 |
| 4550 } // namespace blink | 4550 } // namespace blink |
| OLD | NEW |