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 786 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
797 | 797 |
798 // Fieldsets need to find their legend and position it inside the border of
the object. | 798 // Fieldsets need to find their legend and position it inside the border of
the object. |
799 // The legend then gets skipped during normal layout. The same is true for r
uby text. | 799 // The legend then gets skipped during normal layout. The same is true for r
uby text. |
800 // It doesn't get included in the normal layout process but is instead skipp
ed. | 800 // It doesn't get included in the normal layout process but is instead skipp
ed. |
801 RenderObject* childToExclude = layoutSpecialExcludedChild(relayoutChildren,
layoutScope); | 801 RenderObject* childToExclude = layoutSpecialExcludedChild(relayoutChildren,
layoutScope); |
802 | 802 |
803 LayoutUnit previousFloatLogicalBottom = 0; | 803 LayoutUnit previousFloatLogicalBottom = 0; |
804 maxFloatLogicalBottom = 0; | 804 maxFloatLogicalBottom = 0; |
805 | 805 |
806 RenderBox* next = firstChildBox(); | 806 RenderBox* next = firstChildBox(); |
| 807 RenderBox* lastNormalFlowChild = 0; |
807 | 808 |
808 while (next) { | 809 while (next) { |
809 RenderBox* child = next; | 810 RenderBox* child = next; |
810 next = child->nextSiblingBox(); | 811 next = child->nextSiblingBox(); |
811 | 812 |
812 LayoutRectRecorder recorder(*child); | 813 LayoutRectRecorder recorder(*child); |
813 | 814 |
814 if (childToExclude == child) | 815 if (childToExclude == child) |
815 continue; // Skip this child, since it will be positioned by the spe
cialized subclass (fieldsets and ruby runs). | 816 continue; // Skip this child, since it will be positioned by the spe
cialized subclass (fieldsets and ruby runs). |
816 | 817 |
817 updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, child); | 818 updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, child); |
818 | 819 |
819 if (child->isOutOfFlowPositioned()) { | 820 if (child->isOutOfFlowPositioned()) { |
820 child->containingBlock()->insertPositionedObject(child); | 821 child->containingBlock()->insertPositionedObject(child); |
821 adjustPositionedBlock(child, marginInfo); | 822 adjustPositionedBlock(child, marginInfo); |
822 continue; | 823 continue; |
823 } | 824 } |
824 if (child->isFloating()) { | 825 if (child->isFloating()) { |
825 insertFloatingObject(child); | 826 insertFloatingObject(child); |
826 adjustFloatingBlock(marginInfo); | 827 adjustFloatingBlock(marginInfo); |
827 continue; | 828 continue; |
828 } | 829 } |
829 | 830 |
830 // Lay out the child. | 831 // Lay out the child. |
831 layoutBlockChild(child, marginInfo, previousFloatLogicalBottom, maxFloat
LogicalBottom); | 832 layoutBlockChild(child, marginInfo, previousFloatLogicalBottom, maxFloat
LogicalBottom); |
| 833 lastNormalFlowChild = child; |
832 | 834 |
833 // If doing a partial layout and the child was the target renderer, earl
y exit here. | 835 // If doing a partial layout and the child was the target renderer, earl
y exit here. |
834 if (frameView()->partialLayout().checkPartialLayoutComplete(child)) | 836 if (frameView()->partialLayout().checkPartialLayoutComplete(child)) |
835 break; | 837 return; |
| 838 |
836 } | 839 } |
837 | 840 |
838 // Now do the handling of the bottom of the block, adding in our bottom bord
er/padding and | 841 // Now do the handling of the bottom of the block, adding in our bottom bord
er/padding and |
839 // determining the correct collapsed bottom margin information. | 842 // determining the correct collapsed bottom margin information. |
840 handleAfterSideOfBlock(beforeEdge, afterEdge, marginInfo); | 843 handleAfterSideOfBlock(lastNormalFlowChild, beforeEdge, afterEdge, marginInf
o); |
841 } | 844 } |
842 | 845 |
843 // Our MarginInfo state used when laying out block children. | 846 // Our MarginInfo state used when laying out block children. |
844 MarginInfo::MarginInfo(RenderBlockFlow* blockFlow, LayoutUnit beforeBorderPaddin
g, LayoutUnit afterBorderPadding) | 847 MarginInfo::MarginInfo(RenderBlockFlow* blockFlow, LayoutUnit beforeBorderPaddin
g, LayoutUnit afterBorderPadding) |
845 : m_canCollapseMarginAfterWithLastChild(true) | 848 : m_canCollapseMarginAfterWithLastChild(true) |
846 , m_atBeforeSideOfBlock(true) | 849 , m_atBeforeSideOfBlock(true) |
847 , m_atAfterSideOfBlock(false) | 850 , m_atAfterSideOfBlock(false) |
848 , m_hasMarginBeforeQuirk(false) | 851 , m_hasMarginBeforeQuirk(false) |
849 , m_hasMarginAfterQuirk(false) | 852 , m_hasMarginAfterQuirk(false) |
850 , m_determinedMarginBeforeQuirk(false) | 853 , m_determinedMarginBeforeQuirk(false) |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
999 } | 1002 } |
1000 | 1003 |
1001 if (marginInfo.quirkContainer() && marginInfo.atBeforeSideOfBlock() && (posT
op - negTop)) | 1004 if (marginInfo.quirkContainer() && marginInfo.atBeforeSideOfBlock() && (posT
op - negTop)) |
1002 marginInfo.setHasMarginBeforeQuirk(topQuirk); | 1005 marginInfo.setHasMarginBeforeQuirk(topQuirk); |
1003 | 1006 |
1004 LayoutUnit beforeCollapseLogicalTop = logicalHeight(); | 1007 LayoutUnit beforeCollapseLogicalTop = logicalHeight(); |
1005 LayoutUnit logicalTop = beforeCollapseLogicalTop; | 1008 LayoutUnit logicalTop = beforeCollapseLogicalTop; |
1006 | 1009 |
1007 LayoutUnit clearanceForSelfCollapsingBlock; | 1010 LayoutUnit clearanceForSelfCollapsingBlock; |
1008 RenderObject* prev = child->previousSibling(); | 1011 RenderObject* prev = child->previousSibling(); |
| 1012 RenderBlockFlow* previousBlockFlow = prev && prev->isRenderBlockFlow() && !
prev->isFloatingOrOutOfFlowPositioned() ? toRenderBlockFlow(prev) : 0; |
1009 // If the child's previous sibling is a self-collapsing block that cleared a
float then its top border edge has been set at the bottom border edge | 1013 // If the child's previous sibling is a self-collapsing block that cleared a
float then its top border edge has been set at the bottom border edge |
1010 // of the float. Since we want to collapse the child's top margin with the s
elf-collapsing block's top and bottom margins we need to adjust our parent's hei
ght to match the | 1014 // of the float. Since we want to collapse the child's top margin with the s
elf-collapsing block's top and bottom margins we need to adjust our parent's hei
ght to match the |
1011 // margin top of the self-collapsing block. If the resulting collapsed margi
n leaves the child still intruding into the float then we will want to clear it. | 1015 // margin top of the self-collapsing block. If the resulting collapsed margi
n leaves the child still intruding into the float then we will want to clear it. |
1012 if (!marginInfo.canCollapseWithMarginBefore() && prev && prev->isRenderBlock
Flow() && toRenderBlockFlow(prev)->isSelfCollapsingBlock()) { | 1016 if (!marginInfo.canCollapseWithMarginBefore() && previousBlockFlow && previo
usBlockFlow->isSelfCollapsingBlock()) { |
1013 clearanceForSelfCollapsingBlock = toRenderBlockFlow(prev)->marginOffsetF
orSelfCollapsingBlock(); | 1017 clearanceForSelfCollapsingBlock = previousBlockFlow->marginOffsetForSelf
CollapsingBlock(); |
1014 setLogicalHeight(logicalHeight() - clearanceForSelfCollapsingBlock); | 1018 setLogicalHeight(logicalHeight() - clearanceForSelfCollapsingBlock); |
1015 } | 1019 } |
1016 | 1020 |
1017 if (childIsSelfCollapsing) { | 1021 if (childIsSelfCollapsing) { |
1018 // For a self collapsing block both the before and after margins get dis
carded. The block doesn't contribute anything to the height of the block. | 1022 // For a self collapsing block both the before and after margins get dis
carded. The block doesn't contribute anything to the height of the block. |
1019 // Also, the child's top position equals the logical height of the conta
iner. | 1023 // Also, the child's top position equals the logical height of the conta
iner. |
1020 if (!childDiscardMarginBefore && !marginInfo.discardMargin()) { | 1024 if (!childDiscardMarginBefore && !marginInfo.discardMargin()) { |
1021 // This child has no height. We need to compute our | 1025 // This child has no height. We need to compute our |
1022 // position before we collapse the child's margins together, | 1026 // position before we collapse the child's margins together, |
1023 // so that we can get an accurate position for the zero-height block
. | 1027 // so that we can get an accurate position for the zero-height block
. |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1072 // If margins would pull us past the top of the next page, then we need to p
ull back and pretend like the margins | 1076 // If margins would pull us past the top of the next page, then we need to p
ull back and pretend like the margins |
1073 // collapsed into the page edge. | 1077 // collapsed into the page edge. |
1074 LayoutState* layoutState = view()->layoutState(); | 1078 LayoutState* layoutState = view()->layoutState(); |
1075 if (layoutState->isPaginated() && layoutState->pageLogicalHeight() && logica
lTop > beforeCollapseLogicalTop | 1079 if (layoutState->isPaginated() && layoutState->pageLogicalHeight() && logica
lTop > beforeCollapseLogicalTop |
1076 && hasNextPage(beforeCollapseLogicalTop)) { | 1080 && hasNextPage(beforeCollapseLogicalTop)) { |
1077 LayoutUnit oldLogicalTop = logicalTop; | 1081 LayoutUnit oldLogicalTop = logicalTop; |
1078 logicalTop = min(logicalTop, nextPageLogicalTop(beforeCollapseLogicalTop
)); | 1082 logicalTop = min(logicalTop, nextPageLogicalTop(beforeCollapseLogicalTop
)); |
1079 setLogicalHeight(logicalHeight() + (logicalTop - oldLogicalTop)); | 1083 setLogicalHeight(logicalHeight() + (logicalTop - oldLogicalTop)); |
1080 } | 1084 } |
1081 | 1085 |
1082 if (prev && prev->isRenderBlockFlow() && !prev->isFloatingOrOutOfFlowPositio
ned()) { | 1086 if (previousBlockFlow) { |
1083 // If |child| is a self-collapsing block it may have collapsed into a pr
evious sibling and although it hasn't reduced the height of the parent yet | 1087 // If |child| is a self-collapsing block it may have collapsed into a pr
evious sibling and although it hasn't reduced the height of the parent yet |
1084 // any floats from the parent will now overhang. | 1088 // any floats from the parent will now overhang. |
1085 RenderBlockFlow* blockFlow = toRenderBlockFlow(prev); | |
1086 LayoutUnit oldLogicalHeight = logicalHeight(); | 1089 LayoutUnit oldLogicalHeight = logicalHeight(); |
1087 setLogicalHeight(logicalTop); | 1090 setLogicalHeight(logicalTop); |
1088 if (blockFlow->containsFloats() && !blockFlow->avoidsFloats() && (blockF
low->logicalTop() + blockFlow->lowestFloatLogicalBottom()) > logicalTop) | 1091 if (previousBlockFlow->containsFloats() && !previousBlockFlow->avoidsFlo
ats() && (previousBlockFlow->logicalTop() + previousBlockFlow->lowestFloatLogica
lBottom()) > logicalTop) |
1089 addOverhangingFloats(blockFlow, false); | 1092 addOverhangingFloats(previousBlockFlow, false); |
1090 setLogicalHeight(oldLogicalHeight); | 1093 setLogicalHeight(oldLogicalHeight); |
1091 | 1094 |
1092 // If |child|'s previous sibling is a self-collapsing block that cleared
a float and margin collapsing resulted in |child| moving up | 1095 // If |child|'s previous sibling is a self-collapsing block that cleared
a float and margin collapsing resulted in |child| moving up |
1093 // into the margin area of the self-collapsing block then the float it c
lears is now intruding into |child|. Layout again so that we can look for | 1096 // into the margin area of the self-collapsing block then the float it c
lears is now intruding into |child|. Layout again so that we can look for |
1094 // floats in the parent that overhang |child|'s new logical top. | 1097 // floats in the parent that overhang |child|'s new logical top. |
1095 bool logicalTopIntrudesIntoFloat = clearanceForSelfCollapsingBlock > 0 &
& logicalTop < beforeCollapseLogicalTop; | 1098 bool logicalTopIntrudesIntoFloat = clearanceForSelfCollapsingBlock > 0 &
& logicalTop < beforeCollapseLogicalTop; |
1096 if (logicalTopIntrudesIntoFloat && containsFloats() && !child->avoidsFlo
ats() && lowestFloatLogicalBottom() > logicalTop) | 1099 if (logicalTopIntrudesIntoFloat && containsFloats() && !child->avoidsFlo
ats() && lowestFloatLogicalBottom() > logicalTop) |
1097 child->setNeedsLayout(); | 1100 child->setNeedsLayout(); |
1098 } | 1101 } |
1099 | 1102 |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1363 // height when computing the position of the float. This condition can be te
sted | 1366 // height when computing the position of the float. This condition can be te
sted |
1364 // for by simply calling canCollapseWithMarginBefore. See | 1367 // for by simply calling canCollapseWithMarginBefore. See |
1365 // http://www.hixie.ch/tests/adhoc/css/box/block/margin-collapse/046.html fo
r | 1368 // http://www.hixie.ch/tests/adhoc/css/box/block/margin-collapse/046.html fo
r |
1366 // an example of this scenario. | 1369 // an example of this scenario. |
1367 LayoutUnit marginOffset = marginInfo.canCollapseWithMarginBefore() ? LayoutU
nit() : marginInfo.margin(); | 1370 LayoutUnit marginOffset = marginInfo.canCollapseWithMarginBefore() ? LayoutU
nit() : marginInfo.margin(); |
1368 setLogicalHeight(logicalHeight() + marginOffset); | 1371 setLogicalHeight(logicalHeight() + marginOffset); |
1369 positionNewFloats(); | 1372 positionNewFloats(); |
1370 setLogicalHeight(logicalHeight() - marginOffset); | 1373 setLogicalHeight(logicalHeight() - marginOffset); |
1371 } | 1374 } |
1372 | 1375 |
1373 void RenderBlockFlow::handleAfterSideOfBlock(LayoutUnit beforeSide, LayoutUnit a
fterSide, MarginInfo& marginInfo) | 1376 void RenderBlockFlow::handleAfterSideOfBlock(RenderBox* lastChild, LayoutUnit be
foreSide, LayoutUnit afterSide, MarginInfo& marginInfo) |
1374 { | 1377 { |
1375 marginInfo.setAtAfterSideOfBlock(true); | 1378 marginInfo.setAtAfterSideOfBlock(true); |
1376 | 1379 |
1377 // If our last child was a self-collapsing block with clearance then our log
ical height is flush with the | 1380 // If our last child was a self-collapsing block with clearance then our log
ical height is flush with the |
1378 // bottom edge of the float that the child clears. The correct vertical posi
tion for the margin-collapsing we want | 1381 // bottom edge of the float that the child clears. The correct vertical posi
tion for the margin-collapsing we want |
1379 // to perform now is at the child's margin-top - so adjust our height to tha
t position. | 1382 // to perform now is at the child's margin-top - so adjust our height to tha
t position. |
1380 RenderObject* child = lastChild(); | 1383 if (lastChild && lastChild->isRenderBlockFlow() && lastChild->isSelfCollapsi
ngBlock()) |
1381 if (child && child->isRenderBlockFlow() && toRenderBlockFlow(child)->isSelfC
ollapsingBlock()) | 1384 setLogicalHeight(logicalHeight() - toRenderBlockFlow(lastChild)->marginO
ffsetForSelfCollapsingBlock()); |
1382 setLogicalHeight(logicalHeight() - toRenderBlockFlow(child)->marginOffse
tForSelfCollapsingBlock()); | |
1383 | 1385 |
1384 if (marginInfo.canCollapseMarginAfterWithChildren() && !marginInfo.canCollap
seMarginAfterWithLastChild()) | 1386 if (marginInfo.canCollapseMarginAfterWithChildren() && !marginInfo.canCollap
seMarginAfterWithLastChild()) |
1385 marginInfo.setCanCollapseMarginAfterWithChildren(false); | 1387 marginInfo.setCanCollapseMarginAfterWithChildren(false); |
1386 | 1388 |
1387 // If we can't collapse with children then go ahead and add in the bottom ma
rgin. | 1389 // If we can't collapse with children then go ahead and add in the bottom ma
rgin. |
1388 if (!marginInfo.discardMargin() && (!marginInfo.canCollapseWithMarginAfter()
&& !marginInfo.canCollapseWithMarginBefore() | 1390 if (!marginInfo.discardMargin() && (!marginInfo.canCollapseWithMarginAfter()
&& !marginInfo.canCollapseWithMarginBefore() |
1389 && (!document().inQuirksMode() || !marginInfo.quirkContainer() || !margi
nInfo.hasMarginAfterQuirk()))) | 1391 && (!document().inQuirksMode() || !marginInfo.quirkContainer() || !margi
nInfo.hasMarginAfterQuirk()))) |
1390 setLogicalHeight(logicalHeight() + marginInfo.margin()); | 1392 setLogicalHeight(logicalHeight() + marginInfo.margin()); |
1391 | 1393 |
1392 // Now add in our bottom border/padding. | 1394 // Now add in our bottom border/padding. |
(...skipping 1412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2805 RenderBlockFlow::RenderBlockFlowRareData& RenderBlockFlow::ensureRareData() | 2807 RenderBlockFlow::RenderBlockFlowRareData& RenderBlockFlow::ensureRareData() |
2806 { | 2808 { |
2807 if (m_rareData) | 2809 if (m_rareData) |
2808 return *m_rareData; | 2810 return *m_rareData; |
2809 | 2811 |
2810 m_rareData = adoptPtr(new RenderBlockFlowRareData(this)); | 2812 m_rareData = adoptPtr(new RenderBlockFlowRareData(this)); |
2811 return *m_rareData; | 2813 return *m_rareData; |
2812 } | 2814 } |
2813 | 2815 |
2814 } // namespace WebCore | 2816 } // namespace WebCore |
OLD | NEW |