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 |