WebCore:
authorhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 27 Mar 2009 18:02:18 +0000 (18:02 +0000)
committerhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 27 Mar 2009 18:02:18 +0000 (18:02 +0000)
2009-03-27  David Hyatt  <hyatt@apple.com>

        Reviewed by Simon Fraser

        If an object has a self-painting layer, don't count it as part of a block's visual overflow.
        This fix has only been made for block-level children.   The inline-level case is still broken
        (and covered by an existing bug).

        Added fast/block/positioning/negative-rel-position.html

        * rendering/InlineFlowBox.cpp:
        (WebCore::InlineFlowBox::placeBoxesVertically):
        * rendering/RenderBlock.cpp:
        (WebCore::RenderBlock::layoutBlockChildren):
        (WebCore::RenderBlock::lowestPosition):
        (WebCore::RenderBlock::rightmostPosition):
        (WebCore::RenderBlock::leftmostPosition):

LayoutTests:

2009-03-27  David Hyatt  <hyatt@apple.com>

        Reviewed by Simon Fraser

        Test case for relative positioning bug.

        * fast/block/positioning/negative-rel-position.html: Added.
        * platform/mac/fast/block/positioning/negative-rel-position-expected.checksum: Added.
        * platform/mac/fast/block/positioning/negative-rel-position-expected.png: Added.
        * platform/mac/fast/block/positioning/negative-rel-position-expected.txt: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@42043 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/block/positioning/negative-rel-position.html [new file with mode: 0644]
LayoutTests/platform/mac/fast/block/positioning/002-expected.txt
LayoutTests/platform/mac/fast/block/positioning/negative-rel-position-expected.checksum [new file with mode: 0644]
LayoutTests/platform/mac/fast/block/positioning/negative-rel-position-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/fast/block/positioning/negative-rel-position-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/fast/block/positioning/relative-overflow-block-expected.txt
LayoutTests/platform/mac/fast/transforms/transforms-with-opacity-expected.txt
WebCore/ChangeLog
WebCore/rendering/InlineFlowBox.cpp
WebCore/rendering/RenderBlock.cpp

index 2c6c575..7fae158 100644 (file)
@@ -1,3 +1,14 @@
+2009-03-27  David Hyatt  <hyatt@apple.com>
+
+        Reviewed by Simon Fraser
+
+        Test case for relative positioning bug.
+
+        * fast/block/positioning/negative-rel-position.html: Added.
+        * platform/mac/fast/block/positioning/negative-rel-position-expected.checksum: Added.
+        * platform/mac/fast/block/positioning/negative-rel-position-expected.png: Added.
+        * platform/mac/fast/block/positioning/negative-rel-position-expected.txt: Added.
+
 2009-03-26  Eric Seidel  <eric@webkit.org>
 
         Reviewed by David Hyatt.
diff --git a/LayoutTests/fast/block/positioning/negative-rel-position.html b/LayoutTests/fast/block/positioning/negative-rel-position.html
new file mode 100644 (file)
index 0000000..94b71e2
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head> 
+<style>                                
+div {
+    background-color:lime;
+    display: block;
+    padding: 10px;
+    position: relative;
+    left: -430px;
+    width: 860px;
+    height:100px;
+    margin-left: 50%;
+}
+</style>
+</head>
+<body>
+<div></div>
+</body>
+</html>
\ No newline at end of file
index 94d2e2c..1d9236b 100644 (file)
@@ -1,6 +1,6 @@
 layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
-layer at (0,0) size 800x226
+layer at (0,0) size 800x134
   RenderBlock {HTML} at (0,0) size 800x134
     RenderBody {BODY} at (8,8) size 784x118
       RenderBlock (anonymous) at (0,0) size 784x18
diff --git a/LayoutTests/platform/mac/fast/block/positioning/negative-rel-position-expected.checksum b/LayoutTests/platform/mac/fast/block/positioning/negative-rel-position-expected.checksum
new file mode 100644 (file)
index 0000000..56d8803
--- /dev/null
@@ -0,0 +1 @@
+9497a40eaf0792a0d4614412aaf98462
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/fast/block/positioning/negative-rel-position-expected.png b/LayoutTests/platform/mac/fast/block/positioning/negative-rel-position-expected.png
new file mode 100644 (file)
index 0000000..0bbab7a
Binary files /dev/null and b/LayoutTests/platform/mac/fast/block/positioning/negative-rel-position-expected.png differ
diff --git a/LayoutTests/platform/mac/fast/block/positioning/negative-rel-position-expected.txt b/LayoutTests/platform/mac/fast/block/positioning/negative-rel-position-expected.txt
new file mode 100644 (file)
index 0000000..e5fb4f1
--- /dev/null
@@ -0,0 +1,7 @@
+layer at (0,0) size 850x585
+  RenderView at (0,0) size 800x585
+layer at (0,0) size 800x136
+  RenderBlock {HTML} at (0,0) size 800x136
+    RenderBody {BODY} at (8,8) size 784x120
+layer at (-30,8) size 880x120 backgroundClip at (0,0) size 850x585 clip at (0,0) size 850x585 outlineClip at (0,0) size 850x585
+  RenderBlock (relative positioned) {DIV} at (392,0) size 880x120 [bgcolor=#00FF00]
index c56c90b..ef37679 100644 (file)
@@ -6,7 +6,7 @@ layer at (0,0) size 785x585
       RenderText {#text} at (0,0) size 762x36
         text run at (0,0) width 762: "Document canvas should be big enough to fit both blue and red (relative positioned) rectangles (ie. have scrollbars if they"
         text run at (0,18) width 131: "don't fit to the view) "
-layer at (8,44) size 506x506
+layer at (8,44) size 504x506
   RenderBlock (positioned) {DIV} at (8,44) size 504x504 [border: (2px solid #0000FF)]
 layer at (310,346) size 504x504
   RenderBlock (relative positioned) {DIV} at (2,2) size 504x504 [border: (2px solid #FF0000)]
index 554d759..e1b7cdc 100644 (file)
@@ -6,9 +6,9 @@ layer at (0,0) size 800x600
       RenderBlock (anonymous) at (0,0) size 784x18
         RenderText {#text} at (0,0) size 750x18
           text run at (0,0) width 750: "In the example below you should see three blocks right next to one another, and they should all be partially transparent."
-layer at (8,26) size 140x130
+layer at (8,26) size 120x130
   RenderBlock {DIV} at (0,18) size 120x120 [bgcolor=#87CEEB] [border: (10px solid #000000)]
-layer at (18,36) size 130x130
+layer at (18,36) size 120x130
   RenderBlock {DIV} at (10,10) size 120x120 [border: (10px solid #000000)]
 layer at (28,46) size 120x120
   RenderBlock {DIV} at (10,10) size 120x120 [border: (10px solid #000000)]
index 323ee65..7dfedad 100644 (file)
@@ -1,3 +1,21 @@
+2009-03-27  David Hyatt  <hyatt@apple.com>
+
+        Reviewed by Simon Fraser
+
+        If an object has a self-painting layer, don't count it as part of a block's visual overflow.
+        This fix has only been made for block-level children.   The inline-level case is still broken
+        (and covered by an existing bug).
+
+        Added fast/block/positioning/negative-rel-position.html
+
+        * rendering/InlineFlowBox.cpp:
+        (WebCore::InlineFlowBox::placeBoxesVertically):
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::layoutBlockChildren):
+        (WebCore::RenderBlock::lowestPosition):
+        (WebCore::RenderBlock::rightmostPosition):
+        (WebCore::RenderBlock::leftmostPosition):
+
 2009-03-27  Anders Carlsson  <andersca@apple.com>
 
         Reviewed by Darin Adler.
index 2e23bb6..584d05b 100644 (file)
@@ -492,6 +492,11 @@ void InlineFlowBox::placeBoxesVertically(int yPos, int maxHeight, int maxAscent,
             curr->setY(curr->y() + yPos + posAdjust);
         }
         
+        // FIXME: By only considering overflow as part of the root line box, we can't get an accurate picture regarding what the line
+        // actually needs to paint.  A line box that is part of a self-painting layer technically shouldn't contribute to the overflow
+        // of the line, but in order to not do this and paint accurately, we have to track the overflow somewhere else (either by storing overflow
+        // in each InlineFlowBox up the chain or in the layer itself).  Relative positioned objects on a line will cause scrollbars
+        // to appear when they shouldn't until we fix this issue.
         int newY = curr->y();
         int overflowTop = 0;
         int overflowBottom = 0;
index 867cc58..59284ee 100644 (file)
@@ -1423,11 +1423,14 @@ void RenderBlock::layoutBlockChildren(bool relayoutChildren, int& maxFloatBottom
         if (child->isBlockFlow() && toRenderBlock(child)->containsFloats())
             maxFloatBottom = max(maxFloatBottom, addOverhangingFloats(toRenderBlock(child), -child->x(), -child->y(), !childNeededLayout));
 
-        // Update our overflow in case the child spills out the block.
-        m_overflowTop = min(m_overflowTop, child->y() + child->overflowTop(false));
-        m_overflowHeight = max(m_overflowHeight, height() + child->overflowHeight(false) - child->height());
-        m_overflowWidth = max(child->x() + child->overflowWidth(false), m_overflowWidth);
-        m_overflowLeft = min(child->x() + child->overflowLeft(false), m_overflowLeft);
+        // Update our visual overflow in case the child spills out the block, but only if we were going to paint
+        // the child block ourselves.
+        if (!child->hasSelfPaintingLayer()) {
+            m_overflowTop = min(m_overflowTop, child->y() + child->overflowTop(false));
+            m_overflowHeight = max(m_overflowHeight, height() + child->overflowHeight(false) - child->height());
+            m_overflowWidth = max(child->x() + child->overflowWidth(false), m_overflowWidth);
+            m_overflowLeft = min(child->x() + child->overflowLeft(false), m_overflowLeft);
+        }
 
         IntSize childOffset(child->x() - oldRect.x(), child->y() - oldRect.y());
         if (childOffset.width() || childOffset.height()) {
@@ -2667,6 +2670,8 @@ int RenderBlock::lowestPosition(bool includeOverflowInterior, bool includeSelf)
         // For now, we have to descend into all the children, since we may have a huge abs div inside
         // a tiny rel div buried somewhere deep in our child tree.  In this case we have to get to
         // the abs div.
+        // See the last test case in https://bugs.webkit.org/show_bug.cgi?id=9314 for why this is a problem.
+        // For inline children, we miss relative positioned boxes that might be buried inside <span>s.
         for (RenderObject* c = firstChild(); c; c = c->nextSibling()) {
             if (!c->isFloatingOrPositioned() && c->isBox()) {
                 RenderBox* childBox = toRenderBox(c);
@@ -2723,11 +2728,11 @@ int RenderBlock::lowestPosition(bool includeOverflowInterior, bool includeSelf)
     }
 
     if (!includeSelf) {
-        bottom = max(bottom, borderTop() + paddingTop() + paddingBottom());
+        bottom = max(bottom, borderTop() + paddingTop() + paddingBottom() + relativeOffset);
         if (childrenInline()) {
             if (lastLineBox()) {
                 int childBottomEdge = lastLineBox()->y() + lastLineBox()->height();
-                bottom = max(bottom, childBottomEdge + paddingBottom());
+                bottom = max(bottom, childBottomEdge + paddingBottom() + relativeOffset);
             }
         } else {
             // Find the last normal flow child.
@@ -2736,7 +2741,7 @@ int RenderBlock::lowestPosition(bool includeOverflowInterior, bool includeSelf)
                 currBox = currBox->previousSiblingBox();
             if (currBox) {
                 int childBottomEdge = currBox->y() + currBox->height() + currBox->collapsedMarginBottom();
-                bottom = max(bottom, childBottomEdge + paddingBottom());
+                bottom = max(bottom, childBottomEdge + paddingBottom() + relativeOffset);
             }
         }
     }
@@ -2813,7 +2818,7 @@ int RenderBlock::rightmostPosition(bool includeOverflowInterior, bool includeSel
     }
 
     if (!includeSelf) {
-        right = max(right, borderLeft() + paddingLeft() + paddingRight());
+        right = max(right, borderLeft() + paddingLeft() + paddingRight() + relativeOffset);
         if (childrenInline()) {
             for (InlineRunBox* currBox = firstLineBox(); currBox; currBox = currBox->nextLineBox()) {
                 int childRightEdge = currBox->x() + currBox->width();
@@ -2822,7 +2827,7 @@ int RenderBlock::rightmostPosition(bool includeOverflowInterior, bool includeSel
                 // FIXME: Need to find another way to do this, since scrollbars could show when we don't want them to.
                 if (node() && node()->isContentEditable() && node() == node()->rootEditableElement() && style()->direction() == LTR && !paddingRight())
                     childRightEdge += 1;
-                right = max(right, childRightEdge + paddingRight());
+                right = max(right, childRightEdge + paddingRight() + relativeOffset);
             }
         } else {
             // Walk all normal flow children.
@@ -2830,7 +2835,7 @@ int RenderBlock::rightmostPosition(bool includeOverflowInterior, bool includeSel
                 if (currBox->isFloatingOrPositioned())
                     continue;
                 int childRightEdge = currBox->x() + currBox->width() + currBox->marginRight();
-                right = max(right, childRightEdge + paddingRight());
+                right = max(right, childRightEdge + paddingRight() + relativeOffset);
             }
         }
     }
@@ -2907,7 +2912,7 @@ int RenderBlock::leftmostPosition(bool includeOverflowInterior, bool includeSelf
 
     if (!includeSelf && firstLineBox()) {
         for (InlineRunBox* currBox = firstLineBox(); currBox; currBox = currBox->nextLineBox())
-            left = min(left, (int)currBox->x());
+            left = min(left, (int)currBox->x() + relativeOffset);
     }
     
     return left;