Positioned, replaced elements with intrinsic width keywords compute the wrong width
authorojan@chromium.org <ojan@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Feb 2013 01:07:56 +0000 (01:07 +0000)
committerojan@chromium.org <ojan@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Feb 2013 01:07:56 +0000 (01:07 +0000)
https://bugs.webkit.org/show_bug.cgi?id=110393

Reviewed by Emil A Eklund.

Source/WebCore:

Test: fast/css-intrinsic-dimensions/intrinsic-sized-replaced-absolutes.html

* rendering/RenderBox.cpp:
(WebCore::RenderBox::computeReplacedLogicalWidthUsing):
Add the intrinsic size keywords to the switch. Confusingly, we have to
subtract the border and padding since the callers expect the content width.

* rendering/RenderReplaced.cpp:
(WebCore::RenderReplaced::computeReplacedLogicalWidth):
Don't do the intrinsic ratio calculation if the width is an
intrinsic width keyword, as per, http://dev.w3.org/csswg/css3-sizing/#replaced-intrinsic.

(WebCore::RenderReplaced::computeIntrinsicLogicalWidths):
(WebCore::RenderReplaced::computePreferredLogicalWidths):
The old code was trying to apply the intrinsic ratio calculation to
the intrinsic width, which is wrong per spec.

LayoutTests:

* fast/css-intrinsic-dimensions/intrinsic-sized-replaced-absolutes-expected.txt: Added.
* fast/css-intrinsic-dimensions/intrinsic-sized-replaced-absolutes.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-replaced-absolutes-expected.txt [new file with mode: 0644]
LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-replaced-absolutes.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderBox.cpp
Source/WebCore/rendering/RenderReplaced.cpp

index bc4e5c5..c83eaa7 100644 (file)
@@ -1,3 +1,13 @@
+2013-02-20  Ojan Vafai  <ojan@chromium.org>
+
+        Positioned, replaced elements with intrinsic width keywords compute the wrong width
+        https://bugs.webkit.org/show_bug.cgi?id=110393
+
+        Reviewed by Emil A Eklund.
+
+        * fast/css-intrinsic-dimensions/intrinsic-sized-replaced-absolutes-expected.txt: Added.
+        * fast/css-intrinsic-dimensions/intrinsic-sized-replaced-absolutes.html: Added.
+
 2013-02-20  Simon Fraser  <simon.fraser@apple.com>
 
         Zoomed, slow-scrolling pages keep recreating tiles when scrolled
diff --git a/LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-replaced-absolutes-expected.txt b/LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-replaced-absolutes-expected.txt
new file mode 100644 (file)
index 0000000..af2f668
--- /dev/null
@@ -0,0 +1,31 @@
+Tests that intrinsic width values on absolutely positioned element work.
+
+PASS
+
+PASS
+
+PASS
+
+PASS
+
+PASS
+
+PASS
+
+PASS
+
+PASS
+
+PASS
+
+PASS
+
+PASS
+
+PASS
+
+PASS
+
+PASS
+
+PASS
diff --git a/LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-replaced-absolutes.html b/LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-replaced-absolutes.html
new file mode 100644 (file)
index 0000000..84fc0d5
--- /dev/null
@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<style>
+.container {
+    position:relative;
+    border: 5px solid blue;
+    width: 350px;
+    height: 350px;
+}
+.child {
+    position:absolute;
+    border: 5px solid pink;
+}
+</style>
+
+Tests that intrinsic width values on absolutely positioned element work.
+
+<!-- The 310px expected values are the 300px intrinsic width of an iframe plus 10px of border.
+    The 350px expected values are the iframe filling the 350px available width from the container.
+-->
+
+<!-- width tests -->
+<div class="container">
+    <iframe class="child" style="width: -webkit-max-content;" data-expected-width="310"></iframe>
+</div>
+
+<div class="container">
+    <iframe class="child" style="width: -webkit-min-content;" data-expected-width="310"></iframe>
+</div>
+
+<div class="container">
+    <iframe class="child" style="width: -webkit-fit-content;" data-expected-width="310"></iframe>
+</div>
+
+<div class="container" style="width: 50px">
+    <iframe class="child" style="width: -webkit-fit-content;" data-expected-width="310"></iframe>
+</div>
+
+<div class="container">
+    <iframe class="child" style="width: -webkit-fill-available;" data-expected-width="350"></iframe>
+</div>
+
+<!-- min-width tests -->
+<div class="container">
+    <iframe class="child" style="min-width: -webkit-max-content; width: 10px;" data-expected-width="310"></iframe>
+</div>
+
+<div class="container">
+    <iframe class="child" style="min-width: -webkit-min-content; width: 10px;" data-expected-width="310"></iframe>
+</div>
+
+<div class="container">
+    <iframe class="child" style="min-width: -webkit-fit-content; width: 10px;" data-expected-width="310"></iframe>
+</div>
+
+<div class="container" style="width: 50px">
+    <iframe class="child" style="min-width: -webkit-fit-content; width: 10px;" data-expected-width="310"></iframe>
+</div>
+
+<div class="container">
+    <iframe class="child" style="min-width: -webkit-fill-available; width: 10px;" data-expected-width="350"></iframe>
+</div>
+
+<!-- max-width tests -->
+<div class="container">
+    <iframe class="child" style="max-width: -webkit-max-content; width: 1000px;" data-expected-width="310"></iframe>
+</div>
+
+<div class="container">
+    <iframe class="child" style="max-width: -webkit-min-content; width: 1000px;" data-expected-width="310"></iframe>
+</div>
+
+<div class="container">
+    <iframe class="child" style="max-width: -webkit-fit-content; width: 1000px;" data-expected-width="310"></iframe>
+</div>
+
+<div class="container" style="width: 50px">
+    <iframe class="child" style="max-width: -webkit-fit-content; width: 1000px;" data-expected-width="310"></iframe>
+</div>
+
+<div class="container">
+    <iframe class="child" style="max-width: -webkit-fill-available; width: 1000px;" data-expected-width="350"></iframe>
+</div>
+
+<script src="../../resources/check-layout.js"></script>
+<script>
+checkLayout(".container");
+</script>
index e80d63f..9aafb56 100644 (file)
@@ -1,3 +1,27 @@
+2013-02-20  Ojan Vafai  <ojan@chromium.org>
+
+        Positioned, replaced elements with intrinsic width keywords compute the wrong width
+        https://bugs.webkit.org/show_bug.cgi?id=110393
+
+        Reviewed by Emil A Eklund.
+
+        Test: fast/css-intrinsic-dimensions/intrinsic-sized-replaced-absolutes.html
+
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::computeReplacedLogicalWidthUsing):
+        Add the intrinsic size keywords to the switch. Confusingly, we have to
+        subtract the border and padding since the callers expect the content width.
+
+        * rendering/RenderReplaced.cpp:
+        (WebCore::RenderReplaced::computeReplacedLogicalWidth):
+        Don't do the intrinsic ratio calculation if the width is an
+        intrinsic width keyword, as per, http://dev.w3.org/csswg/css3-sizing/#replaced-intrinsic.
+
+        (WebCore::RenderReplaced::computeIntrinsicLogicalWidths):
+        (WebCore::RenderReplaced::computePreferredLogicalWidths):
+        The old code was trying to apply the intrinsic ratio calculation to
+        the intrinsic width, which is wrong per spec.
+
 2013-02-20  Alec Flett  <alecflett@chromium.org>
 
         LevelDB: Remove excess vector copy
index d21267f..73587aa 100644 (file)
@@ -2588,11 +2588,19 @@ LayoutUnit RenderBox::computeReplacedLogicalWidthUsing(SizeType sizeType, Length
     switch (logicalWidth.type()) {
         case Fixed:
             return adjustContentBoxLogicalWidthForBoxSizing(logicalWidth.value());
+        case MinContent:
+        case MaxContent: {
+            // MinContent/MaxContent don't need the availableLogicalWidth argument.
+            LayoutUnit availableLogicalWidth = 0;
+            return computeIntrinsicLogicalWidthUsing(logicalWidth, availableLogicalWidth) - borderAndPaddingLogicalWidth();
+        }
         case ViewportPercentageWidth:
         case ViewportPercentageHeight:
         case ViewportPercentageMin:
         case ViewportPercentageMax:
             return adjustContentBoxLogicalWidthForBoxSizing(valueForLength(logicalWidth, 0, view()));
+        case FitContent:
+        case FillAvailable:
         case Percent: 
         case Calculated: {
             // FIXME: containingBlockLogicalWidthForContent() is wrong if the replaced element's block-flow is perpendicular to the
@@ -2602,11 +2610,17 @@ LayoutUnit RenderBox::computeReplacedLogicalWidthUsing(SizeType sizeType, Length
             Length containerLogicalWidth = containingBlock()->style()->logicalWidth();
             // FIXME: Handle cases when containing block width is calculated or viewport percent.
             // https://bugs.webkit.org/show_bug.cgi?id=91071
+            if (logicalWidth.isIntrinsic())
+                return computeIntrinsicLogicalWidthUsing(logicalWidth, cw) - borderAndPaddingLogicalWidth();
             if (cw > 0 || (!cw && (containerLogicalWidth.isFixed() || containerLogicalWidth.isPercent())))
                 return adjustContentBoxLogicalWidthForBoxSizing(minimumValueForLength(logicalWidth, cw));
         }
         // fall through
-        default:
+        case Intrinsic:
+        case MinIntrinsic:
+        case Auto:
+        case Relative:
+        case Undefined:
             return intrinsicLogicalWidth();
      }
 }
index 2ffa006..3be91bb 100644 (file)
@@ -319,7 +319,7 @@ void RenderReplaced::computeIntrinsicRatioInformation(FloatSize& intrinsicSize,
 
 LayoutUnit RenderReplaced::computeReplacedLogicalWidth(ShouldComputePreferred shouldComputePreferred) const
 {
-    if (style()->logicalWidth().isSpecified())
+    if (style()->logicalWidth().isSpecified() || style()->logicalWidth().isIntrinsic())
         return computeReplacedLogicalWidthRespectingMinMaxWidth(computeReplacedLogicalWidthUsing(MainOrPreferredSize, style()->logicalWidth()), shouldComputePreferred);
 
     RenderBox* contentRenderer = embeddedContentBox();
@@ -421,16 +421,19 @@ LayoutUnit RenderReplaced::computeReplacedLogicalHeight() const
 
 void RenderReplaced::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
 {
-    // We cannot resolve any percent logical width here as the available logical
-    // width may not be set on our containing block.
-    minLogicalWidth = maxLogicalWidth = style()->logicalWidth().isPercent() ? intrinsicLogicalWidth() : computeReplacedLogicalWidth(ComputePreferred);
+    minLogicalWidth = maxLogicalWidth = intrinsicLogicalWidth();
 }
 
 void RenderReplaced::computePreferredLogicalWidths()
 {
     ASSERT(preferredLogicalWidthsDirty());
 
-    computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
+    // We cannot resolve any percent logical width here as the available logical
+    // width may not be set on our containing block.
+    if (style()->logicalWidth().isPercent())
+        computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
+    else
+        m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = computeReplacedLogicalWidth(ComputePreferred);
 
     RenderStyle* styleToUse = style();
     if (styleToUse->logicalWidth().isPercent() || styleToUse->logicalMaxWidth().isPercent() || hasRelativeIntrinsicLogicalWidth())