Added: trunk/LayoutTests/fast/replaced/table-percent-width.html (0 => 97525)
--- trunk/LayoutTests/fast/replaced/table-percent-width.html (rev 0)
+++ trunk/LayoutTests/fast/replaced/table-percent-width.html 2011-10-14 22:49:25 UTC (rev 97525)
@@ -0,0 +1,115 @@
+<html>
+<head>
+<title> webkit.org/b/29447: Replaced elements squeezed when width is specified as percentage inside a table with Auto layout</title>
+<link rel="stylesheet" href=""
+<script src=""
+<script src=""
+<script>
+if (window.layoutTestController) {
+ layoutTestController.waitUntilDone();
+ layoutTestController.dumpAsText();
+}
+
+function getComputedStyleForElement(element, cssPropertyName)
+{
+ if (!element) {
+ return null;
+ }
+ if (window.getComputedStyle) {
+ return window.getComputedStyle(element, '').getPropertyValue(cssPropertyName.replace(/([A-Z])/g, "-$1").toLowerCase());
+ }
+ if (element.currentStyle) {
+ return element.currentStyle[cssPropertyName];
+ }
+ return null;
+}
+
+function getWidth(id)
+{
+ return getComputedStyleForElement(document.getElementById(id), 'width');
+}
+
+function getHeight(id)
+{
+ return getComputedStyleForElement(document.getElementById(id), 'height');
+}
+
+function parsePixelValue(str)
+{
+ if (typeof str != "string" || str.length < 3 || str.substr(str.length - 2) != "px") {
+ testFailed(str + " is unparsable.");
+ return -1;
+ }
+ return parseFloat(str);
+}
+
+function test()
+{
+ description("This test checks that a replaced element with percentage width (and no height specified) within a table cell is squeezed to the dimensions of the table cell.<br>See bug #29447.");
+
+ shouldBe("getWidth('img-1')", "'105px'");
+ shouldBe("getHeight('img-1')", "'105px'");
+ shouldBe("getWidth('img-2')", "'98px'");
+ shouldBe("getHeight('img-2')", "'98px'");
+ shouldBe("getWidth('img-3')", "'40px'");
+ shouldBe("getHeight('img-3')", "'40px'");
+ shouldBe("getWidth('img-4')", "'36px'");
+ shouldBe("getHeight('img-4')", "'36px'");
+ shouldBe("getWidth('img-5')", "'40px'");
+ shouldBe("getHeight('img-5')", "'36px'");
+
+ isSuccessfullyParsed();
+
+ if (window.layoutTestController) {
+ layoutTestController.notifyDone();
+ }
+}
+
+var successfullyParsed = true;
+</script>
+</head>
+<body _onload_="test()">
+ <table>
+ <tr>
+ <td>
+ <img id="img-1" src="" width="100%" align="LEFT" border="1">
+ </td>
+ </tr>
+ </table>
+
+ <table>
+ <tr>
+ <td>
+ <img id="img-2" src="" height="100%" align="LEFT" border="1">
+ </td>
+ </tr>
+ </table>
+
+ <table height="50" width="50" border="1">
+ <tr>
+ <td>
+ <img id="img-3" src="" width="100%" align="LEFT" border="1">
+ </td>
+ </tr>
+ </table>
+
+ <table height="50" width="50" border="1">
+ <tr>
+ <td>
+ <img id="img-4" src="" height="100%" align="LEFT" border="1">
+ </td>
+ </tr>
+ </table>
+
+ <table height="50" width="50" border="1">
+ <tr>
+ <td>
+ <img id="img-5" src="" width="100%" height="100%" align="LEFT" border="1">
+ </td>
+ </tr>
+ </table>
+
+<p id="description"></p>
+<div id="console"></div>
+</body>
+</html>
Property changes on: trunk/LayoutTests/fast/replaced/table-percent-width.html
___________________________________________________________________
Modified: trunk/LayoutTests/platform/chromium-win/fast/replaced/table-percent-height-expected.txt (97524 => 97525)
--- trunk/LayoutTests/platform/chromium-win/fast/replaced/table-percent-height-expected.txt 2011-10-14 22:45:54 UTC (rev 97524)
+++ trunk/LayoutTests/platform/chromium-win/fast/replaced/table-percent-height-expected.txt 2011-10-14 22:49:25 UTC (rev 97525)
@@ -4,6 +4,8 @@
+
+
Button
Button
@@ -22,87 +24,60 @@
-
-
-This is a searchable index. Enter search keywords:
-This is a searchable index. Enter search keywords:
-
-
-
-
This test checks that replaced elements with percentage heights within table cells have the correct height.
+Note, some of the button height tests fail on the Windows ports. See bug #34071.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-PASS getComputedStyleForElement(document.getElementById('canvas-75'), 'width') is '300px'
-PASS getComputedStyleForElement(document.getElementById('canvas-75'), 'height') is '112px'
-PASS getComputedStyleForElement(document.getElementById('canvas-100'), 'width') is '300px'
-PASS getComputedStyleForElement(document.getElementById('canvas-100'), 'height') is '150px'
-PASS getComputedStyleForElement(document.getElementById('embed-75'), 'width') is '300px'
-PASS getComputedStyleForElement(document.getElementById('embed-75'), 'height') is '112px'
-PASS getComputedStyleForElement(document.getElementById('embed-100'), 'width') is '300px'
-PASS getComputedStyleForElement(document.getElementById('embed-100'), 'height') is '150px'
-PASS getComputedStyleForElement(document.getElementById('img-75'), 'width') is '75px'
-PASS getComputedStyleForElement(document.getElementById('img-75'), 'height') is '75px'
-PASS getComputedStyleForElement(document.getElementById('img-100'), 'width') is '100px'
-PASS getComputedStyleForElement(document.getElementById('img-100'), 'height') is '100px'
-PASS getComputedStyleForElement(document.getElementById('object-75'), 'width') is '300px'
-PASS getComputedStyleForElement(document.getElementById('object-75'), 'height') is '112px'
-PASS getComputedStyleForElement(document.getElementById('object-100'), 'width') is '300px'
-PASS getComputedStyleForElement(document.getElementById('object-100'), 'height') is '150px'
-PASS getComputedStyleForElement(document.getElementById('button-75'), 'width') is '51px'
-PASS getComputedStyleForElement(document.getElementById('button-75'), 'height') is '15px'
-PASS getComputedStyleForElement(document.getElementById('button-100'), 'width') is '51px'
-PASS getComputedStyleForElement(document.getElementById('button-100'), 'height') is '15px'
-PASS getComputedStyleForElement(document.getElementById('input-button-75'), 'width') is '16px'
-PASS getComputedStyleForElement(document.getElementById('input-button-75'), 'height') is '18px'
-PASS getComputedStyleForElement(document.getElementById('input-button-100'), 'width') is '16px'
-PASS getComputedStyleForElement(document.getElementById('input-button-100'), 'height') is '18px'
-PASS getComputedStyleForElement(document.getElementById('input-checkbox-75'), 'width') is '12px'
-PASS getComputedStyleForElement(document.getElementById('input-checkbox-75'), 'height') is '4px'
-PASS getComputedStyleForElement(document.getElementById('input-checkbox-100'), 'width') is '12px'
-PASS getComputedStyleForElement(document.getElementById('input-checkbox-100'), 'height') is '6px'
-PASS getComputedStyleForElement(document.getElementById('input-file-75'), 'width') is '237px'
-PASS getComputedStyleForElement(document.getElementById('input-file-75'), 'height') is '13px'
-PASS getComputedStyleForElement(document.getElementById('input-file-100'), 'width') is '237px'
-PASS getComputedStyleForElement(document.getElementById('input-file-100'), 'height') is '18px'
-PASS getComputedStyleForElement(document.getElementById('input-image-75'), 'width') is '75px'
-PASS getComputedStyleForElement(document.getElementById('input-image-75'), 'height') is '75px'
-PASS getComputedStyleForElement(document.getElementById('input-image-100'), 'width') is '100px'
-PASS getComputedStyleForElement(document.getElementById('input-image-100'), 'height') is '100px'
-FAIL getComputedStyleForElement(document.getElementById('input-password-75'), 'width') should be 148px. Was 146px.
-PASS getComputedStyleForElement(document.getElementById('input-password-75'), 'height') is '8px'
-FAIL getComputedStyleForElement(document.getElementById('input-password-100'), 'width') should be 148px. Was 146px.
-PASS getComputedStyleForElement(document.getElementById('input-password-100'), 'height') is '13px'
-PASS getComputedStyleForElement(document.getElementById('input-radio-75'), 'width') is '12px'
-FAIL getComputedStyleForElement(document.getElementById('input-radio-75'), 'height') should be 4px. Was 2px.
-PASS getComputedStyleForElement(document.getElementById('input-radio-100'), 'width') is '12px'
-FAIL getComputedStyleForElement(document.getElementById('input-radio-100'), 'height') should be 6px. Was 3px.
-PASS getComputedStyleForElement(document.getElementById('input-reset-75'), 'width') is '45px'
-PASS getComputedStyleForElement(document.getElementById('input-reset-75'), 'height') is '18px'
-PASS getComputedStyleForElement(document.getElementById('input-reset-100'), 'width') is '45px'
-PASS getComputedStyleForElement(document.getElementById('input-reset-100'), 'height') is '18px'
-PASS getComputedStyleForElement(document.getElementById('input-submit-75'), 'width') is '54px'
-PASS getComputedStyleForElement(document.getElementById('input-submit-75'), 'height') is '18px'
-PASS getComputedStyleForElement(document.getElementById('input-submit-100'), 'width') is '54px'
-PASS getComputedStyleForElement(document.getElementById('input-submit-100'), 'height') is '18px'
-FAIL getComputedStyleForElement(document.getElementById('input-text-75'), 'width') should be 148px. Was 146px.
-PASS getComputedStyleForElement(document.getElementById('input-text-75'), 'height') is '8px'
-FAIL getComputedStyleForElement(document.getElementById('input-text-100'), 'width') should be 148px. Was 146px.
-PASS getComputedStyleForElement(document.getElementById('input-text-100'), 'height') is '13px'
-PASS getComputedStyleForElement(document.getElementById('isindex-75'), 'width') is '142px'
-PASS getComputedStyleForElement(document.getElementById('isindex-75'), 'height') is '13px'
-PASS getComputedStyleForElement(document.getElementById('isindex-100'), 'width') is '142px'
-PASS getComputedStyleForElement(document.getElementById('isindex-100'), 'height') is '13px'
-PASS getComputedStyleForElement(document.getElementById('select-75'), 'width') is '68px'
-PASS getComputedStyleForElement(document.getElementById('select-75'), 'height') is '18px'
-PASS getComputedStyleForElement(document.getElementById('select-100'), 'width') is '68px'
-PASS getComputedStyleForElement(document.getElementById('select-100'), 'height') is '18px'
-PASS getComputedStyleForElement(document.getElementById('textarea-75'), 'width') is '163px'
-PASS getComputedStyleForElement(document.getElementById('textarea-75'), 'height') is '19px'
-PASS getComputedStyleForElement(document.getElementById('textarea-100'), 'width') is '163px'
-PASS getComputedStyleForElement(document.getElementById('textarea-100'), 'height') is '26px'
+PASS getWidth('canvas-75') is '224px'
+PASS getHeight('canvas-75') is '112px'
+PASS getWidth('canvas-100') is '300px'
+PASS getHeight('canvas-100') is '150px'
+PASS getWidth('embed-75') is '300px'
+PASS getHeight('embed-75') is '112px'
+PASS getWidth('embed-100') is '300px'
+PASS getHeight('embed-100') is '150px'
+PASS getWidth('img-75') is '75px'
+PASS getHeight('img-75') is '75px'
+PASS getWidth('img-100') is '100px'
+PASS getHeight('img-100') is '100px'
+PASS getWidth('img-75-nested') is '75px'
+PASS getHeight('img-75-nested') is '75px'
+PASS getWidth('img-100-nested') is '100px'
+PASS getHeight('img-100-nested') is '100px'
+PASS getWidth('object-75') is '300px'
+PASS getHeight('object-75') is '112px'
+PASS getWidth('object-100') is '300px'
+PASS getHeight('object-100') is '150px'
+PASS getWidth('button-75') is getWidth('button-100')
+PASS getHeight('button-75') != '0px' is true
+FAIL getHeight('button-75') should be 16px. Was 10px.
+PASS getWidth('input-button-75') is getWidth('input-button-100')
+PASS getHeight('input-button-75') != '0px' is true
+FAIL getHeight('input-button-75') should be 16px. Was 10px.
+PASS getWidth('input-checkbox-75') is getWidth('input-checkbox-100')
+PASS getHeight('input-checkbox-75') != '0px' is true
+PASS getHeight('input-checkbox-75') is 75% of getHeight('input-checkbox-100').
+PASS getWidth('input-file-75') is getWidth('input-file-100')
+PASS getHeight('input-file-75') != '0px' is true
+PASS getHeight('input-file-75') is 75% of getHeight('input-file-100').
+PASS getWidth('input-image-75') is '75px'
+PASS getHeight('input-image-75') is '75px'
+PASS getWidth('input-image-100') is '100px'
+PASS getHeight('input-image-100') is '100px'
+PASS getWidth('input-radio-75') is getWidth('input-radio-100')
+PASS getHeight('input-radio-75') != '0px' is true
+PASS getHeight('input-radio-75') is 75% of getHeight('input-radio-100').
+PASS getWidth('input-reset-75') is getWidth('input-reset-100')
+PASS getHeight('input-reset-75') != '0px' is true
+FAIL getHeight('input-reset-75') should be 16px. Was 10px.
+PASS getWidth('input-submit-75') is getWidth('input-submit-100')
+PASS getHeight('input-submit-75') != '0px' is true
+FAIL getHeight('input-submit-75') should be 16px. Was 10px.
+PASS getWidth('select-75') is getWidth('select-100')
+PASS getHeight('select-75') != '0px' is true
+FAIL getHeight('select-75') should be 18px. Was 13px.
PASS successfullyParsed is true
TEST COMPLETE
Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (97524 => 97525)
--- trunk/Source/WebCore/rendering/RenderBox.cpp 2011-10-14 22:45:54 UTC (rev 97524)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp 2011-10-14 22:49:25 UTC (rev 97525)
@@ -1271,6 +1271,39 @@
return clipRect;
}
+enum IntrinsicDimension { LogicalHeightDimension, LogicalWidthDimension };
+
+static bool shouldExpandToIntrinsicDimension(RenderBlock* cb, IntrinsicDimension dimension)
+{
+ // This function allows images to size correctly to their intrinsic height/width when inside table cells
+ // that only have percent or auto height/width.
+ // It's only interested in inspecting as far as the containing table, if there is one.
+ bool inTableCell = false;
+ while (cb && !cb->isRenderView()) {
+ if (cb->isTableCell())
+ inTableCell = true;
+
+ if (dimension == LogicalHeightDimension && !cb->style()->logicalHeight().isAuto() && !cb->style()->logicalHeight().isPercent())
+ return false;
+ if (dimension == LogicalWidthDimension && !cb->style()->logicalWidth().isAuto() && !cb->style()->logicalWidth().isPercent())
+ return false;
+
+ if (cb->isTable())
+ break;
+
+ cb = cb->containingBlock();
+ }
+ return inTableCell;
+}
+
+LayoutUnit RenderBox::containingBlockReplacedLogicalWidthForContent() const
+{
+ RenderBlock* cb = containingBlock();
+ if (shouldExpandToIntrinsicDimension(cb, LogicalWidthDimension))
+ return max(shrinkToAvoidFloats() ? cb->availableLogicalWidthForLine(logicalTop(), false) : cb->availableLogicalWidth(), intrinsicLogicalWidth());
+ return containingBlockLogicalWidthForContent();
+}
+
LayoutUnit RenderBox::containingBlockLogicalWidthForContent() const
{
RenderBlock* cb = containingBlock();
@@ -2177,7 +2210,7 @@
// FIXME: containingBlockLogicalWidthForContent() is wrong if the replaced element's block-flow is perpendicular to the
// containing block's block-flow.
// https://bugs.webkit.org/show_bug.cgi?id=46496
- const LayoutUnit cw = isPositioned() ? containingBlockLogicalWidthForPositioned(toRenderBoxModelObject(container())) : containingBlockLogicalWidthForContent();
+ const LayoutUnit cw = isPositioned() ? containingBlockLogicalWidthForPositioned(toRenderBoxModelObject(container())) : containingBlockReplacedLogicalWidthForContent();
if (cw > 0)
return computeContentBoxLogicalWidth(logicalWidth.calcMinValue(cw));
}
@@ -2237,14 +2270,9 @@
// table cells using percentage heights.
// FIXME: This needs to be made block-flow-aware. If the cell and image are perpendicular block-flows, this isn't right.
// https://bugs.webkit.org/show_bug.cgi?id=46997
- while (cb && !cb->isRenderView() && (cb->style()->logicalHeight().isAuto() || cb->style()->logicalHeight().isPercent())) {
- if (cb->isTableCell()) {
- // Don't let table cells squeeze percent-height replaced elements
- // <http://bugs.webkit.org/show_bug.cgi?id=15359>
- availableHeight = max(availableHeight, intrinsicLogicalHeight());
- return logicalHeight.calcValue(availableHeight - borderAndPaddingLogicalHeight());
- }
- cb = cb->containingBlock();
+ if (shouldExpandToIntrinsicDimension(toRenderBlock(cb), LogicalHeightDimension)) {
+ availableHeight = max(availableHeight, intrinsicLogicalHeight());
+ return logicalHeight.calcValue(availableHeight - borderAndPaddingLogicalHeight());
}
}
return computeContentBoxLogicalHeight(logicalHeight.calcValue(availableHeight));