Changeset 122489 in webkit


Ignore:
Timestamp:
Jul 12, 2012 11:46:53 AM (12 years ago)
Author:
hyatt@apple.com
Message:

https://bugs.webkit.org/show_bug.cgi?id=91000
REGRESSION (r122244): Overflow elements don't shrink as much as they should.

Reviewed by Simon Fraser.

This is a fix for a a regression from https://bugs.webkit.org/show_bug.cgi?id=90646.

I incorrectly analyzed the issue with Robert Hogan's negative margin patch and fooled myself into putting back
in an incorrect minimum width check from long ago.

What should have happened in the test case I patched is that the overflow element should shrink to 0. The issue
with improving the logical top estimate in the previous patch is it made the clear delta become 0. This in turn
exposed a bug in our clearing algorithm with Robert's changes where you could need a relayout even if you didn't
actually move. This issue only occurs because the floats list is getting changed mid-layout because of negative margins.

The patch changes getClearDelta to call setChildNeedsLayout(true) on children whose widths change even when their
positions do not. In effect this dynamic addition of new floats after you have done a layout on the child already means
that you can need to lay out again despite not actually having to move.

To handle this, the code that does the relayout is now called if the child needs a relayout. This is done even if
the logical top estimate matches the final position.

No new tests required, since the test in fast/block/float is now correctly covering the issue.

  • rendering/RenderBlock.cpp:

(WebCore::RenderBlock::layoutBlockChild):
(WebCore::RenderBlock::getClearDelta):

  • rendering/RenderBox.cpp:

(WebCore::RenderBox::shrinkLogicalWidthToAvoidFloats):

Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r122488 r122489  
     12012-07-11  David Hyatt  <hyatt@apple.com>
     2
     3        https://bugs.webkit.org/show_bug.cgi?id=91000
     4        REGRESSION (r122244): Overflow elements don't shrink as much as they should.
     5
     6        Reviewed by Simon Fraser.
     7
     8        This is a fix for a a regression from https://bugs.webkit.org/show_bug.cgi?id=90646.
     9
     10        I incorrectly analyzed the issue with Robert Hogan's negative margin patch and fooled myself into putting back
     11        in an incorrect minimum width check from long ago.
     12       
     13        What should have happened in the test case I patched is that the overflow element should shrink to 0. The issue
     14        with improving the logical top estimate in the previous patch is it made the clear delta become 0. This in turn
     15        exposed a bug in our clearing algorithm with Robert's changes where you could need a relayout even if you didn't
     16        actually move. This issue only occurs because the floats list is getting changed mid-layout because of negative margins.
     17
     18        The patch changes getClearDelta to call setChildNeedsLayout(true) on children whose widths change even when their
     19        positions do not. In effect this dynamic addition of new floats after you have done a layout on the child already means
     20        that you can need to lay out again despite not actually having to move.
     21       
     22        To handle this, the code that does the relayout is now called if the child needs a relayout. This is done even if
     23        the logical top estimate matches the final position.
     24       
     25        No new tests required, since the test in fast/block/float is now correctly covering the issue.
     26
     27        * rendering/RenderBlock.cpp:
     28        (WebCore::RenderBlock::layoutBlockChild):
     29        (WebCore::RenderBlock::getClearDelta):
     30        * rendering/RenderBox.cpp:
     31        (WebCore::RenderBox::shrinkLogicalWidthToAvoidFloats):
     32
    1332012-07-12  James Weatherall  <wez@chromium.org>
    234
  • trunk/Source/WebCore/rendering/RenderBlock.cpp

    r122244 r122489  
    24282428
    24292429    // Now we have a final top position.  See if it really does end up being different from our estimate.
    2430     if (logicalTopAfterClear != logicalTopEstimate) {
     2430    // clearFloatsIfNeeded can also mark the child as needing a layout even though we didn't move. This happens
     2431    // when collapseMargins dynamically adds overhanging floats because of a child with negative margins.
     2432    if (logicalTopAfterClear != logicalTopEstimate || child->needsLayout()) {
    24312433        if (child->shrinkToAvoidFloats()) {
    24322434            // The child's width depends on the line width.
     
    45844586                return newLogicalTop - logicalTop;
    45854587
     4588            RenderRegion* region = regionAtBlockOffset(logicalTopForChild(child));
     4589            LayoutRect borderBox = child->borderBoxRectInRegion(region, offsetFromLogicalTopOfFirstPage() + logicalTopForChild(child), DoNotCacheRenderBoxRegionInfo);
     4590            LayoutUnit childLogicalWidthAtOldLogicalTopOffset = isHorizontalWritingMode() ? borderBox.width() : borderBox.height();
     4591
    45864592            // FIXME: None of this is right for perpendicular writing-mode children.
    45874593            LayoutUnit childOldLogicalWidth = child->logicalWidth();
     
    45924598            child->setLogicalTop(newLogicalTop);
    45934599            child->computeLogicalWidth();
    4594             RenderRegion* region = regionAtBlockOffset(logicalTopForChild(child));
    4595             LayoutRect borderBox = child->borderBoxRectInRegion(region, offsetFromLogicalTopOfFirstPage() + logicalTopForChild(child), DoNotCacheRenderBoxRegionInfo);
     4600            region = regionAtBlockOffset(logicalTopForChild(child));
     4601            borderBox = child->borderBoxRectInRegion(region, offsetFromLogicalTopOfFirstPage() + logicalTopForChild(child), DoNotCacheRenderBoxRegionInfo);
    45964602            LayoutUnit childLogicalWidthAtNewLogicalTopOffset = isHorizontalWritingMode() ? borderBox.width() : borderBox.height();
    45974603
     
    46014607            child->setMarginRight(childOldMarginRight);
    46024608           
    4603             if (childLogicalWidthAtNewLogicalTopOffset <= availableLogicalWidthAtNewLogicalTopOffset)
     4609            if (childLogicalWidthAtNewLogicalTopOffset <= availableLogicalWidthAtNewLogicalTopOffset) {
     4610                // Even though we may not be moving, if the logical width did shrink because of the presence of new floats, then
     4611                // we need to force a relayout as though we shifted. This happens because of the dynamic addition of overhanging floats
     4612                // from previous siblings when negative margins exist on a child (see the addOverhangingFloats call at the end of collapseMargins).
     4613                if (childLogicalWidthAtOldLogicalTopOffset != childLogicalWidthAtNewLogicalTopOffset)
     4614                    child->setChildNeedsLayout(true, MarkOnlyThis);
    46044615                return newLogicalTop - logicalTop;
     4616            }
    46054617
    46064618            newLogicalTop = nextFloatLogicalBottomBelow(newLogicalTop);
  • trunk/Source/WebCore/rendering/RenderBox.cpp

    r122268 r122489  
    11791179
    11801180    LayoutUnit result = cb->availableLogicalWidthForLine(logicalTopPosition, false, containingBlockRegion, adjustedPageOffsetForContainingBlock) - childMarginStart - childMarginEnd;
    1181     result = max(result, minPreferredLogicalWidth()); // Don't shrink below our minimum preferred logical width.
    11821181
    11831182    // We need to see if margins on either the start side or the end side can contain the floats in question. If they can,
Note: See TracChangeset for help on using the changeset viewer.