Commit 6c6315ec authored by robhogan's avatar robhogan Committed by Commit bot

Percent height border-box content should get correct height in percent height cells

"For the purpose of calculating [the minimum height of a row],
descendants of table cells whose height depends on percentages
of their parent cell's height are considered to have an auto
height if they have overflow set to visible or hidden or if
they are replaced elements, and a 0px height if they have not."

This CL does two things re this rule:

- It ensures we respect it for replaced elements, including ones that aren't
  LayoutReplaced or isReplaced() objects. This is covered by the table-percent-
  height-* tests.
- It ensures we always obey it for hidden/visible overflow elements.

The CL also does two other things:

- If the cell doesn't have a specified height then treat it as auto for the
  purposes of calculating percent heights of its children. See bug
  671010 for the discussion that leads to this approach - soon to be specified
  we hope.
  Note that this results in the new behaviour of the form control elements in
  table-percent-height-* tests: they size as they would if they were in auto-
  sized <div>. Again, see bug 671010.
  We introduce a 'regression' in the behaviour of radio/select elements when
  percent-sized inside a cell that has no specified height - they now behave
  the same as radio/select elements when inside a div with auto height, they
  get a zero height. This is covered specifically in input-radio-height-inside-auto-container.html.
  It can also be seen in the updates to table-percent-height.html.

- If we've computed the height of a cell's child using the height made available
  by the cell, then be sure to respect content-/border-sizing of the child. We
  were just assuming that children were always content-sized. These are covered
  by the percent-height-border-box-content-* tests and are the main fall-out
  in 669867.

BUG=669867, 671010

Review-Url: https://codereview.chromium.org/2535173006
Cr-Commit-Position: refs/heads/master@{#438652}
parent 47fb891d
...@@ -1212,6 +1212,14 @@ crbug.com/306222 fast/hidpi/image-srcset-relative-svg-canvas-2x.html [ Skip ] ...@@ -1212,6 +1212,14 @@ crbug.com/306222 fast/hidpi/image-srcset-relative-svg-canvas-2x.html [ Skip ]
crbug.com/467477 fast/multicol/vertical-rl/nested-columns.html [ Failure ] crbug.com/467477 fast/multicol/vertical-rl/nested-columns.html [ Failure ]
crbug.com/674225 [ Mac ] fast/replaced/input-radio-height-inside-auto-container.html [ Failure ]
crbug.com/669867 [ Mac Win ] fast/replaced/table-percent-height-text-controls.html [ NeedsRebaseline ]
crbug.com/669867 [ Mac Win ] fast/replaced/table-percent-height.html [ NeedsRebaseline ]
crbug.com/669867 [ Mac Win ] fast/table/003.html [ NeedsRebaseline ]
crbug.com/669867 [ Mac Win ] fast/table/split-table-section-before-anonymous-block-2.html [ NeedsRebaseline ]
crbug.com/669867 [ Mac Win ] fast/table/split-table-section-before-anonymous-block-4.html [ NeedsRebaseline ]
crbug.com/669867 [ Mac Win ] tables/mozilla/bugs/bug30692.html [ NeedsRebaseline ]
crbug.com/400841 media/video-canvas-draw.html [ Failure ] crbug.com/400841 media/video-canvas-draw.html [ Failure ]
crbug.com/400829 media/video-object-fit.html [ Failure ] crbug.com/400829 media/video-object-fit.html [ Failure ]
crbug.com/400829 virtual/stable/media/stable/video-object-fit-stable.html [ Failure ] crbug.com/400829 virtual/stable/media/stable/video-object-fit-stable.html [ Failure ]
......
<!DOCTYPE html>
<p> crbug.com/669867: Inputs and radio boxes get a height of 0 when their container's height is treated as auto. There should be nothing below on Linux and Win. The theme on Mac gives them a full height.</p>
<!DOCTYPE html>
<p> crbug.com/669867: Inputs and radio boxes get a height of 0 when their container's height is treated as auto. There should be nothing below on Linux and Win. The theme on Mac gives them a full height.</p>
<div><input type="checkbox" style="height: 100%;"><div>
<div style="display:table-cell;"><input type="checkbox" style="height: 100%;"><div>
<table><tr><td><input type="checkbox" style="height: 100%;"></td></tr></table>
<div><input type="radio" style="height: 100%;"><div>
<div style="display:table-cell;"><input type="radio" style="height: 100%;"><div>
<table><tr><td><input type="radio" style="height: 100%;"></td></tr></table>
...@@ -30,11 +30,7 @@ function getWidth(id) ...@@ -30,11 +30,7 @@ function getWidth(id)
function getFullHeight(id) function getFullHeight(id)
{ {
var element = document.getElementById(id); var element = document.getElementById(id);
var h = parseFloat(getComputedStyleForElement(element, 'border-top-width')); var h = parseFloat(getComputedStyleForElement(element, 'height'));
h += parseFloat(getComputedStyleForElement(element, 'padding-top'));
h += parseFloat(getComputedStyleForElement(element, 'height'));
h += parseFloat(getComputedStyleForElement(element, 'padding-bottom'));
h += parseFloat(getComputedStyleForElement(element, 'border-bottom-width'));
return h + 'px'; return h + 'px';
} }
...@@ -47,39 +43,24 @@ function parsePixelValue(str) ...@@ -47,39 +43,24 @@ function parsePixelValue(str)
return parseFloat(str); return parseFloat(str);
} }
function is75PercentOf(expression75, expression100)
{
var str75 = eval(expression75);
var str100 = eval(expression100);
var num75 = parsePixelValue(str75);
var num100 = parsePixelValue(str100);
if (num75 < 0 || num100 < 0)
return;
if (num75 == Math.floor(num100 * 75 / 100))
testPassed(expression75 + " is 75% of " + expression100 + ".");
else
testFailed(expression75 + " [" + str75 + "] is not 75% of " + expression100 + " [" + str100 + "].");
}
function test() function test()
{ {
description("This test checks that text controls with percentage heights within table cells have the correct height." + description("This test checks that text controls with percentage heights within table cells have the correct height." +
"Text controls are in a different test than other replaced elements because their metrics are platform-specific."); "Text controls are in a different test than other replaced elements because their metrics are platform-specific." +
"The reason a 75% control is the same height as a 100% control is because a replaced element that depends on the" +
"height of its parent cell is treated as auto. So by itself it will set the height of the row. See https://drafts.csswg.org/css-tables-3/#row-layout");
shouldBe("getWidth('input-password-75')", "getWidth('input-password-100')"); shouldBe("getWidth('input-password-75')", "getWidth('input-password-100')");
shouldBeTrue("getFullHeight('input-password-75') != '0px'"); shouldBeTrue("getFullHeight('input-password-75') != '0px'");
// Note: This behavior doesn't match to IE 8, Firefox 3.5 and Opera 10. shouldBe("getFullHeight('input-password-75')", "getFullHeight('input-password-100')");
is75PercentOf("getFullHeight('input-password-75')", "getFullHeight('input-password-100')");
shouldBe("getWidth('input-text-75')", "getWidth('input-text-100')"); shouldBe("getWidth('input-text-75')", "getWidth('input-text-100')");
shouldBeTrue("getFullHeight('input-text-75') != '0px'"); shouldBeTrue("getFullHeight('input-text-75') != '0px'");
// Note: This behavior doesn't match to IE 8, Firefox 3.5 and Opera 10. shouldBe("getFullHeight('input-text-75')", "getFullHeight('input-text-100')");
is75PercentOf("getFullHeight('input-text-75')", "getFullHeight('input-text-100')");
shouldBe("getWidth('textarea-75')", "getWidth('textarea-100')"); shouldBe("getWidth('textarea-75')", "getWidth('textarea-100')");
shouldBeTrue("getFullHeight('textarea-75') != '0px'"); shouldBeTrue("getFullHeight('textarea-75') != '0px'");
// Note: This behavior doesn't match to IE 8, Firefox 3.5 and Opera 10. shouldBe("getFullHeight('textarea-75')", "getFullHeight('textarea-100')");
is75PercentOf("getFullHeight('textarea-75')", "getFullHeight('textarea-100')");
isSuccessfullyParsed(); isSuccessfullyParsed();
......
...@@ -41,21 +41,6 @@ function parsePixelValue(str) ...@@ -41,21 +41,6 @@ function parsePixelValue(str)
return parseFloat(str); return parseFloat(str);
} }
function is75PercentOf(expression75, expression100)
{
var str75 = eval(expression75);
var str100 = eval(expression100);
var num75 = parsePixelValue(str75);
var num100 = parsePixelValue(str100);
if (num75 < 0 || num100 < 0)
return;
var expectedValue = num100 * 75 / 100;
if (num75 == expectedValue)
testPassed(expression75 + " is 75% of " + expression100 + ".");
else
testFailed(expression75 + " [" + str75 + "] is not 75% of " + expression100 + " [" + str100 + "].");
}
function test() function test()
{ {
description("This test checks that replaced elements with percentage heights within table cells have the correct height.<br>Note, some of the button height tests fail on the Windows ports. See bug #34071."); description("This test checks that replaced elements with percentage heights within table cells have the correct height.<br>Note, some of the button height tests fail on the Windows ports. See bug #34071.");
...@@ -94,14 +79,12 @@ function test() ...@@ -94,14 +79,12 @@ function test()
shouldBe("getHeight('input-button-75')", "getHeight('input-button-100')"); shouldBe("getHeight('input-button-75')", "getHeight('input-button-100')");
shouldBe("getWidth('input-checkbox-75')", "getWidth('input-checkbox-100')"); shouldBe("getWidth('input-checkbox-75')", "getWidth('input-checkbox-100')");
shouldBeTrue("getHeight('input-checkbox-75') != '0px'"); shouldBeTrue("getHeight('input-checkbox-75') == '0px'");
// Note: This behavior doesn't match to Firefox 3.5 and Opera 10. shouldBe("getHeight('input-checkbox-75')", "getHeight('input-checkbox-100')");
is75PercentOf("getHeight('input-checkbox-75')", "getHeight('input-checkbox-100')");
shouldBe("getWidth('input-file-75')", "getWidth('input-file-100')"); shouldBe("getWidth('input-file-75')", "getWidth('input-file-100')");
shouldBeTrue("getHeight('input-file-75') != '0px'"); shouldBeTrue("getHeight('input-file-75') != '0px'");
// Note: This behavior doesn't match to Firefox 3.5 and Opera 10. shouldBe("getHeight('input-file-75')", "getHeight('input-file-100')");
is75PercentOf("getHeight('input-file-75')", "getHeight('input-file-100')");
// Note: This behavior doesn't match to Firefox 3.5 and Opera 10. // Note: This behavior doesn't match to Firefox 3.5 and Opera 10.
shouldBe("getWidth('input-image-75')", "'75px'"); shouldBe("getWidth('input-image-75')", "'75px'");
...@@ -110,9 +93,8 @@ function test() ...@@ -110,9 +93,8 @@ function test()
shouldBe("getHeight('input-image-100')", "'100px'"); shouldBe("getHeight('input-image-100')", "'100px'");
shouldBe("getWidth('input-radio-75')", "getWidth('input-radio-100')"); shouldBe("getWidth('input-radio-75')", "getWidth('input-radio-100')");
shouldBeTrue("getHeight('input-radio-75') != '0px'"); shouldBeTrue("getHeight('input-radio-75') == '0px'");
// Note: This behavior doesn't match to Firefox 3.5 and Opera 10. shouldBe("getHeight('input-radio-75')", "getHeight('input-radio-100')");
is75PercentOf("getHeight('input-radio-75')", "getHeight('input-radio-100')");
shouldBe("getWidth('input-reset-75')", "getWidth('input-reset-100')"); shouldBe("getWidth('input-reset-75')", "getWidth('input-reset-100')");
shouldBeTrue("getHeight('input-reset-75') != '0px'"); shouldBeTrue("getHeight('input-reset-75') != '0px'");
......
Text
crbug.com/669687: Percent height border-box replaced content in a cell gets the correct height.
PASS
<!DOCTYPE html>
<style>
.cell { display:table-cell; }
.div { height: 100%; display: inline-block; box-sizing: border-box; border: 2px solid black; padding: 2px; font: 20px Ahem;}
</style>
<div class="cell">
<div class="div" data-expected-height=28>Text</div>
</div>
<script src="../../resources/check-layout.js"></script>
<p> crbug.com/669687: Percent height border-box replaced content in a cell gets the correct height. </p>
<div id="output"></div>
<script>
checkLayout('.div', output);
</script>
Text
crbug.com/669687: Percent height border-box content in a cell gets the correct height.
PASS
<!DOCTYPE html>
<style>
.cell { display:table-cell; }
.div { height: 100%; box-sizing: border-box; border: 2px solid black; padding: 2px; font: 20px Ahem;}
</style>
<div class="cell">
<div class="div" data-expected-height=28>Text</div>
</div>
<script src="../../resources/check-layout.js"></script>
<p> crbug.com/669687: Percent height border-box content in a cell gets the correct height. </p>
<div id="output"></div>
<script>
checkLayout('.div', output);
</script>
<!DOCTYPE html>
<style>
.button { font: 20px Ahem;}
</style>
<button type="button" class="button">Text</button>
<p> crbug.com/669687: Percent height border-box replaced content in a cell gets the correct height. </p>
<!DOCTYPE html>
<style>
.cell { display:table-cell; }
.button { height: 100%; font: 20px Ahem;}
</style>
<div class="cell">
<button type="button" class="button" id="button">Text</button>
</div>
<p> crbug.com/669687: Percent height border-box replaced content in a cell gets the correct height. </p>
...@@ -19,8 +19,8 @@ layer at (0,0) size 800x600 ...@@ -19,8 +19,8 @@ layer at (0,0) size 800x600
LayoutTableSection {TBODY} at (2,2) size 96x96 LayoutTableSection {TBODY} at (2,2) size 96x96
LayoutTableRow {TR} at (0,2) size 96x92 LayoutTableRow {TR} at (0,2) size 96x92
LayoutTableCell {TD} at (2,46) size 92x4 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=1] LayoutTableCell {TD} at (2,46) size 92x4 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=1]
LayoutTable {TABLE} at (0,152) size 191x120 [border: (2px outset #808080)] LayoutTable {TABLE} at (0,152) size 191x126 [border: (2px outset #808080)]
LayoutTableSection {TBODY} at (2,2) size 187x116 LayoutTableSection {TBODY} at (2,2) size 187x122
LayoutTableRow {TR} at (0,2) size 187x24 LayoutTableRow {TR} at (0,2) size 187x24
LayoutTableCell {TD} at (2,2) size 183x24 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=1] LayoutTableCell {TD} at (2,2) size 183x24 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=1]
LayoutText {#text} at (2,2) size 28x19 LayoutText {#text} at (2,2) size 28x19
...@@ -33,10 +33,10 @@ layer at (0,0) size 800x600 ...@@ -33,10 +33,10 @@ layer at (0,0) size 800x600
LayoutTableCell {TD} at (2,54) size 183x24 [border: (1px inset #808080)] [r=2 c=0 rs=1 cs=1] LayoutTableCell {TD} at (2,54) size 183x24 [border: (1px inset #808080)] [r=2 c=0 rs=1 cs=1]
LayoutText {#text} at (2,2) size 35x19 LayoutText {#text} at (2,2) size 35x19
text run at (2,2) width 35: "world" text run at (2,2) width 35: "world"
LayoutTableRow {TR} at (0,80) size 187x34 LayoutTableRow {TR} at (0,80) size 187x40
LayoutTableCell {TD} at (2,82) size 183x30 [border: (1px inset #808080)] [r=3 c=0 rs=1 cs=1] LayoutTableCell {TD} at (2,80) size 183x40 [border: (1px inset #808080)] [r=3 c=0 rs=1 cs=1]
LayoutText {#text} at (0,0) size 0x0 LayoutText {#text} at (0,0) size 0x0
LayoutTable {TABLE} at (0,272) size 106x86 LayoutTable {TABLE} at (0,278) size 106x86
LayoutTableSection {TBODY} at (0,0) size 106x86 LayoutTableSection {TBODY} at (0,0) size 106x86
LayoutTableRow {TR} at (0,2) size 106x82 LayoutTableRow {TR} at (0,2) size 106x82
LayoutTableCell {TD} at (2,2) size 102x82 [r=0 c=0 rs=1 cs=1] LayoutTableCell {TD} at (2,2) size 102x82 [r=0 c=0 rs=1 cs=1]
...@@ -46,7 +46,7 @@ layer at (0,0) size 800x600 ...@@ -46,7 +46,7 @@ layer at (0,0) size 800x600
text run at (1,41) width 54: "nowrap. " text run at (1,41) width 54: "nowrap. "
text run at (55,41) width 41: "I really" text run at (55,41) width 41: "I really"
text run at (1,61) width 43: "should." text run at (1,61) width 43: "should."
LayoutTable {TABLE} at (0,358) size 106x86 LayoutTable {TABLE} at (0,364) size 106x86
LayoutTableSection {TBODY} at (0,0) size 106x86 LayoutTableSection {TBODY} at (0,0) size 106x86
LayoutTableRow {TR} at (0,2) size 106x82 LayoutTableRow {TR} at (0,2) size 106x82
LayoutTableCell {TD} at (2,2) size 102x82 [r=0 c=0 rs=1 cs=1] LayoutTableCell {TD} at (2,2) size 102x82 [r=0 c=0 rs=1 cs=1]
...@@ -57,7 +57,7 @@ layer at (0,0) size 800x600 ...@@ -57,7 +57,7 @@ layer at (0,0) size 800x600
text run at (0,40) width 54: "nowrap. " text run at (0,40) width 54: "nowrap. "
text run at (54,40) width 41: "I really" text run at (54,40) width 41: "I really"
text run at (0,60) width 43: "should." text run at (0,60) width 43: "should."
LayoutTable {TABLE} at (0,444) size 345x26 LayoutTable {TABLE} at (0,450) size 345x26
LayoutTableSection {TBODY} at (0,0) size 345x26 LayoutTableSection {TBODY} at (0,0) size 345x26
LayoutTableRow {TR} at (0,2) size 345x22 LayoutTableRow {TR} at (0,2) size 345x22
LayoutTableCell {TD} at (2,2) size 341x22 [r=0 c=0 rs=1 cs=1] LayoutTableCell {TD} at (2,2) size 341x22 [r=0 c=0 rs=1 cs=1]
...@@ -65,7 +65,7 @@ layer at (0,0) size 800x600 ...@@ -65,7 +65,7 @@ layer at (0,0) size 800x600
text run at (1,1) width 138: "I should have nowrap. " text run at (1,1) width 138: "I should have nowrap. "
text run at (139,1) width 92: "I really should. " text run at (139,1) width 92: "I really should. "
text run at (231,1) width 109: "Definitely. Should." text run at (231,1) width 109: "Definitely. Should."
LayoutTable {TABLE} at (0,470) size 345x26 LayoutTable {TABLE} at (0,476) size 345x26
LayoutTableSection {TBODY} at (0,0) size 345x26 LayoutTableSection {TBODY} at (0,0) size 345x26
LayoutTableRow {TR} at (0,2) size 345x22 LayoutTableRow {TR} at (0,2) size 345x22
LayoutTableCell {TD} at (2,2) size 341x22 [r=0 c=0 rs=1 cs=1] LayoutTableCell {TD} at (2,2) size 341x22 [r=0 c=0 rs=1 cs=1]
...@@ -76,6 +76,6 @@ layer at (0,0) size 800x600 ...@@ -76,6 +76,6 @@ layer at (0,0) size 800x600
text run at (230,0) width 109: "Definitely. Should." text run at (230,0) width 109: "Definitely. Should."
layer at (57,14) size 730x16 layer at (57,14) size 730x16
LayoutBlockFlow {DIV} at (2,3) size 730x16 LayoutBlockFlow {DIV} at (2,3) size 730x16
layer at (14,246) size 179x26 clip at (15,247) size 177x24 layer at (14,244) size 179x36 clip at (15,245) size 177x34
LayoutTextControl {TEXTAREA} at (2,2) size 179x26 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)] LayoutTextControl {TEXTAREA} at (2,2) size 179x36 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
LayoutBlockFlow {DIV} at (3,3) size 175x16 LayoutBlockFlow {DIV} at (3,3) size 175x16
...@@ -14,5 +14,5 @@ layer at (0,0) size 800x80 ...@@ -14,5 +14,5 @@ layer at (0,0) size 800x80
LayoutTableRow {DIV} at (0,0) size 150x0 LayoutTableRow {DIV} at (0,0) size 150x0
LayoutTableRow (anonymous) at (0,0) size 150x20 LayoutTableRow (anonymous) at (0,0) size 150x20
LayoutTableCell (anonymous) at (0,0) size 150x20 [r=2 c=0 rs=1 cs=1] LayoutTableCell (anonymous) at (0,0) size 150x20 [r=2 c=0 rs=1 cs=1]
LayoutBlockFlow {DIV} at (0,5) size 75x10 [bgcolor=#0000FF] LayoutBlockFlow {DIV} at (0,15) size 75x0 [bgcolor=#0000FF]
LayoutBlockFlow {DIV} at (75,5) size 75x10 [bgcolor=#0000FF] LayoutBlockFlow {DIV} at (75,15) size 75x0 [bgcolor=#0000FF]
...@@ -10,8 +10,8 @@ layer at (0,0) size 800x80 ...@@ -10,8 +10,8 @@ layer at (0,0) size 800x80
LayoutTableSection {DIV} at (0,0) size 150x20 LayoutTableSection {DIV} at (0,0) size 150x20
LayoutTableRow (anonymous) at (0,0) size 150x20 LayoutTableRow (anonymous) at (0,0) size 150x20
LayoutTableCell (anonymous) at (0,0) size 150x20 [r=0 c=0 rs=1 cs=1] LayoutTableCell (anonymous) at (0,0) size 150x20 [r=0 c=0 rs=1 cs=1]
LayoutBlockFlow {DIV} at (0,5) size 75x10 [bgcolor=#0000FF] LayoutBlockFlow {DIV} at (0,15) size 75x0 [bgcolor=#0000FF]
LayoutBlockFlow {DIV} at (75,5) size 75x10 [bgcolor=#0000FF] LayoutBlockFlow {DIV} at (75,15) size 75x0 [bgcolor=#0000FF]
LayoutTableRow {DIV} at (0,20) size 150x0 LayoutTableRow {DIV} at (0,20) size 150x0
LayoutTableRow (anonymous) at (0,20) size 150x0 LayoutTableRow (anonymous) at (0,20) size 150x0
LayoutTableCell (anonymous) at (0,20) size 150x0 [r=2 c=0 rs=1 cs=1] LayoutTableCell (anonymous) at (0,20) size 150x0 [r=2 c=0 rs=1 cs=1]
......
...@@ -20,7 +20,7 @@ layer at (0,0) size 800x600 ...@@ -20,7 +20,7 @@ layer at (0,0) size 800x600
LayoutTable {TABLE} at (0,38) size 784x100 LayoutTable {TABLE} at (0,38) size 784x100
LayoutTableSection {TBODY} at (0,0) size 784x100 LayoutTableSection {TBODY} at (0,0) size 784x100
LayoutTableRow {TR} at (0,2) size 784x96 LayoutTableRow {TR} at (0,2) size 784x96
LayoutTableCell {TD} at (2,13) size 780x73 [bgcolor=#FF0000] [r=0 c=0 rs=1 cs=1] LayoutTableCell {TD} at (2,11) size 780x77 [bgcolor=#FF0000] [r=0 c=0 rs=1 cs=1]
LayoutText {#text} at (0,0) size 0x0 LayoutText {#text} at (0,0) size 0x0
LayoutBlockFlow {HR} at (0,146) size 784x2 [border: (1px inset #EEEEEE)] LayoutBlockFlow {HR} at (0,146) size 784x2 [border: (1px inset #EEEEEE)]
LayoutTable {TABLE} at (0,156) size 784x100 LayoutTable {TABLE} at (0,156) size 784x100
...@@ -44,8 +44,8 @@ layer at (0,0) size 800x600 ...@@ -44,8 +44,8 @@ layer at (0,0) size 800x600
LayoutBlockFlow {P} at (1,1) size 622.39x80 [bgcolor=#FFFFE0] LayoutBlockFlow {P} at (1,1) size 622.39x80 [bgcolor=#FFFFE0]
LayoutText {#text} at (0,0) size 210x19 LayoutText {#text} at (0,0) size 210x19
text run at (0,0) width 210: "OK: the height of the P is 80 pixels" text run at (0,0) width 210: "OK: the height of the P is 80 pixels"
layer at (11,100) size 622x71 clip at (12,101) size 620x69 layer at (11,98) size 622x75 clip at (12,99) size 620x73
LayoutTextControl {TEXTAREA} at (1,1) size 622.39x71.19 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)] LayoutTextControl {TEXTAREA} at (1,1) size 622.39x75.19 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
LayoutBlockFlow {DIV} at (3,3) size 618.39x16 LayoutBlockFlow {DIV} at (3,3) size 618.39x16
LayoutText {#text} at (0,0) size 336x16 LayoutText {#text} at (0,0) size 336x16
text run at (0,0) width 336: "BUG: the height of the textarea is not 80%" text run at (0,0) width 336: "BUG: the height of the textarea is not 80%"
......
...@@ -55,32 +55,32 @@ PASS getWidth('object-100') is '300px' ...@@ -55,32 +55,32 @@ PASS getWidth('object-100') is '300px'
PASS getHeight('object-100') is '150px' PASS getHeight('object-100') is '150px'
PASS getWidth('button-75') is getWidth('button-100') PASS getWidth('button-75') is getWidth('button-100')
PASS getHeight('button-75') != '0px' is true PASS getHeight('button-75') != '0px' is true
FAIL getHeight('button-75') should be 16px. Was 10.5px. PASS getHeight('button-75') is getHeight('button-100')
PASS getWidth('input-button-75') is getWidth('input-button-100') PASS getWidth('input-button-75') is getWidth('input-button-100')
PASS getHeight('input-button-75') != '0px' is true PASS getHeight('input-button-75') != '0px' is true
FAIL getHeight('input-button-75') should be 16px. Was 10.5px. PASS getHeight('input-button-75') is getHeight('input-button-100')
PASS getWidth('input-checkbox-75') is getWidth('input-checkbox-100') PASS getWidth('input-checkbox-75') is getWidth('input-checkbox-100')
PASS getHeight('input-checkbox-75') != '0px' is true PASS getHeight('input-checkbox-75') == '0px' is true
PASS getHeight('input-checkbox-75') is 75% of getHeight('input-checkbox-100'). PASS getHeight('input-checkbox-75') is getHeight('input-checkbox-100')
PASS getWidth('input-file-75') is getWidth('input-file-100') PASS getWidth('input-file-75') is getWidth('input-file-100')
PASS getHeight('input-file-75') != '0px' is true PASS getHeight('input-file-75') != '0px' is true
PASS getHeight('input-file-75') is 75% of getHeight('input-file-100'). PASS getHeight('input-file-75') is getHeight('input-file-100')
PASS getWidth('input-image-75') is '75px' PASS getWidth('input-image-75') is '75px'
PASS getHeight('input-image-75') is '75px' PASS getHeight('input-image-75') is '75px'
PASS getWidth('input-image-100') is '100px' PASS getWidth('input-image-100') is '100px'
PASS getHeight('input-image-100') is '100px' PASS getHeight('input-image-100') is '100px'
PASS getWidth('input-radio-75') is getWidth('input-radio-100') PASS getWidth('input-radio-75') is getWidth('input-radio-100')
PASS getHeight('input-radio-75') != '0px' is true PASS getHeight('input-radio-75') == '0px' is true
PASS getHeight('input-radio-75') is 75% of getHeight('input-radio-100'). PASS getHeight('input-radio-75') is getHeight('input-radio-100')
PASS getWidth('input-reset-75') is getWidth('input-reset-100') PASS getWidth('input-reset-75') is getWidth('input-reset-100')
PASS getHeight('input-reset-75') != '0px' is true PASS getHeight('input-reset-75') != '0px' is true
FAIL getHeight('input-reset-75') should be 16px. Was 10.5px. PASS getHeight('input-reset-75') is getHeight('input-reset-100')
PASS getWidth('input-submit-75') is getWidth('input-submit-100') PASS getWidth('input-submit-75') is getWidth('input-submit-100')
PASS getHeight('input-submit-75') != '0px' is true PASS getHeight('input-submit-75') != '0px' is true
FAIL getHeight('input-submit-75') should be 16px. Was 10.5px. PASS getHeight('input-submit-75') is getHeight('input-submit-100')
PASS getWidth('select-75') is getWidth('select-100') PASS getWidth('select-75') is getWidth('select-100')
PASS getHeight('select-75') != '0px' is true PASS getHeight('select-75') != '0px' is true
FAIL getHeight('select-75') should be 18px. Was 13px. PASS getHeight('select-75') is getHeight('select-100')
PASS successfullyParsed is true PASS successfullyParsed is true
TEST COMPLETE TEST COMPLETE
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
This test checks that text controls with percentage heights within table cells have the correct height.Text controls are in a different test than other replaced elements because their metrics are platform-specific. This test checks that text controls with percentage heights within table cells have the correct height.Text controls are in a different test than other replaced elements because their metrics are platform-specific.The reason a 75% control is the same height as a 100% control is because a replaced element that depends on theheight of its parent cell is treated as auto. So by itself it will set the height of the row. See https://drafts.csswg.org/css-tables-3/#row-layout
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
...@@ -14,13 +14,13 @@ PASS successfullyParsed is true ...@@ -14,13 +14,13 @@ PASS successfullyParsed is true
TEST COMPLETE TEST COMPLETE
PASS getWidth('input-password-75') is getWidth('input-password-100') PASS getWidth('input-password-75') is getWidth('input-password-100')
PASS getFullHeight('input-password-75') != '0px' is true PASS getFullHeight('input-password-75') != '0px' is true
FAIL getFullHeight('input-password-75') [16.5px] is not 75% of getFullHeight('input-password-100') [22px]. PASS getFullHeight('input-password-75') is getFullHeight('input-password-100')
PASS getWidth('input-text-75') is getWidth('input-text-100') PASS getWidth('input-text-75') is getWidth('input-text-100')
PASS getFullHeight('input-text-75') != '0px' is true PASS getFullHeight('input-text-75') != '0px' is true
FAIL getFullHeight('input-text-75') [16.5px] is not 75% of getFullHeight('input-text-100') [22px]. PASS getFullHeight('input-text-75') is getFullHeight('input-text-100')
PASS getWidth('textarea-75') is getWidth('textarea-100') PASS getWidth('textarea-75') is getWidth('textarea-100')
PASS getFullHeight('textarea-75') != '0px' is true PASS getFullHeight('textarea-75') != '0px' is true
PASS getFullHeight('textarea-75') is 75% of getFullHeight('textarea-100'). PASS getFullHeight('textarea-75') is getFullHeight('textarea-100')
PASS successfullyParsed is true PASS successfullyParsed is true
TEST COMPLETE TEST COMPLETE
......
...@@ -3185,19 +3185,16 @@ LayoutUnit LayoutBox::computePercentageLogicalHeight( ...@@ -3185,19 +3185,16 @@ LayoutUnit LayoutBox::computePercentageLogicalHeight(
// always make ourselves be a percentage of the cell's current content // always make ourselves be a percentage of the cell's current content
// height. // height.
if (!cb->hasOverrideLogicalContentHeight()) { if (!cb->hasOverrideLogicalContentHeight()) {
// Normally we would let the cell size intrinsically, but scrolling // https://drafts.csswg.org/css-tables-3/#row-layout:
// overflow has to be treated differently, since WinIE lets scrolled // For the purpose of calculating [the minimum height of a row],
// overflow regions shrink as needed. // descendants of table cells whose height depends on percentages
// While we can't get all cases right, we can at least detect when the // of their parent cell's height are considered to have an auto
// cell has a specified height or when the table has a specified height. // height if they have overflow set to visible or hidden or if
// In these cases we want to initially have no size and allow the // they are replaced elements, and a 0px height if they have not.
// flexing of the table or the cell to its specified height to cause us
// to grow to fill the space. This could end up being wrong in some
// cases, but it is preferable to the alternative (sizing intrinsically
// and making the row end up too big).
LayoutTableCell* cell = toLayoutTableCell(cb); LayoutTableCell* cell = toLayoutTableCell(cb);
if (style()->overflowY() != EOverflow::Visible && if (style()->overflowY() != EOverflow::Visible &&
style()->overflowY() != EOverflow::Hidden && style()->overflowY() != EOverflow::Hidden &&
!shouldBeConsideredAsReplaced() &&
(!cell->style()->logicalHeight().isAuto() || (!cell->style()->logicalHeight().isAuto() ||
!cell->table()->style()->logicalHeight().isAuto())) !cell->table()->style()->logicalHeight().isAuto()))
return LayoutUnit(); return LayoutUnit();
...@@ -3218,16 +3215,17 @@ LayoutUnit LayoutBox::computePercentageLogicalHeight( ...@@ -3218,16 +3215,17 @@ LayoutUnit LayoutBox::computePercentageLogicalHeight(
availableHeight += cb->paddingLogicalHeight(); availableHeight += cb->paddingLogicalHeight();
LayoutUnit result = valueForLength(height, availableHeight); LayoutUnit result = valueForLength(height, availableHeight);
bool includeBorderPadding = // |overrideLogicalContentHeight| is the maximum height made available by the
// cell to its percent height children when we decide they can determine the
// height of the cell. If the percent height child is box-sizing:content-box
// then we must subtract the border and padding from the cell's
// |availableHeight| (given by |overrideLogicalContentHeight|) to arrive
// at the child's computed height.
bool subtractBorderAndPadding =
isTable() || (cb->isTableCell() && !skippedAutoHeightContainingBlock && isTable() || (cb->isTableCell() && !skippedAutoHeightContainingBlock &&
cb->hasOverrideLogicalContentHeight()); cb->hasOverrideLogicalContentHeight() &&
style()->boxSizing() == BoxSizingContentBox);
if (includeBorderPadding) { if (subtractBorderAndPadding) {
// FIXME: Table cells should default to box-sizing: border-box so we can
// avoid this hack.
// It is necessary to use the border-box to match WinIE's broken
// box model. This is essential for sizing inside
// table cells using percentage heights.
result -= borderAndPaddingLogicalHeight(); result -= borderAndPaddingLogicalHeight();
return std::max(LayoutUnit(), result); return std::max(LayoutUnit(), result);
} }
...@@ -4672,9 +4670,12 @@ bool LayoutBox::shrinkToAvoidFloats() const { ...@@ -4672,9 +4670,12 @@ bool LayoutBox::shrinkToAvoidFloats() const {
} }
DISABLE_CFI_PERF DISABLE_CFI_PERF
static bool shouldBeConsideredAsReplaced(Node* node) { bool LayoutBox::shouldBeConsideredAsReplaced() const {
// Checkboxes and radioboxes are not isAtomicInlineLevel() nor do they have // Checkboxes and radioboxes are not isAtomicInlineLevel() nor do they have
// their own layoutObject in which to override avoidFloats(). // their own layoutObject in which to override avoidFloats().
if (isAtomicInlineLevel())
return true;
Node* node = this->node();
return node && node->isElementNode() && return node && node->isElementNode() &&
(toElement(node)->isFormControlElement() || (toElement(node)->isFormControlElement() ||
isHTMLImageElement(toElement(node))); isHTMLImageElement(toElement(node)));
...@@ -4682,10 +4683,9 @@ static bool shouldBeConsideredAsReplaced(Node* node) { ...@@ -4682,10 +4683,9 @@ static bool shouldBeConsideredAsReplaced(Node* node) {
DISABLE_CFI_PERF DISABLE_CFI_PERF
bool LayoutBox::avoidsFloats() const { bool LayoutBox::avoidsFloats() const {
return isAtomicInlineLevel() || shouldBeConsideredAsReplaced(node()) || return shouldBeConsideredAsReplaced() || hasOverflowClip() || isHR() ||
hasOverflowClip() || isHR() || isLegend() || isWritingModeRoot() || isLegend() || isWritingModeRoot() || isFlexItemIncludingDeprecated() ||
isFlexItemIncludingDeprecated() || style()->containsPaint() || style()->containsPaint() || style()->containsLayout();
style()->containsLayout();
} }
bool LayoutBox::hasNonCompositedScrollbars() const { bool LayoutBox::hasNonCompositedScrollbars() const {
......
...@@ -1097,6 +1097,7 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject { ...@@ -1097,6 +1097,7 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
bool shrinkToAvoidFloats() const; bool shrinkToAvoidFloats() const;
virtual bool avoidsFloats() const; virtual bool avoidsFloats() const;
bool shouldBeConsideredAsReplaced() const;
void updateFragmentationInfoForChild(LayoutBox&); void updateFragmentationInfoForChild(LayoutBox&);
bool childNeedsRelayoutForPagination(const LayoutBox&) const; bool childNeedsRelayoutForPagination(const LayoutBox&) const;
......
...@@ -1110,13 +1110,15 @@ int LayoutTableSection::distributeExtraLogicalHeightToRows( ...@@ -1110,13 +1110,15 @@ int LayoutTableSection::distributeExtraLogicalHeightToRows(
return extraLogicalHeight - remainingExtraLogicalHeight; return extraLogicalHeight - remainingExtraLogicalHeight;
} }
static bool shouldFlexCellChild(LayoutObject* cellDescendant) { static bool shouldFlexCellChild(const LayoutTableCell& cell,
return cellDescendant->isAtomicInlineLevel() || LayoutObject* cellDescendant) {
(cellDescendant->isBox() && if (!cell.style()->logicalHeight().isSpecified())
toLayoutBox(cellDescendant)->style()->overflowY() != return false;
EOverflow::Visible && if (cellDescendant->style()->overflowY() == EOverflow::Visible ||
toLayoutBox(cellDescendant)->style()->overflowY() != cellDescendant->style()->overflowY() == EOverflow::Hidden)
EOverflow::Hidden); return true;
return cellDescendant->isBox() &&
toLayoutBox(cellDescendant)->shouldBeConsideredAsReplaced();
} }
void LayoutTableSection::layoutRows() { void LayoutTableSection::layoutRows() {
...@@ -1902,7 +1904,7 @@ void LayoutTableSection::relayoutCellIfFlexed(LayoutTableCell& cell, ...@@ -1902,7 +1904,7 @@ void LayoutTableSection::relayoutCellIfFlexed(LayoutTableCell& cell,
for (LayoutObject* child = cell.firstChild(); child; for (LayoutObject* child = cell.firstChild(); child;
child = child->nextSibling()) { child = child->nextSibling()) {
if (!child->isText() && child->style()->logicalHeight().isPercentOrCalc() && if (!child->isText() && child->style()->logicalHeight().isPercentOrCalc() &&
(flexAllChildren || shouldFlexCellChild(child)) && (flexAllChildren || shouldFlexCellChild(cell, child)) &&
(!child->isTable() || toLayoutTable(child)->hasSections())) { (!child->isTable() || toLayoutTable(child)->hasSections())) {
cellChildrenFlex = true; cellChildrenFlex = true;
break; break;
...@@ -1913,7 +1915,7 @@ void LayoutTableSection::relayoutCellIfFlexed(LayoutTableCell& cell, ...@@ -1913,7 +1915,7 @@ void LayoutTableSection::relayoutCellIfFlexed(LayoutTableCell& cell,
if (TrackedLayoutBoxListHashSet* percentHeightDescendants = if (TrackedLayoutBoxListHashSet* percentHeightDescendants =
cell.percentHeightDescendants()) { cell.percentHeightDescendants()) {
for (auto* descendant : *percentHeightDescendants) { for (auto* descendant : *percentHeightDescendants) {
if (flexAllChildren || shouldFlexCellChild(descendant)) { if (flexAllChildren || shouldFlexCellChild(cell, descendant)) {
cellChildrenFlex = true; cellChildrenFlex = true;
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment