Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(272)

Side by Side Diff: Source/core/rendering/RenderBlockFlow.cpp

Issue 129873004: RenderBlock::isSelfCollapsingBlock() should only be used when an object does not require layout. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Update Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698