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 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; | |
|
ojan
2014/01/14 00:34:18
Doesn't this change behavior? Was it always wrong
rhogan
2014/01/14 19:23:01
Yes, it was incorrect not to skip past floats/outo
| |
| 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 |