Changeset 142974 in webkit
- Timestamp:
- Feb 15, 2013 2:22:27 AM (11 years ago)
- Location:
- trunk
- Files:
-
- 8 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r142971 r142974 1 2013-02-15 Andrei Bucur <abucur@adobe.com> 2 3 Implement the -webkit-margin-collapse properties correct rendering 4 https://bugs.webkit.org/show_bug.cgi?id=108168 5 6 Reviewed by David Hyatt. 7 8 Four new tests covering the -webkit-margin-collapse property basic behavior: collapsing 9 between a block container and its children, collapsing between sibling boxes in both TTB 10 and BTT direction. The last test verifies if a container's before margin correctly resets 11 the discard value after a clear of the child that initally caused it. 12 13 * fast/block/margin-collapse/webkit-margin-collapse-container-expected.html: Added. 14 * fast/block/margin-collapse/webkit-margin-collapse-container.html: Added. 15 * fast/block/margin-collapse/webkit-margin-collapse-floats-expected.html: Added. 16 * fast/block/margin-collapse/webkit-margin-collapse-floats.html: Added. 17 * fast/block/margin-collapse/webkit-margin-collapse-siblings-bt-expected.html: Added. 18 * fast/block/margin-collapse/webkit-margin-collapse-siblings-bt.html: Added. 19 * fast/block/margin-collapse/webkit-margin-collapse-siblings-expected.html: Added. 20 * fast/block/margin-collapse/webkit-margin-collapse-siblings.html: Added. 21 1 22 2013-02-15 KwangYong Choi <ky0.choi@samsung.com> 2 23 -
trunk/Source/WebCore/ChangeLog
r142969 r142974 1 2013-02-15 Andrei Bucur <abucur@adobe.com> 2 3 Implement the -webkit-margin-collapse properties correct rendering 4 https://bugs.webkit.org/show_bug.cgi?id=108168 5 6 Reviewed by David Hyatt. 7 8 The patch implements the correct behavior for the -webkit-margin-collapse properties: 9 - a value of "discard" on a margin will truncate all the margins collapsing with it; 10 - a value of "separate" will prevent the margin to collapse; 11 - a value of "collapse" is the default collapse behavior. 12 13 The implementation is aware of multiple writing-modes: 14 - if the writing mode of a child is parallel with the writing mode of the container and has the same direction, 15 the -webkit-margin-collapse properties on the child are left as is; 16 - if the writing mode of a child is parallel with the writing mode of the container but has a different direction, 17 the -webkit-margin-collapse properties on the child are reversed; 18 - if the writing mode of a child is perpendicular on the writing mode of the container, 19 the -webkit-margin-collapse properties on the child are ignored; 20 21 I. The "discard" value implementation 22 There are two new bits (before and after) added on the RenderBlockRareData structure specifying if the margins 23 of the block will be discarded or not. We can't rely only on the value from style() because 24 it's possible a block to discard it's margins because it has collapsed with a children that 25 specified "discard" for -webkit-margin-collapse. However, the bits are set only if it is 26 required. 27 Another bit is added on the MarginInfo structure specifying if the margin has to be discarded or not. When 28 collapsing at the before side of a block it will hold information if the container block needs to discard 29 or not. If the collapsing happens between siblings/with after side of the container it will tell if the previous 30 child discards the margin or not. The self collapsing blocks are a special case. If any of its margins 31 discards then both its margins discard and all the other margins collapsing with it. 32 To ensure an optimal behavior it is asserted margin values can't be set on the MarginInfo object if the 33 discard flag is active. If this happens it may indicate someone ignored the possibility of the margin being 34 discarded altogether and incorrectly updated the margin values. 35 Float clearing also needs to change because it may force margins to stop collapsing. If this happens the discard 36 flags and margins needs to be restored to their values before the collapse. 37 38 II. The "separate" value implementation 39 The implementation for separate was not changed too much. I've added new accessor methods for the property 40 that take writing mode into consideration and I've removed some code that didn't work correctly in layoutBlockChild. 41 The problem was the marginInfo structure was cleared if the child was specifying the "separate" value for before. 42 This is wrong because you lose the margin information of the previous child/before side. 43 44 Tests: fast/block/margin-collapse/webkit-margin-collapse-container.html 45 fast/block/margin-collapse/webkit-margin-collapse-floats.html 46 fast/block/margin-collapse/webkit-margin-collapse-siblings-bt.html 47 fast/block/margin-collapse/webkit-margin-collapse-siblings.html 48 49 * rendering/RenderBlock.cpp: 50 (WebCore::RenderBlock::MarginInfo::MarginInfo): 51 (WebCore::RenderBlock::layoutBlock): 52 (WebCore::RenderBlock::collapseMargins): 53 (WebCore::RenderBlock::clearFloatsIfNeeded): 54 (WebCore::RenderBlock::marginBeforeEstimateForChild): 55 (WebCore::RenderBlock::estimateLogicalTopPosition): 56 (WebCore::RenderBlock::setCollapsedBottomMargin): 57 (WebCore::RenderBlock::handleAfterSideOfBlock): 58 (WebCore::RenderBlock::layoutBlockChild): 59 (WebCore::RenderBlock::setMustDiscardMarginBefore): 60 (WebCore): 61 (WebCore::RenderBlock::setMustDiscardMarginAfter): 62 (WebCore::RenderBlock::mustDiscardMarginBefore): 63 (WebCore::RenderBlock::mustDiscardMarginAfter): 64 (WebCore::RenderBlock::mustDiscardMarginBeforeForChild): 65 (WebCore::RenderBlock::mustDiscardMarginAfterForChild): 66 (WebCore::RenderBlock::mustSeparateMarginBeforeForChild): 67 (WebCore::RenderBlock::mustSeparateMarginAfterForChild): 68 * rendering/RenderBlock.h: 69 (RenderBlock): 70 (WebCore::RenderBlock::initMaxMarginValues): 71 (MarginInfo): 72 (WebCore::RenderBlock::MarginInfo::setPositiveMargin): 73 (WebCore::RenderBlock::MarginInfo::setNegativeMargin): 74 (WebCore::RenderBlock::MarginInfo::setPositiveMarginIfLarger): 75 (WebCore::RenderBlock::MarginInfo::setNegativeMarginIfLarger): 76 (WebCore::RenderBlock::MarginInfo::setMargin): 77 (WebCore::RenderBlock::MarginInfo::setCanCollapseMarginAfterWithChildren): 78 (WebCore::RenderBlock::MarginInfo::setDiscardMargin): 79 (WebCore::RenderBlock::MarginInfo::discardMargin): 80 (WebCore::RenderBlock::RenderBlockRareData::RenderBlockRareData): 81 (WebCore::RenderBlock::RenderBlockRareData::positiveMarginBeforeDefault): 82 (RenderBlockRareData): 83 * rendering/style/RenderStyle.h: 84 1 85 2013-02-14 Yury Semikhatsky <yurys@chromium.org> 2 86 -
trunk/Source/WebCore/rendering/RenderBlock.cpp
r142922 r142974 170 170 , m_marginAfterQuirk(false) 171 171 , m_determinedMarginBeforeQuirk(false) 172 , m_discardMargin(false) 172 173 { 173 174 RenderStyle* blockStyle = block->style(); … … 187 188 (blockStyle->logicalHeight().isAuto() && !blockStyle->logicalHeight().value()) && blockStyle->marginAfterCollapse() != MSEPARATE; 188 189 189 m_quirkContainer = block->isTableCell() || block->isBody() || blockStyle->marginBeforeCollapse() == MDISCARD 190 || blockStyle->marginAfterCollapse() == MDISCARD; 191 192 m_positiveMargin = m_canCollapseMarginBeforeWithChildren ? block->maxPositiveMarginBefore() : LayoutUnit(); 193 m_negativeMargin = m_canCollapseMarginBeforeWithChildren ? block->maxNegativeMarginBefore() : LayoutUnit(); 190 m_quirkContainer = block->isTableCell() || block->isBody(); 191 192 m_discardMargin = m_canCollapseMarginBeforeWithChildren && block->mustDiscardMarginBefore(); 193 194 m_positiveMargin = (m_canCollapseMarginBeforeWithChildren && !block->mustDiscardMarginBefore()) ? block->maxPositiveMarginBefore() : LayoutUnit(); 195 m_negativeMargin = (m_canCollapseMarginBeforeWithChildren && !block->mustDiscardMarginBefore()) ? block->maxNegativeMarginBefore() : LayoutUnit(); 194 196 } 195 197 … … 1527 1529 initMaxMarginValues(); 1528 1530 1529 setMarginBeforeQuirk(styleToUse-> marginBefore().quirk());1530 setMarginAfterQuirk(styleToUse-> marginAfter().quirk());1531 setMarginBeforeQuirk(styleToUse->isMarginBeforeQuirk()); 1532 setMarginAfterQuirk(styleToUse->isMarginAfterQuirk()); 1531 1533 setPaginationStrut(0); 1532 1534 } … … 1958 1960 LayoutUnit RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo) 1959 1961 { 1962 bool childDiscardMarginBefore = mustDiscardMarginBeforeForChild(child); 1963 bool childDiscardMarginAfter = mustDiscardMarginAfterForChild(child); 1964 bool childIsSelfCollapsing = child->isSelfCollapsingBlock(); 1965 1966 // The child discards the before margin when the the after margin has discard in the case of a self collapsing block. 1967 childDiscardMarginBefore = childDiscardMarginBefore || (childDiscardMarginAfter && childIsSelfCollapsing); 1968 1960 1969 // Get the four margin values for the child and cache them. 1961 1970 const MarginValues childMargins = marginValuesForChild(child); … … 1967 1976 // For self-collapsing blocks, collapse our bottom margins into our 1968 1977 // top to get new posTop and negTop values. 1969 if (child ->isSelfCollapsingBlock()) {1978 if (childIsSelfCollapsing) { 1970 1979 posTop = max(posTop, childMargins.positiveMarginAfter()); 1971 1980 negTop = max(negTop, childMargins.negativeMarginAfter()); … … 1974 1983 // See if the top margin is quirky. We only care if this child has 1975 1984 // margins that will collapse with us. 1976 bool topQuirk = child->isMarginBeforeQuirk() || style()->marginBeforeCollapse() == MDISCARD;1985 bool topQuirk = child->isMarginBeforeQuirk(); 1977 1986 1978 1987 if (marginInfo.canCollapseWithMarginBefore()) { 1979 // This child is collapsing with the top of the 1980 // block. If it has larger margin values, then we need to update 1981 // our own maximal values. 1982 if (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !topQuirk) 1983 setMaxMarginBeforeValues(max(posTop, maxPositiveMarginBefore()), max(negTop, maxNegativeMarginBefore())); 1984 1985 // The minute any of the margins involved isn't a quirk, don't 1986 // collapse it away, even if the margin is smaller (www.webreference.com 1987 // has an example of this, a <dt> with 0.8em author-specified inside 1988 // a <dl> inside a <td>. 1989 if (!marginInfo.determinedMarginBeforeQuirk() && !topQuirk && (posTop - negTop)) { 1990 setMarginBeforeQuirk(false); 1991 marginInfo.setDeterminedMarginBeforeQuirk(true); 1992 } 1993 1994 if (!marginInfo.determinedMarginBeforeQuirk() && topQuirk && !marginBefore()) 1995 // We have no top margin and our top child has a quirky margin. 1996 // We will pick up this quirky margin and pass it through. 1997 // This deals with the <td><div><p> case. 1998 // Don't do this for a block that split two inlines though. You do 1999 // still apply margins in this case. 2000 setMarginBeforeQuirk(true); 1988 if (!childDiscardMarginBefore && !marginInfo.discardMargin()) { 1989 // This child is collapsing with the top of the 1990 // block. If it has larger margin values, then we need to update 1991 // our own maximal values. 1992 if (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !topQuirk) 1993 setMaxMarginBeforeValues(max(posTop, maxPositiveMarginBefore()), max(negTop, maxNegativeMarginBefore())); 1994 1995 // The minute any of the margins involved isn't a quirk, don't 1996 // collapse it away, even if the margin is smaller (www.webreference.com 1997 // has an example of this, a <dt> with 0.8em author-specified inside 1998 // a <dl> inside a <td>. 1999 if (!marginInfo.determinedMarginBeforeQuirk() && !topQuirk && (posTop - negTop)) { 2000 setMarginBeforeQuirk(false); 2001 marginInfo.setDeterminedMarginBeforeQuirk(true); 2002 } 2003 2004 if (!marginInfo.determinedMarginBeforeQuirk() && topQuirk && !marginBefore()) 2005 // We have no top margin and our top child has a quirky margin. 2006 // We will pick up this quirky margin and pass it through. 2007 // This deals with the <td><div><p> case. 2008 // Don't do this for a block that split two inlines though. You do 2009 // still apply margins in this case. 2010 setMarginBeforeQuirk(true); 2011 } else 2012 // The before margin of the container will also discard all the margins it is collapsing with. 2013 setMustDiscardMarginBefore(); 2014 } 2015 2016 // Once we find a child with discardMarginBefore all the margins collapsing with us must also discard. 2017 if (childDiscardMarginBefore) { 2018 marginInfo.setDiscardMargin(true); 2019 marginInfo.clearMargin(); 2001 2020 } 2002 2021 … … 2006 2025 LayoutUnit beforeCollapseLogicalTop = logicalHeight(); 2007 2026 LayoutUnit logicalTop = beforeCollapseLogicalTop; 2008 if (child->isSelfCollapsingBlock()) { 2009 // This child has no height. We need to compute our 2010 // position before we collapse the child's margins together, 2011 // so that we can get an accurate position for the zero-height block. 2012 LayoutUnit collapsedBeforePos = max(marginInfo.positiveMargin(), childMargins.positiveMarginBefore()); 2013 LayoutUnit collapsedBeforeNeg = max(marginInfo.negativeMargin(), childMargins.negativeMarginBefore()); 2014 marginInfo.setMargin(collapsedBeforePos, collapsedBeforeNeg); 2015 2016 // Now collapse the child's margins together, which means examining our 2017 // bottom margin values as well. 2018 marginInfo.setPositiveMarginIfLarger(childMargins.positiveMarginAfter()); 2019 marginInfo.setNegativeMarginIfLarger(childMargins.negativeMarginAfter()); 2020 2021 if (!marginInfo.canCollapseWithMarginBefore()) 2022 // We need to make sure that the position of the self-collapsing block 2023 // is correct, since it could have overflowing content 2024 // that needs to be positioned correctly (e.g., a block that 2025 // had a specified height of 0 but that actually had subcontent). 2026 logicalTop = logicalHeight() + collapsedBeforePos - collapsedBeforeNeg; 2027 } 2028 else { 2029 if (child->style()->marginBeforeCollapse() == MSEPARATE) { 2027 if (childIsSelfCollapsing) { 2028 // For a self collapsing block both the before and after margins get discarded. The block doesn't contribute anything to the height of the block. 2029 // Also, the child's top position equals the logical height of the container. 2030 if (!childDiscardMarginBefore && !marginInfo.discardMargin()) { 2031 // This child has no height. We need to compute our 2032 // position before we collapse the child's margins together, 2033 // so that we can get an accurate position for the zero-height block. 2034 LayoutUnit collapsedBeforePos = max(marginInfo.positiveMargin(), childMargins.positiveMarginBefore()); 2035 LayoutUnit collapsedBeforeNeg = max(marginInfo.negativeMargin(), childMargins.negativeMarginBefore()); 2036 marginInfo.setMargin(collapsedBeforePos, collapsedBeforeNeg); 2037 2038 // Now collapse the child's margins together, which means examining our 2039 // bottom margin values as well. 2040 marginInfo.setPositiveMarginIfLarger(childMargins.positiveMarginAfter()); 2041 marginInfo.setNegativeMarginIfLarger(childMargins.negativeMarginAfter()); 2042 2043 if (!marginInfo.canCollapseWithMarginBefore()) 2044 // We need to make sure that the position of the self-collapsing block 2045 // is correct, since it could have overflowing content 2046 // that needs to be positioned correctly (e.g., a block that 2047 // had a specified height of 0 but that actually had subcontent). 2048 logicalTop = logicalHeight() + collapsedBeforePos - collapsedBeforeNeg; 2049 } 2050 } else { 2051 if (mustSeparateMarginBeforeForChild(child)) { 2052 ASSERT(!marginInfo.discardMargin() || (marginInfo.discardMargin() && !marginInfo.margin())); 2030 2053 setLogicalHeight(logicalHeight() + marginInfo.margin() + marginBeforeForChild(child)); 2031 2054 logicalTop = logicalHeight(); 2032 } 2033 else if (!marginInfo.atBeforeSideOfBlock() || 2034 (!marginInfo.canCollapseMarginBeforeWithChildren() 2035 && (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.marginBeforeQuirk()))) { 2055 } else if (!marginInfo.discardMargin() && (!marginInfo.atBeforeSideOfBlock() 2056 || (!marginInfo.canCollapseMarginBeforeWithChildren() 2057 && (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.marginBeforeQuirk())))) { 2036 2058 // We're collapsing with a previous sibling's margins and not 2037 2059 // with the top of the block. … … 2040 2062 } 2041 2063 2042 marginInfo.setPositiveMargin(childMargins.positiveMarginAfter()); 2043 marginInfo.setNegativeMargin(childMargins.negativeMarginAfter()); 2064 marginInfo.setDiscardMargin(childDiscardMarginAfter); 2065 2066 if (!marginInfo.discardMargin()) { 2067 marginInfo.setPositiveMargin(childMargins.positiveMarginAfter()); 2068 marginInfo.setNegativeMargin(childMargins.negativeMarginAfter()); 2069 } else 2070 marginInfo.clearMargin(); 2044 2071 2045 2072 if (marginInfo.margin()) 2046 marginInfo.setMarginAfterQuirk(child->isMarginAfterQuirk() || style()->marginAfterCollapse() == MDISCARD);2073 marginInfo.setMarginAfterQuirk(child->isMarginAfterQuirk()); 2047 2074 } 2048 2075 … … 2080 2107 2081 2108 if (child->isSelfCollapsingBlock()) { 2109 bool childDiscardMargin = mustDiscardMarginBeforeForChild(child) || mustDiscardMarginAfterForChild(child); 2110 2082 2111 // For self-collapsing blocks that clear, they can still collapse their 2083 2112 // margins with following siblings. Reset the current margins to represent 2084 2113 // the self-collapsing block's margins only. 2085 MarginValues childMargins = marginValuesForChild(child); 2086 marginInfo.setPositiveMargin(max(childMargins.positiveMarginBefore(), childMargins.positiveMarginAfter())); 2087 marginInfo.setNegativeMargin(max(childMargins.negativeMarginBefore(), childMargins.negativeMarginAfter())); 2114 // If DISCARD is specified for -webkit-margin-collapse, reset the margin values. 2115 if (!childDiscardMargin) { 2116 MarginValues childMargins = marginValuesForChild(child); 2117 marginInfo.setPositiveMargin(max(childMargins.positiveMarginBefore(), childMargins.positiveMarginAfter())); 2118 marginInfo.setNegativeMargin(max(childMargins.negativeMarginBefore(), childMargins.negativeMarginAfter())); 2119 } else 2120 marginInfo.clearMargin(); 2121 marginInfo.setDiscardMargin(childDiscardMargin); 2088 2122 2089 2123 // CSS2.1 states: … … 2118 2152 setMaxMarginBeforeValues(oldTopPosMargin, oldTopNegMargin); 2119 2153 marginInfo.setAtBeforeSideOfBlock(false); 2154 2155 // In case the child discarded the before margin of the block we need to reset the mustDiscardMarginBefore flag to the initial value. 2156 setMustDiscardMarginBefore(style()->marginBeforeCollapse() == MDISCARD); 2120 2157 } 2121 2158 … … 2129 2166 } 2130 2167 2131 void RenderBlock::marginBeforeEstimateForChild(RenderBox* child, LayoutUnit& positiveMarginBefore, LayoutUnit& negativeMarginBefore) const 2132 { 2133 // FIXME: We should deal with the margin-collapse-* style extensions that prevent collapsing and that discard margins. 2168 void RenderBlock::marginBeforeEstimateForChild(RenderBox* child, LayoutUnit& positiveMarginBefore, LayoutUnit& negativeMarginBefore, bool& discardMarginBefore) const 2169 { 2134 2170 // Give up if in quirks mode and we're a body/table cell and the top margin of the child box is quirky. 2135 if (document()->inQuirksMode() && child->isMarginBeforeQuirk() && (isTableCell() || isBody())) 2136 return; 2171 // Give up if the child specified -webkit-margin-collapse: separate that prevents collapsing. 2172 // FIXME: Use writing mode independent accessor for marginBeforeCollapse. 2173 if ((document()->inQuirksMode() && child->isMarginBeforeQuirk() && (isTableCell() || isBody())) || child->style()->marginBeforeCollapse() == MSEPARATE) 2174 return; 2175 2176 // The margins are discarded by a child that specified -webkit-margin-collapse: discard. 2177 // FIXME: Use writing mode independent accessor for marginBeforeCollapse. 2178 if (child->style()->marginBeforeCollapse() == MDISCARD) { 2179 positiveMarginBefore = 0; 2180 negativeMarginBefore = 0; 2181 discardMarginBefore = true; 2182 return; 2183 } 2137 2184 2138 2185 LayoutUnit beforeChildMargin = marginBeforeForChild(child); … … 2164 2211 if (grandchildBox->needsLayout()) { 2165 2212 grandchildBox->computeAndSetBlockDirectionMargins(this); 2166 grandchildBox->setMarginBeforeQuirk(grandchildBox->style()-> marginBefore().quirk());2167 grandchildBox->setMarginAfterQuirk(grandchildBox->style()-> marginAfter().quirk());2213 grandchildBox->setMarginBeforeQuirk(grandchildBox->style()->isMarginBeforeQuirk()); 2214 grandchildBox->setMarginAfterQuirk(grandchildBox->style()->isMarginAfterQuirk()); 2168 2215 } 2169 2216 2170 2217 // Collapse the margin of the grandchild box with our own to produce an estimate. 2171 childBlock->marginBeforeEstimateForChild(grandchildBox, positiveMarginBefore, negativeMarginBefore );2218 childBlock->marginBeforeEstimateForChild(grandchildBox, positiveMarginBefore, negativeMarginBefore, discardMarginBefore); 2172 2219 } 2173 2220 … … 2180 2227 LayoutUnit positiveMarginBefore = 0; 2181 2228 LayoutUnit negativeMarginBefore = 0; 2229 bool discardMarginBefore = false; 2182 2230 if (child->selfNeedsLayout()) { 2183 2231 // Try to do a basic estimation of how the collapse is going to go. 2184 marginBeforeEstimateForChild(child, positiveMarginBefore, negativeMarginBefore );2232 marginBeforeEstimateForChild(child, positiveMarginBefore, negativeMarginBefore, discardMarginBefore); 2185 2233 } else { 2186 2234 // Use the cached collapsed margin values from a previous layout. Most of the time they … … 2189 2237 positiveMarginBefore = max(positiveMarginBefore, marginValues.positiveMarginBefore()); 2190 2238 negativeMarginBefore = max(negativeMarginBefore, marginValues.negativeMarginBefore()); 2239 discardMarginBefore = mustDiscardMarginBeforeForChild(child); 2191 2240 } 2192 2241 2193 2242 // Collapse the result with our current margins. 2194 logicalTopEstimate += max(marginInfo.positiveMargin(), positiveMarginBefore) - max(marginInfo.negativeMargin(), negativeMarginBefore); 2243 if (!discardMarginBefore) 2244 logicalTopEstimate += max(marginInfo.positiveMargin(), positiveMarginBefore) - max(marginInfo.negativeMargin(), negativeMarginBefore); 2195 2245 } 2196 2246 … … 2267 2317 { 2268 2318 if (marginInfo.canCollapseWithMarginAfter() && !marginInfo.canCollapseWithMarginBefore()) { 2319 // Update the after side margin of the container to discard if the after margin of the last child also discards and we collapse with it. 2320 // Don't update the max margin values because we won't need them anyway. 2321 if (marginInfo.discardMargin()) { 2322 setMustDiscardMarginAfter(); 2323 return; 2324 } 2325 2269 2326 // Update our max pos/neg bottom margins, since we collapsed our bottom margins 2270 2327 // with our children. … … 2289 2346 // Don't do this for ordinary anonymous blocks as only the enclosing box should add in 2290 2347 // its margin. 2291 if (!marginInfo. canCollapseWithMarginAfter() && !marginInfo.canCollapseWithMarginBefore()2348 if (!marginInfo.discardMargin() && (!marginInfo.canCollapseWithMarginAfter() && !marginInfo.canCollapseWithMarginBefore() 2292 2349 && (!isAnonymousBlock() || isAnonymousColumnsBlock() || isAnonymousColumnSpanBlock()) 2293 && (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.marginAfterQuirk())) 2350 && (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.marginAfterQuirk()))) 2294 2351 setLogicalHeight(logicalHeight() + marginInfo.margin()); 2295 2352 … … 2416 2473 child->computeAndSetBlockDirectionMargins(this); 2417 2474 2418 // Do not allow a collapse if the margin-before-collapse style is set to SEPARATE.2419 RenderStyle* childStyle = child->style();2420 if (childStyle->marginBeforeCollapse() == MSEPARATE) {2421 marginInfo.setAtBeforeSideOfBlock(false);2422 marginInfo.clearMargin();2423 }2424 2425 2475 // Try to guess our correct logical top position. In most cases this guess will 2426 2476 // be correct. Only if we're wrong (when we compute the real logical top position) … … 2516 2566 // Update our height now that the child has been placed in the correct position. 2517 2567 setLogicalHeight(logicalHeight() + logicalHeightForChild(child)); 2518 if ( childStyle->marginAfterCollapse() == MSEPARATE) {2568 if (mustSeparateMarginAfterForChild(child)) { 2519 2569 setLogicalHeight(logicalHeight() + marginAfterForChild(child)); 2520 2570 marginInfo.clearMargin(); … … 6820 6870 } 6821 6871 6872 void RenderBlock::setMustDiscardMarginBefore(bool value) 6873 { 6874 if (style()->marginBeforeCollapse() == MDISCARD) { 6875 ASSERT(value); 6876 return; 6877 } 6878 6879 if (!m_rareData && !value) 6880 return; 6881 6882 if (!m_rareData) 6883 m_rareData = adoptPtr(new RenderBlockRareData(this)); 6884 6885 m_rareData->m_discardMarginBefore = value; 6886 } 6887 6888 void RenderBlock::setMustDiscardMarginAfter(bool value) 6889 { 6890 if (style()->marginAfterCollapse() == MDISCARD) { 6891 ASSERT(value); 6892 return; 6893 } 6894 6895 if (!m_rareData && !value) 6896 return; 6897 6898 if (!m_rareData) 6899 m_rareData = adoptPtr(new RenderBlockRareData(this)); 6900 6901 m_rareData->m_discardMarginAfter = value; 6902 } 6903 6904 bool RenderBlock::mustDiscardMarginBefore() const 6905 { 6906 return style()->marginBeforeCollapse() == MDISCARD || (m_rareData && m_rareData->m_discardMarginBefore); 6907 } 6908 6909 bool RenderBlock::mustDiscardMarginAfter() const 6910 { 6911 return style()->marginAfterCollapse() == MDISCARD || (m_rareData && m_rareData->m_discardMarginAfter); 6912 } 6913 6914 bool RenderBlock::mustDiscardMarginBeforeForChild(const RenderBox* child) const 6915 { 6916 ASSERT(!child->selfNeedsLayout()); 6917 if (!child->isWritingModeRoot()) 6918 return child->isRenderBlock() ? toRenderBlock(child)->mustDiscardMarginBefore() : (child->style()->marginBeforeCollapse() == MDISCARD); 6919 if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) 6920 return child->isRenderBlock() ? toRenderBlock(child)->mustDiscardMarginAfter() : (child->style()->marginAfterCollapse() == MDISCARD); 6921 6922 // FIXME: We return false here because the implementation is not geometrically complete. We have values only for before/after, not start/end. 6923 // In case the boxes are perpendicular we assume the property is not specified. 6924 return false; 6925 } 6926 6927 bool RenderBlock::mustDiscardMarginAfterForChild(const RenderBox* child) const 6928 { 6929 ASSERT(!child->selfNeedsLayout()); 6930 if (!child->isWritingModeRoot()) 6931 return child->isRenderBlock() ? toRenderBlock(child)->mustDiscardMarginAfter() : (child->style()->marginAfterCollapse() == MDISCARD); 6932 if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) 6933 return child->isRenderBlock() ? toRenderBlock(child)->mustDiscardMarginBefore() : (child->style()->marginBeforeCollapse() == MDISCARD); 6934 6935 // FIXME: See |mustDiscardMarginBeforeForChild| above. 6936 return false; 6937 } 6938 6939 bool RenderBlock::mustSeparateMarginBeforeForChild(const RenderBox* child) const 6940 { 6941 ASSERT(!child->selfNeedsLayout()); 6942 const RenderStyle* childStyle = child->style(); 6943 if (!child->isWritingModeRoot()) 6944 return childStyle->marginBeforeCollapse() == MSEPARATE; 6945 if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) 6946 return childStyle->marginAfterCollapse() == MSEPARATE; 6947 6948 // FIXME: See |mustDiscardMarginBeforeForChild| above. 6949 return false; 6950 } 6951 6952 bool RenderBlock::mustSeparateMarginAfterForChild(const RenderBox* child) const 6953 { 6954 ASSERT(!child->selfNeedsLayout()); 6955 const RenderStyle* childStyle = child->style(); 6956 if (!child->isWritingModeRoot()) 6957 return childStyle->marginAfterCollapse() == MSEPARATE; 6958 if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) 6959 return childStyle->marginBeforeCollapse() == MSEPARATE; 6960 6961 // FIXME: See |mustDiscardMarginBeforeForChild| above. 6962 return false; 6963 } 6964 6822 6965 void RenderBlock::setPaginationStrut(LayoutUnit strut) 6823 6966 { -
trunk/Source/WebCore/rendering/RenderBlock.h
r142527 r142974 456 456 void setMaxMarginAfterValues(LayoutUnit pos, LayoutUnit neg); 457 457 458 void setMustDiscardMarginBefore(bool = true); 459 void setMustDiscardMarginAfter(bool = true); 460 461 bool mustDiscardMarginBefore() const; 462 bool mustDiscardMarginAfter() const; 463 464 bool mustDiscardMarginBeforeForChild(const RenderBox*) const; 465 bool mustDiscardMarginAfterForChild(const RenderBox*) const; 466 467 bool mustSeparateMarginBeforeForChild(const RenderBox*) const; 468 bool mustSeparateMarginAfterForChild(const RenderBox*) const; 469 458 470 void initMaxMarginValues() 459 471 { … … 462 474 RenderBlockRareData::positiveMarginAfterDefault(this), RenderBlockRareData::negativeMarginAfterDefault(this)); 463 475 m_rareData->m_paginationStrut = 0; 476 477 m_rareData->m_discardMarginBefore = false; 478 m_rareData->m_discardMarginAfter = false; 464 479 } 465 480 } … … 950 965 bool m_determinedMarginBeforeQuirk : 1; 951 966 967 bool m_discardMargin : 1; 968 952 969 // These flags track the previous maximal positive and negative margins. 953 970 LayoutUnit m_positiveMargin; … … 967 984 void setMarginAfterQuirk(bool b) { m_marginAfterQuirk = b; } 968 985 void setDeterminedMarginBeforeQuirk(bool b) { m_determinedMarginBeforeQuirk = b; } 969 void setPositiveMargin(LayoutUnit p) { m_positiveMargin = p; }970 void setNegativeMargin(LayoutUnit n) { m_negativeMargin = n; }986 void setPositiveMargin(LayoutUnit p) { ASSERT(!m_discardMargin); m_positiveMargin = p; } 987 void setNegativeMargin(LayoutUnit n) { ASSERT(!m_discardMargin); m_negativeMargin = n; } 971 988 void setPositiveMarginIfLarger(LayoutUnit p) 972 989 { 990 ASSERT(!m_discardMargin); 973 991 if (p > m_positiveMargin) 974 992 m_positiveMargin = p; … … 976 994 void setNegativeMarginIfLarger(LayoutUnit n) 977 995 { 996 ASSERT(!m_discardMargin); 978 997 if (n > m_negativeMargin) 979 998 m_negativeMargin = n; 980 999 } 981 1000 982 void setMargin(LayoutUnit p, LayoutUnit n) { m_positiveMargin = p; m_negativeMargin = n; } 1001 void setMargin(LayoutUnit p, LayoutUnit n) { ASSERT(!m_discardMargin); m_positiveMargin = p; m_negativeMargin = n; } 1002 void setCanCollapseMarginAfterWithChildren(bool collapse) { m_canCollapseMarginAfterWithChildren = collapse; } 1003 void setDiscardMargin(bool value) { m_discardMargin = value; } 983 1004 984 1005 bool atBeforeSideOfBlock() const { return m_atBeforeSideOfBlock; } … … 987 1008 bool canCollapseMarginBeforeWithChildren() const { return m_canCollapseMarginBeforeWithChildren; } 988 1009 bool canCollapseMarginAfterWithChildren() const { return m_canCollapseMarginAfterWithChildren; } 989 void setCanCollapseMarginAfterWithChildren(bool collapse) { m_canCollapseMarginAfterWithChildren = collapse; }990 1010 bool quirkContainer() const { return m_quirkContainer; } 991 1011 bool determinedMarginBeforeQuirk() const { return m_determinedMarginBeforeQuirk; } … … 994 1014 LayoutUnit positiveMargin() const { return m_positiveMargin; } 995 1015 LayoutUnit negativeMargin() const { return m_negativeMargin; } 1016 bool discardMargin() const { return m_discardMargin; } 996 1017 LayoutUnit margin() const { return m_positiveMargin - m_negativeMargin; } 997 1018 }; … … 1011 1032 LayoutUnit clearFloatsIfNeeded(RenderBox* child, MarginInfo&, LayoutUnit oldTopPosMargin, LayoutUnit oldTopNegMargin, LayoutUnit yPos); 1012 1033 LayoutUnit estimateLogicalTopPosition(RenderBox* child, const MarginInfo&, LayoutUnit& estimateWithoutPagination); 1013 void marginBeforeEstimateForChild(RenderBox* child, LayoutUnit& positiveMarginBefore, LayoutUnit& negativeMarginBefore) const;1034 void marginBeforeEstimateForChild(RenderBox*, LayoutUnit&, LayoutUnit&, bool&) const; 1014 1035 void determineLogicalLeftPositionForChild(RenderBox* child); 1015 1036 void handleAfterSideOfBlock(LayoutUnit top, LayoutUnit bottom, MarginInfo&); … … 1173 1194 , m_pageLogicalOffset(0) 1174 1195 , m_lineGridBox(0) 1196 , m_lineBreakToAvoidWidow(0) 1175 1197 , m_shouldBreakAtLineToAvoidWidow(false) 1176 , m_lineBreakToAvoidWidow(0) 1198 , m_discardMarginBefore(false) 1199 , m_discardMarginAfter(false) 1177 1200 { 1178 1201 } … … 1182 1205 return std::max<LayoutUnit>(block->marginBefore(), 0); 1183 1206 } 1184 1185 1207 static LayoutUnit negativeMarginBeforeDefault(const RenderBlock* block) 1186 1208 { … … 1202 1224 RootInlineBox* m_lineGridBox; 1203 1225 1204 bool m_shouldBreakAtLineToAvoidWidow;1205 1226 RootInlineBox* m_lineBreakToAvoidWidow; 1227 bool m_shouldBreakAtLineToAvoidWidow : 1; 1228 bool m_discardMarginBefore : 1; 1229 bool m_discardMarginAfter : 1; 1206 1230 }; 1207 1231 -
trunk/Source/WebCore/rendering/style/RenderStyle.h
r142893 r142974 378 378 bool hasPadding() const { return surround->padding.nonZero(); } 379 379 bool hasOffset() const { return surround->offset.nonZero(); } 380 bool isMarginBeforeQuirk() const { return marginBefore().quirk(); } 381 bool isMarginAfterQuirk() const { return marginAfter().quirk(); } 380 382 381 383 bool hasBackgroundImage() const { return m_background->background().hasImage(); }
Note: See TracChangeset
for help on using the changeset viewer.