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 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
569 setChildNeedsLayout(MarkOnlyThis); | 569 setChildNeedsLayout(MarkOnlyThis); |
570 return false; | 570 return false; |
571 } | 571 } |
572 } | 572 } |
573 | 573 |
574 if (shouldBreakAtLineToAvoidWidow()) { | 574 if (shouldBreakAtLineToAvoidWidow()) { |
575 setEverHadLayout(); | 575 setEverHadLayout(); |
576 return false; | 576 return false; |
577 } | 577 } |
578 | 578 |
579 // Calculate our new height. | 579 // Remember the automatic logical height we got from laying out the children. |
580 LayoutUnit oldHeight = logicalHeight(); | 580 LayoutUnit unconstrainedHeight = logicalHeight(); |
581 LayoutUnit oldClientAfterEdge = clientLogicalBottom(); | 581 LayoutUnit unconstrainedClientAfterEdge = clientLogicalBottom(); |
582 | 582 |
| 583 // Adjust logical height to satisfy whatever computed style requires. |
583 updateLogicalHeight(); | 584 updateLogicalHeight(); |
584 LayoutUnit newHeight = logicalHeight(); | |
585 if (!childrenInline()) { | |
586 LayoutBlockFlow* lowestBlock = nullptr; | |
587 bool addedOverhangingFloats = false; | |
588 // One of our children's floats may have become an overhanging float for us. | |
589 for (LayoutObject* child = lastChild(); child; | |
590 child = child->previousSibling()) { | |
591 // TODO(robhogan): We should exclude blocks that create formatting | |
592 // contexts, not just out of flow or floating blocks. | |
593 if (child->isLayoutBlockFlow() && | |
594 !child->isFloatingOrOutOfFlowPositioned()) { | |
595 LayoutBlockFlow* block = toLayoutBlockFlow(child); | |
596 if (!block->containsFloats()) | |
597 continue; | |
598 lowestBlock = block; | |
599 if (oldHeight <= newHeight || | |
600 block->lowestFloatLogicalBottom() + block->logicalTop() <= | |
601 newHeight) | |
602 break; | |
603 addOverhangingFloats(block, false); | |
604 addedOverhangingFloats = true; | |
605 } | |
606 } | |
607 // If we have no overhanging floats we still pass a record of the lowest | |
608 // non-overhanging float up the tree so we can enclose it if we are a | |
609 // formatting context and allow siblings to avoid it if they have negative | |
610 // margin and find themselves in its vicinity. | |
611 if (!addedOverhangingFloats) | |
612 addLowestFloatFromChildren(lowestBlock); | |
613 } | |
614 | 585 |
615 bool heightChanged = (previousHeight != newHeight); | 586 if (!childrenInline()) |
616 if (heightChanged) | 587 addOverhangingFloatsFromChildren(unconstrainedHeight); |
| 588 |
| 589 if (previousHeight != logicalHeight() || isDocumentElement()) |
617 relayoutChildren = true; | 590 relayoutChildren = true; |
618 | 591 |
619 layoutPositionedObjects(relayoutChildren || isDocumentElement(), | 592 PositionedLayoutBehavior behavior = DefaultLayout; |
620 oldLeft != logicalLeft() | 593 if (oldLeft != logicalLeft()) |
621 ? ForcedLayoutAfterContainingBlockMoved | 594 behavior = ForcedLayoutAfterContainingBlockMoved; |
622 : DefaultLayout); | 595 layoutPositionedObjects(relayoutChildren, behavior); |
623 | 596 |
624 // Add overflow from children (unless we're multi-column, since in that case | 597 // Add overflow from children (unless we're multi-column, since in that case |
625 // all our child overflow is clipped anyway). | 598 // all our child overflow is clipped anyway). |
626 computeOverflow(oldClientAfterEdge); | 599 computeOverflow(unconstrainedClientAfterEdge); |
627 | 600 |
628 m_descendantsWithFloatsMarkedForLayout = false; | 601 m_descendantsWithFloatsMarkedForLayout = false; |
629 return true; | 602 return true; |
630 } | 603 } |
631 | 604 |
| 605 void LayoutBlockFlow::addOverhangingFloatsFromChildren( |
| 606 LayoutUnit unconstrainedHeight) { |
| 607 LayoutBlockFlow* lowestBlock = nullptr; |
| 608 bool addedOverhangingFloats = false; |
| 609 // One of our children's floats may have become an overhanging float for us. |
| 610 for (LayoutObject* child = lastChild(); child; |
| 611 child = child->previousSibling()) { |
| 612 // TODO(robhogan): We should exclude blocks that create formatting |
| 613 // contexts, not just out of flow or floating blocks. |
| 614 if (child->isLayoutBlockFlow() && |
| 615 !child->isFloatingOrOutOfFlowPositioned()) { |
| 616 LayoutBlockFlow* block = toLayoutBlockFlow(child); |
| 617 if (!block->containsFloats()) |
| 618 continue; |
| 619 lowestBlock = block; |
| 620 if (unconstrainedHeight <= logicalHeight()) |
| 621 break; |
| 622 LayoutUnit logicalBottom = |
| 623 block->logicalTop() + block->lowestFloatLogicalBottom(); |
| 624 if (logicalBottom <= logicalHeight()) |
| 625 break; |
| 626 addOverhangingFloats(block, false); |
| 627 addedOverhangingFloats = true; |
| 628 } |
| 629 } |
| 630 // If we have no overhanging floats we still pass a record of the lowest |
| 631 // non-overhanging float up the tree so we can enclose it if we are a |
| 632 // formatting context and allow siblings to avoid it if they have negative |
| 633 // margin and find themselves in its vicinity. |
| 634 if (!addedOverhangingFloats) |
| 635 addLowestFloatFromChildren(lowestBlock); |
| 636 } |
| 637 |
632 void LayoutBlockFlow::addLowestFloatFromChildren(LayoutBlockFlow* block) { | 638 void LayoutBlockFlow::addLowestFloatFromChildren(LayoutBlockFlow* block) { |
633 // TODO(robhogan): Make createsNewFormattingContext an ASSERT. | 639 // TODO(robhogan): Make createsNewFormattingContext an ASSERT. |
634 if (!block || !block->containsFloats() || | 640 if (!block || !block->containsFloats() || |
635 block->createsNewFormattingContext()) | 641 block->createsNewFormattingContext()) |
636 return; | 642 return; |
637 | 643 |
638 FloatingObject* floatingObject = | 644 FloatingObject* floatingObject = |
639 block->m_floatingObjects->lowestFloatingObject(); | 645 block->m_floatingObjects->lowestFloatingObject(); |
640 if (!floatingObject || containsFloat(floatingObject->layoutObject())) | 646 if (!floatingObject || containsFloat(floatingObject->layoutObject())) |
641 return; | 647 return; |
(...skipping 3909 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4551 return LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState); | 4557 return LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState); |
4552 } | 4558 } |
4553 | 4559 |
4554 void LayoutBlockFlow::invalidateDisplayItemClients( | 4560 void LayoutBlockFlow::invalidateDisplayItemClients( |
4555 PaintInvalidationReason invalidationReason) const { | 4561 PaintInvalidationReason invalidationReason) const { |
4556 BlockFlowPaintInvalidator(*this).invalidateDisplayItemClients( | 4562 BlockFlowPaintInvalidator(*this).invalidateDisplayItemClients( |
4557 invalidationReason); | 4563 invalidationReason); |
4558 } | 4564 } |
4559 | 4565 |
4560 } // namespace blink | 4566 } // namespace blink |
OLD | NEW |