Title: [120844] trunk
Revision
120844
Author
[email protected]
Date
2012-06-20 11:40:09 -0700 (Wed, 20 Jun 2012)

Log Message

Negative margin block doesn't properly clear a float enclosed by a previous sibling
https://bugs.webkit.org/show_bug.cgi?id=10900

Reviewed by Eric Seidel.

Source/WebCore:

Tests: fast/block/float/previous-sibling-abspos-001.html
       fast/block/float/previous-sibling-abspos-002.html
       fast/block/float/previous-sibling-float-001.html
       fast/block/float/previous-sibling-float-002.html
       fast/css/clear-float-sibling.html

Parent blocks keep a list of child floats that extend out of the parent block and
by implication overhang into the parent's siblings. But this doesn't work if the
sibling has collapsing margins - it will not find the float in the previous block's
list so will ignore the float and fail to clear it.

RenderBlock:collapseMargins() needs to check if a child's collapsing margin has
reduced the height of the parent up past the bottom of its previous sibling's lowest float
and add the now overhanging float to the parent's float list if appropriate. No need to do
this if the previous sibling is a float or is positioned - the child will clear/avoid it anyway
and attempting to avoid floated children of floats causes incorrect layout.

* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::collapseMargins):

LayoutTests:

* fast/block/float/previous-sibling-abspos-001-expected.html: Added.
* fast/block/float/previous-sibling-abspos-001.html: Added.
* fast/block/float/previous-sibling-abspos-002-expected.html: Added.
* fast/block/float/previous-sibling-abspos-002.html: Added.
* fast/block/float/previous-sibling-float-001-expected.html: Added.
* fast/block/float/previous-sibling-float-001.html: Added.
* fast/block/float/previous-sibling-float-002-expected.html: Added.
* fast/block/float/previous-sibling-float-002.html: Added.
* fast/css/clear-float-sibling-expected.html: Added.
* fast/css/clear-float-sibling.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (120843 => 120844)


--- trunk/LayoutTests/ChangeLog	2012-06-20 18:36:40 UTC (rev 120843)
+++ trunk/LayoutTests/ChangeLog	2012-06-20 18:40:09 UTC (rev 120844)
@@ -1,3 +1,21 @@
+2012-06-20  Robert Hogan  <[email protected]>
+
+        Negative margin block doesn't properly clear a float enclosed by a previous sibling
+        https://bugs.webkit.org/show_bug.cgi?id=10900
+
+        Reviewed by Eric Seidel.
+
+        * fast/block/float/previous-sibling-abspos-001-expected.html: Added.
+        * fast/block/float/previous-sibling-abspos-001.html: Added.
+        * fast/block/float/previous-sibling-abspos-002-expected.html: Added.
+        * fast/block/float/previous-sibling-abspos-002.html: Added.
+        * fast/block/float/previous-sibling-float-001-expected.html: Added.
+        * fast/block/float/previous-sibling-float-001.html: Added.
+        * fast/block/float/previous-sibling-float-002-expected.html: Added.
+        * fast/block/float/previous-sibling-float-002.html: Added.
+        * fast/css/clear-float-sibling-expected.html: Added.
+        * fast/css/clear-float-sibling.html: Added.
+
 2012-06-20  Alexis Menard  <[email protected]>
 
         [CSS3 Backgrounds and Borders] Implement box-decoration-break rendering.

Added: trunk/LayoutTests/fast/block/float/previous-sibling-abspos-001-expected.html (0 => 120844)


--- trunk/LayoutTests/fast/block/float/previous-sibling-abspos-001-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/block/float/previous-sibling-abspos-001-expected.html	2012-06-20 18:40:09 UTC (rev 120844)
@@ -0,0 +1,20 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+    <head>
+        <title>CSS Test: Avoid nested floats in previous siblings</title>
+        <link rel="author" title="WebKit" href=""
+        <style type="text/css">
+            #container
+            {
+                background-color:green;
+                width: 400px;
+                height: 100px; 
+            }
+        </style>
+    </head>
+    <body>
+        <p>There should be no red.</p>
+        <div id="container">
+        </div>
+    </body>
+</html>

Added: trunk/LayoutTests/fast/block/float/previous-sibling-abspos-001.html (0 => 120844)


--- trunk/LayoutTests/fast/block/float/previous-sibling-abspos-001.html	                        (rev 0)
+++ trunk/LayoutTests/fast/block/float/previous-sibling-abspos-001.html	2012-06-20 18:40:09 UTC (rev 120844)
@@ -0,0 +1,44 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+    <head>
+        <title>CSS Test: Avoid nested floats in previous siblings</title>
+        <link rel="author" title="WebKit" href=""
+        <style type="text/css">
+            #container
+            {
+                background-color:red;
+                overflow:hidden;
+                width: 400px;
+            }
+            #absolute
+            {
+                position: absolute;
+                width: 400px;
+            }
+            #float-left
+            {
+                float: right; 
+                height: 100px; 
+                width: 20px; 
+                background-color: green;
+            }
+            #div1
+            {
+                /*'overflow: hidden' forces the div to avoid floats*/
+                overflow: hidden; 
+                height: 100px; 
+                width: 380px; 
+                background-color: green;
+            }
+        </style>
+    </head>
+    <body>
+        <p>There should be no red.</p>
+        <div id="container">
+            <div id="absolute">
+                <div id="float-left"></div>
+            </div>
+            <div id="div1"></div>
+        </div>
+    </body>
+</html>

Added: trunk/LayoutTests/fast/block/float/previous-sibling-abspos-002-expected.html (0 => 120844)


--- trunk/LayoutTests/fast/block/float/previous-sibling-abspos-002-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/block/float/previous-sibling-abspos-002-expected.html	2012-06-20 18:40:09 UTC (rev 120844)
@@ -0,0 +1,20 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+    <head>
+        <title>CSS Test: Avoid nested floats in previous siblings</title>
+        <link rel="author" title="WebKit" href=""
+        <style type="text/css">
+            #container
+            {
+                width: 400px;
+                height: 20px; 
+                background-color: green;
+            }
+        </style>
+    </head>
+    <body>
+        <p>There should be no red below.</p>
+        <div id="container">
+        </div>
+    </body>
+</html>

Added: trunk/LayoutTests/fast/block/float/previous-sibling-abspos-002.html (0 => 120844)


--- trunk/LayoutTests/fast/block/float/previous-sibling-abspos-002.html	                        (rev 0)
+++ trunk/LayoutTests/fast/block/float/previous-sibling-abspos-002.html	2012-06-20 18:40:09 UTC (rev 120844)
@@ -0,0 +1,42 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+    <head>
+        <title>CSS Test: Avoid nested floats in previous siblings</title>
+        <link rel="author" title="WebKit" href=""
+        <style type="text/css">
+            #container
+            {
+                width: 400px;
+            }
+            #div1
+            {
+                height: 80px;
+                width: 400px;
+                position: absolute;
+            }
+            #float-right
+            {
+                float: right; 
+                height: 20px; 
+                width: 400px; 
+                background-color: green;
+            }
+            #div2
+            {
+                /*'overflow: hidden' forces the div to avoid floats*/
+                overflow: hidden; 
+                font: 10px Ahem;
+                color: red;
+            }
+        </style>
+    </head>
+    <body>
+        <p>There should be no red below.</p>
+        <div id="container">
+            <div id="div1">
+                <div id="float-right"></div>
+            </div>
+            <div id="div2">You should not see this text</div>
+        </div>
+    </body>
+</html>

Added: trunk/LayoutTests/fast/block/float/previous-sibling-float-001-expected.html (0 => 120844)


--- trunk/LayoutTests/fast/block/float/previous-sibling-float-001-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/block/float/previous-sibling-float-001-expected.html	2012-06-20 18:40:09 UTC (rev 120844)
@@ -0,0 +1,20 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+    <head>
+        <title>CSS Test: Avoid nested floats in previous siblings</title>
+        <link rel="author" title="WebKit" href=""
+        <style type="text/css">
+            #container
+            {
+                background-color: green;
+                width: 400px;
+                height: 100px; 
+            }
+        </style>
+    </head>
+    <body>
+        <p>There should be no red.</p>
+        <div id="container">
+        </div>
+    </body>
+</html>

Added: trunk/LayoutTests/fast/block/float/previous-sibling-float-001.html (0 => 120844)


--- trunk/LayoutTests/fast/block/float/previous-sibling-float-001.html	                        (rev 0)
+++ trunk/LayoutTests/fast/block/float/previous-sibling-float-001.html	2012-06-20 18:40:09 UTC (rev 120844)
@@ -0,0 +1,43 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+    <head>
+        <title>CSS Test: Avoid nested floats in previous siblings</title>
+        <link rel="author" title="WebKit" href=""
+        <style type="text/css">
+            #container
+            {
+                background-color:red;
+                overflow:hidden;
+                width: 400px;
+            }
+            #float-right
+            {
+                float: right;
+            }
+            #float-left
+            {
+                float: left; 
+                height: 100px; 
+                width: 20px; 
+                background-color: green;
+            }
+            #div1
+            {
+                /*'overflow: hidden' forces the div to avoid floats*/
+                overflow: hidden; 
+                height: 100px; 
+                width: 380px; 
+                background-color: green;
+            }
+        </style>
+    </head>
+    <body>
+        <p>There should be no red.</p>
+        <div id="container">
+            <div id="float-right">
+                <div id="float-left"></div>
+            </div>
+            <div id="div1"></div>
+        </div>
+    </body>
+</html>

Added: trunk/LayoutTests/fast/block/float/previous-sibling-float-002-expected.html (0 => 120844)


--- trunk/LayoutTests/fast/block/float/previous-sibling-float-002-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/block/float/previous-sibling-float-002-expected.html	2012-06-20 18:40:09 UTC (rev 120844)
@@ -0,0 +1,20 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+    <head>
+        <title>CSS Test: Avoid nested floats in previous siblings</title>
+        <link rel="author" title="WebKit" href=""
+        <style type="text/css">
+            #container
+            {
+                background-color:green;
+                width: 400px;
+                height: 30px;
+            }
+        </style>
+    </head>
+    <body>
+        <p>There should be no red below.</p>
+        <div id="container">
+        </div>
+    </body>
+</html>

Added: trunk/LayoutTests/fast/block/float/previous-sibling-float-002.html (0 => 120844)


--- trunk/LayoutTests/fast/block/float/previous-sibling-float-002.html	                        (rev 0)
+++ trunk/LayoutTests/fast/block/float/previous-sibling-float-002.html	2012-06-20 18:40:09 UTC (rev 120844)
@@ -0,0 +1,42 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+    <head>
+        <title>CSS Test: Avoid nested floats in previous siblings</title>
+        <link rel="author" title="WebKit" href=""
+        <style type="text/css">
+            #container
+            {
+                background-color:green;
+                width: 400px;
+            }
+            #div1
+            {
+                height: 40px;
+            }
+            #float-right
+            {
+                float: right; 
+                height: 20px; 
+                width: 400px; 
+                background-color: green;
+            }
+            #div2
+            {
+                /*'overflow: hidden' forces the div to avoid floats*/
+                overflow: hidden; 
+                margin-top: -30px;
+                font: 20px Ahem;
+                color: red;
+            }
+        </style>
+    </head>
+    <body>
+        <p>There should be no red below.</p>
+        <div id="container">
+            <div id="div1">
+                <div id="float-right"></div>
+            </div>
+            <div id="div2">Text</div>
+        </div>
+    </body>
+</html>

Added: trunk/LayoutTests/fast/css/clear-float-sibling-expected.html (0 => 120844)


--- trunk/LayoutTests/fast/css/clear-float-sibling-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css/clear-float-sibling-expected.html	2012-06-20 18:40:09 UTC (rev 120844)
@@ -0,0 +1,38 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+    <head>
+        <title>CSS Test: Clear set to 'right' and negative margin with earlier right floated boxes</title>
+        <link rel="author" title="WebKit" href=""
+        <link rel="help" href=""
+        <meta name="flags" content="">
+        <meta name="assert" content="Boxes with 'clear: both' and collapsing margins need to clear earlier right floated boxes.">
+        <style type="text/css">
+            div
+            {
+                width: 2in;
+            }
+            div
+            {
+                height: 1in;
+                width: 1in;
+            }
+            #div1
+            {
+                float: right;
+                background-color: orange;
+            }
+            #div2
+            {
+                background: blue;
+                clear: both;
+            }
+        </style>
+    </head>
+    <body>
+        <p>Test passes if the blue box is directly below the orange box.</p>
+        <div>
+            <div id="div1"></div>
+        </div>
+        <div id="div2"></div>
+    </body>
+</html>
\ No newline at end of file

Added: trunk/LayoutTests/fast/css/clear-float-sibling.html (0 => 120844)


--- trunk/LayoutTests/fast/css/clear-float-sibling.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css/clear-float-sibling.html	2012-06-20 18:40:09 UTC (rev 120844)
@@ -0,0 +1,39 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+    <head>
+        <title>CSS Test: Clear set to 'right' and negative margin with earlier right floated boxes</title>
+        <link rel="author" title="WebKit" href=""
+        <link rel="help" href=""
+        <meta name="flags" content="">
+        <meta name="assert" content="Boxes with 'clear: both' and collapsing margins need to clear earlier right floated boxes.">
+        <style type="text/css">
+            div
+            {
+                width: 2in;
+            }
+            div
+            {
+                height: 1in;
+                width: 1in;
+            }
+            #div1
+            {
+                float: right;
+                background-color: orange;
+            }
+            #div2
+            {
+                margin-top: -0.5in;
+                background: blue;
+                clear: both;
+            }
+        </style>
+    </head>
+    <body>
+        <p>Test passes if the blue box is directly below the orange box.</p>
+        <div>
+            <div id="div1"></div>
+        </div>
+        <div id="div2"></div>
+    </body>
+</html>
\ No newline at end of file

Modified: trunk/Source/WebCore/ChangeLog (120843 => 120844)


--- trunk/Source/WebCore/ChangeLog	2012-06-20 18:36:40 UTC (rev 120843)
+++ trunk/Source/WebCore/ChangeLog	2012-06-20 18:40:09 UTC (rev 120844)
@@ -1,3 +1,30 @@
+2012-06-20  Robert Hogan  <[email protected]>
+
+        Negative margin block doesn't properly clear a float enclosed by a previous sibling
+        https://bugs.webkit.org/show_bug.cgi?id=10900
+
+        Reviewed by Eric Seidel.
+
+        Tests: fast/block/float/previous-sibling-abspos-001.html
+               fast/block/float/previous-sibling-abspos-002.html
+               fast/block/float/previous-sibling-float-001.html
+               fast/block/float/previous-sibling-float-002.html
+               fast/css/clear-float-sibling.html
+
+        Parent blocks keep a list of child floats that extend out of the parent block and
+        by implication overhang into the parent's siblings. But this doesn't work if the
+        sibling has collapsing margins - it will not find the float in the previous block's
+        list so will ignore the float and fail to clear it.
+
+        RenderBlock:collapseMargins() needs to check if a child's collapsing margin has 
+        reduced the height of the parent up past the bottom of its previous sibling's lowest float
+        and add the now overhanging float to the parent's float list if appropriate. No need to do
+        this if the previous sibling is a float or is positioned - the child will clear/avoid it anyway
+        and attempting to avoid floated children of floats causes incorrect layout.
+        
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::collapseMargins):
+
 2012-06-20  Andrey Adaikin  <[email protected]>
 
         Web Inspector: Allow module injections into the InjectedScript

Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (120843 => 120844)


--- trunk/Source/WebCore/rendering/RenderBlock.cpp	2012-06-20 18:36:40 UTC (rev 120843)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp	2012-06-20 18:40:09 UTC (rev 120844)
@@ -2040,6 +2040,17 @@
         logicalTop = min(logicalTop, nextPageLogicalTop(beforeCollapseLogicalTop));
         setLogicalHeight(logicalHeight() + (logicalTop - oldLogicalTop));
     }
+
+    // If we have collapsed into a previous sibling and so reduced the height of the parent, ensure any floats that now
+    // overhang from the previous sibling are added to our parent. If the child's previous sibling itself is a float the child will avoid
+    // or clear it anyway, so don't worry about any floating children it may contain.
+    RenderObject* prev = child->previousSibling();
+    if (prev && prev->isBlockFlow() && !prev->isFloatingOrPositioned()) {
+        RenderBlock* block = toRenderBlock(prev);
+        if (block->containsFloats() && block->lowestFloatLogicalBottom() > logicalTop) 
+            addOverhangingFloats(block, false);
+    }
+
     return logicalTop;
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to