percentage top value of position:relative element not calculated using parent's min...
authorrobert@webkit.org <robert@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 16 Feb 2013 13:06:03 +0000 (13:06 +0000)
committerrobert@webkit.org <robert@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 16 Feb 2013 13:06:03 +0000 (13:06 +0000)
https://bugs.webkit.org/show_bug.cgi?id=14762

Reviewed by Julien Chaffraix.

Source/WebCore:

Percentage height "is calculated with respect to the height of the generated box's containing block" says
http://www.w3.org/TR/CSS21/visudet.html#the-height-property and "If the height of the containing block is not
specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the
value computes to 'auto'." So when calculating the used height of a replaced element do not crawl through ancestor
blocks except when traversing anonymous blocks. Ensure that anonymous table cells are not skipped through though.

http://www.w3.org/TR/CSS21/tables.html#height-layout adds "In CSS 2.1, the height of a cell box is the minimum
height required by the content." This height is decided by allowing table cells to report their height as auto.
It's not clear why http://trac.webkit.org/changeset/91242 decided it should no longer do this - doing so caused
us to regress in our rendering of computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor.html.

Tests: fast/block/percent-top-parent-respects-min-height.html
       fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr.html
       fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor.html
       fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr.html
       fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor.html

* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::hasAutoHeightOrContainingBlockWithAutoHeight):
(WebCore):
(WebCore::RenderBoxModelObject::relativePositionOffset):
* rendering/RenderBoxModelObject.h:
(RenderBoxModelObject):
* rendering/RenderReplaced.cpp:
(WebCore::RenderReplaced::hasReplacedLogicalHeight):

LayoutTests:

* fast/block/percent-top-parent-respects-min-height-expected.txt: Added.
* fast/block/percent-top-parent-respects-min-height.html: Added.
* fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-expected.txt: Added.
* fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr-expected.txt: Added.
* fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr.html: Added.
* fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor.html: Added.
* fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-expected.txt: Added.
* fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr-expected.txt: Added.
* fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr.html: Added.
* fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor.html: Added.

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

15 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/block/percent-top-parent-respects-min-height-expected.txt [new file with mode: 0644]
LayoutTests/fast/block/percent-top-parent-respects-min-height.html [new file with mode: 0644]
LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-expected.txt [new file with mode: 0644]
LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr-expected.txt [new file with mode: 0644]
LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr.html [new file with mode: 0644]
LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor.html [new file with mode: 0644]
LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-expected.txt [new file with mode: 0644]
LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr-expected.txt [new file with mode: 0644]
LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr.html [new file with mode: 0644]
LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderBoxModelObject.cpp
Source/WebCore/rendering/RenderBoxModelObject.h
Source/WebCore/rendering/RenderReplaced.cpp

index 1688a0a..aa726de 100644 (file)
@@ -1,3 +1,21 @@
+2013-02-16  Robert Hogan  <robert@webkit.org>
+
+        percentage top value of position:relative element not calculated using parent's min-height unless height set
+        https://bugs.webkit.org/show_bug.cgi?id=14762
+
+        Reviewed by Julien Chaffraix.
+
+        * fast/block/percent-top-parent-respects-min-height-expected.txt: Added.
+        * fast/block/percent-top-parent-respects-min-height.html: Added.
+        * fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-expected.txt: Added.
+        * fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr-expected.txt: Added.
+        * fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr.html: Added.
+        * fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor.html: Added.
+        * fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-expected.txt: Added.
+        * fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr-expected.txt: Added.
+        * fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr.html: Added.
+        * fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor.html: Added.
+
 2013-02-16  Stephen White  <senorblanco@chromium.org>
 
         [skia] FEOffset should have a Skia implementation.
diff --git a/LayoutTests/fast/block/percent-top-parent-respects-min-height-expected.txt b/LayoutTests/fast/block/percent-top-parent-respects-min-height-expected.txt
new file mode 100644 (file)
index 0000000..f961f44
--- /dev/null
@@ -0,0 +1,4 @@
+https://bugs.webkit.org/show_bug.cgi?id=14762: There should be no red below.
+
+PASS
+PASS
diff --git a/LayoutTests/fast/block/percent-top-parent-respects-min-height.html b/LayoutTests/fast/block/percent-top-parent-respects-min-height.html
new file mode 100644 (file)
index 0000000..99e8eb1
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <style>
+            div { width: 250px; }
+            .container { 
+                background: green;
+                position: relative;
+                min-height: 200px;
+                height: 10%;
+            }
+            .box { 
+                height: 100px;
+                position: relative;
+                top: 50%;
+                background: blue;
+            }
+            .ref { 
+                height: 100px;
+                position: absolute;
+                top: 150px;
+                background: red;
+            }
+        </style>
+        <script src="../../resources/check-layout.js"></script>
+    </head>
+    <body onload="checkLayout('.box')">
+        <p>https://bugs.webkit.org/show_bug.cgi?id=14762: There should be no red below.</p>
+        <div class="container">
+            <div class="ref"></div>
+            <div class="box" data-total-y="0"></div>
+        </div>
+        <div class="container" style="-webkit-writing-mode: vertical-lr">
+            <div class="ref"></div>
+            <div class="box" data-total-y="100"></div>
+        </div>
+    </body>
+</html>
diff --git a/LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-expected.txt b/LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-expected.txt
new file mode 100644 (file)
index 0000000..dad0071
--- /dev/null
@@ -0,0 +1,6 @@
+The square below should be 100px by 100px. https://bugs.webkit.org/show_bug.cgi?id=103812 In strict mode, an image with height set to 100% and a fixed height ancestor should expand to its instrinsic height and width. Percentage height "is calculated with respect to the height of the generated box's containing block."
+
+
+
+PASS
+
diff --git a/LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr-expected.txt b/LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr-expected.txt
new file mode 100644 (file)
index 0000000..dad0071
--- /dev/null
@@ -0,0 +1,6 @@
+The square below should be 100px by 100px. https://bugs.webkit.org/show_bug.cgi?id=103812 In strict mode, an image with height set to 100% and a fixed height ancestor should expand to its instrinsic height and width. Percentage height "is calculated with respect to the height of the generated box's containing block."
+
+
+
+PASS
+
diff --git a/LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr.html b/LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr.html
new file mode 100644 (file)
index 0000000..afe09c2
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <style>
+        img { height: 100%; }
+        body { height: 400px; margin: 0px; padding: 0px; }
+    </style>
+    <script src="../../resources/check-layout.js"></script>
+</head>
+<body>
+    <p>The square below should be 100px by 100px.
+    https://bugs.webkit.org/show_bug.cgi?id=103812 
+    In strict mode, an image with height set to 100% and a fixed height ancestor should expand to its instrinsic height and width. 
+    Percentage height "is calculated with respect to the height of the generated box's containing block."  </p>
+    <br>
+    <div style="-webkit-writing-mode: vertical-lr;">
+        <img src="resources/square-blue-100x100.png" onload="checkLayout('img')" data-expected-height=100>
+    </div>
+</body>
+</html>
diff --git a/LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor.html b/LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor.html
new file mode 100644 (file)
index 0000000..5ba03f4
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <style>
+        img { height: 100%; }
+        body { height: 400px; }
+    </style>
+    <script src="../../resources/check-layout.js"></script>
+</head>
+<body>
+    <p>The square below should be 100px by 100px.
+    https://bugs.webkit.org/show_bug.cgi?id=103812 
+    In strict mode, an image with height set to 100% and a fixed height ancestor should expand to its instrinsic height and width. 
+    Percentage height "is calculated with respect to the height of the generated box's containing block."  </p>
+    <br>
+    <div>
+        <img src="resources/square-blue-100x100.png" onload="checkLayout('img')" data-expected-height=100>
+    </div>
+</body>
+</html>
diff --git a/LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-expected.txt b/LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-expected.txt
new file mode 100644 (file)
index 0000000..c9b9b92
--- /dev/null
@@ -0,0 +1,3 @@
+The square below should be 100px by 100px. 
+
+PASS
diff --git a/LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr-expected.txt b/LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr-expected.txt
new file mode 100644 (file)
index 0000000..c9b9b92
--- /dev/null
@@ -0,0 +1,3 @@
+The square below should be 100px by 100px. 
+
+PASS
diff --git a/LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr.html b/LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr.html
new file mode 100644 (file)
index 0000000..c0660ca
--- /dev/null
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <style>
+        img { height: 100%; }
+        div { display: table; height: auto; }
+        body { height: 400px; }
+    </style>
+    <script src="../../resources/check-layout.js"></script>
+</head>
+<body>
+    The square below should be 100px by 100px.
+    <!-- https://bugs.webkit.org/show_bug.cgi?id=103812 -->
+    <!-- In strict mode, an image with height set to 100% and a fixed height ancestor should expand to its instrinsic height and width. -->
+    <!-- Percentage height "is calculated with respect to the height of the generated box's containing block." --> 
+    <br>
+    <div style="-webkit-writing-mode: vertical-lr;">
+        <img src="resources/square-blue-100x100.png" onload="checkLayout('img')" data-expected-height=100>
+    </div>
+</body>
+</html>
diff --git a/LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor.html b/LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor.html
new file mode 100644 (file)
index 0000000..47cfeeb
--- /dev/null
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <style>
+        img { height: 100%; }
+        div { display: table; height: auto; }
+        body { height: 400px; }
+    </style>
+    <script src="../../resources/check-layout.js"></script>
+</head>
+<body>
+    The square below should be 100px by 100px.
+    <!-- https://bugs.webkit.org/show_bug.cgi?id=103812 -->
+    <!-- In strict mode, an image with height set to 100% and a fixed height ancestor should expand to its instrinsic height and width. -->
+    <!-- Percentage height "is calculated with respect to the height of the generated box's containing block." --> 
+    <br>
+    <div>
+        <img src="resources/square-blue-100x100.png" onload="checkLayout('img')" data-expected-height=100>
+    </div>
+</body>
+</html>
index d45e035..cd204ba 100644 (file)
@@ -1,3 +1,36 @@
+2013-02-16  Robert Hogan  <robert@webkit.org>
+
+        percentage top value of position:relative element not calculated using parent's min-height unless height set
+        https://bugs.webkit.org/show_bug.cgi?id=14762
+
+        Reviewed by Julien Chaffraix.
+
+        Percentage height "is calculated with respect to the height of the generated box's containing block" says  
+        http://www.w3.org/TR/CSS21/visudet.html#the-height-property and "If the height of the containing block is not 
+        specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the
+        value computes to 'auto'." So when calculating the used height of a replaced element do not crawl through ancestor 
+        blocks except when traversing anonymous blocks. Ensure that anonymous table cells are not skipped through though.
+
+        http://www.w3.org/TR/CSS21/tables.html#height-layout adds "In CSS 2.1, the height of a cell box is the minimum 
+        height required by the content." This height is decided by allowing table cells to report their height as auto.
+        It's not clear why http://trac.webkit.org/changeset/91242 decided it should no longer do this - doing so caused
+        us to regress in our rendering of computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor.html.
+
+        Tests: fast/block/percent-top-parent-respects-min-height.html
+               fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr.html
+               fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor.html
+               fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr.html
+               fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor.html
+
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::RenderBoxModelObject::hasAutoHeightOrContainingBlockWithAutoHeight):
+        (WebCore):
+        (WebCore::RenderBoxModelObject::relativePositionOffset):
+        * rendering/RenderBoxModelObject.h:
+        (RenderBoxModelObject):
+        * rendering/RenderReplaced.cpp:
+        (WebCore::RenderReplaced::hasReplacedLogicalHeight):
+
 2013-02-16  Stephen White  <senorblanco@chromium.org>
 
         [skia] FEOffset should have a Skia implementation.
index 3ddacfa..691c14b 100644 (file)
@@ -368,6 +368,31 @@ static LayoutSize accumulateInFlowPositionOffsets(const RenderObject* child)
     return offset;
 }
 
+bool RenderBoxModelObject::hasAutoHeightOrContainingBlockWithAutoHeight() const
+{
+    Length logicalHeightLength = style()->logicalHeight();
+    if (logicalHeightLength.isAuto())
+        return true;
+
+    // For percentage heights: The percentage is calculated with respect to the height of the generated box's
+    // containing block. If the height of the containing block is not specified explicitly (i.e., it depends
+    // on content height), and this element is not absolutely positioned, the value computes to 'auto'.
+    if (!logicalHeightLength.isPercent() || isOutOfFlowPositioned() || document()->inQuirksMode())
+        return false;
+
+    RenderBlock* cb = containingBlock(); 
+    while (cb->isAnonymousBlock()) {
+        if (cb->isTableCell())
+            return true;
+        cb = cb->containingBlock();
+    }
+
+    if (!cb->style()->logicalHeight().isAuto() || (!cb->style()->logicalTop().isAuto() && !cb->style()->logicalBottom().isAuto()))
+        return false;
+
+    return true;
+}
+
 LayoutSize RenderBoxModelObject::relativePositionOffset() const
 {
     LayoutSize offset = accumulateInFlowPositionOffsets(this);
@@ -394,13 +419,13 @@ LayoutSize RenderBoxModelObject::relativePositionOffset() const
     // calculate the percent offset based on this height.
     // See <https://bugs.webkit.org/show_bug.cgi?id=26396>.
     if (!style()->top().isAuto()
-        && (!containingBlock->style()->height().isAuto()
+        && (!containingBlock->hasAutoHeightOrContainingBlockWithAutoHeight()
             || !style()->top().isPercent()
             || containingBlock->stretchesToViewport()))
         offset.expand(0, valueForLength(style()->top(), containingBlock->availableHeight(), view()));
 
     else if (!style()->bottom().isAuto()
-        && (!containingBlock->style()->height().isAuto()
+        && (!containingBlock->hasAutoHeightOrContainingBlockWithAutoHeight()
             || !style()->bottom().isPercent()
             || containingBlock->stretchesToViewport()))
         offset.expand(0, -valueForLength(style()->bottom(), containingBlock->availableHeight(), view()));
index a32ed1e..bb70d46 100644 (file)
@@ -247,6 +247,8 @@ protected:
 
     static void clipRoundedInnerRect(GraphicsContext*, const LayoutRect&, const RoundedRect& clipRect);
 
+    bool hasAutoHeightOrContainingBlockWithAutoHeight() const;
+
 public:
     // For RenderBlocks and RenderInlines with m_style->styleType() == FIRST_LETTER, this tracks their remaining text fragments
     RenderObject* firstLetterRemainingText() const;
index 1fca9cd..2ffa006 100644 (file)
@@ -233,33 +233,13 @@ bool RenderReplaced::hasReplacedLogicalWidth() const
     return firstContainingBlockWithLogicalWidth(this);
 }
 
-static inline bool hasAutoHeightOrContainingBlockWithAutoHeight(const RenderReplaced* replaced)
-{
-    Length logicalHeightLength = replaced->style()->logicalHeight();
-    if (logicalHeightLength.isAuto())
-        return true;
-
-    // For percentage heights: The percentage is calculated with respect to the height of the generated box's
-    // containing block. If the height of the containing block is not specified explicitly (i.e., it depends
-    // on content height), and this element is not absolutely positioned, the value computes to 'auto'.
-    if (!logicalHeightLength.isPercent() || replaced->isOutOfFlowPositioned() || replaced->document()->inQuirksMode())
-        return false;
-
-    for (RenderBlock* cb = replaced->containingBlock(); !cb->isRenderView(); cb = cb->containingBlock()) {
-        if (cb->isTableCell() || (!cb->style()->logicalHeight().isAuto() || (!cb->style()->top().isAuto() && !cb->style()->bottom().isAuto())))
-            return false;
-    }
-
-    return true;
-}
-
 bool RenderReplaced::hasReplacedLogicalHeight() const
 {
     if (style()->logicalHeight().isAuto())
         return false;
 
     if (style()->logicalHeight().isSpecified()) {
-        if (hasAutoHeightOrContainingBlockWithAutoHeight(this))
+        if (hasAutoHeightOrContainingBlockWithAutoHeight())
             return false;
         return true;
     }