Only do special height reflows for percentage-height children of table cells when there is a specified height on the table, row group, row, or cell in the row. b=370525 Patch by Daniel Holbert <dholbert@mozilla.com>. r+sr=dbaron
authordbaron@dbaron.org
Mon, 25 Jun 2007 13:34:35 -0700
changeset 2765 88947bdd7dfea82b46a17a3e7d8824fda59e4ce5
parent 2764 66ecb460cced49a5807cd7966231ba9b5002ce37
child 2766 9beee8d8145519ed52011a90e01f0154a88bb279
push idunknown
push userunknown
push dateunknown
bugs370525
milestone1.9a6pre
Only do special height reflows for percentage-height children of table cells when there is a specified height on the table, row group, row, or cell in the row. b=370525 Patch by Daniel Holbert <dholbert@mozilla.com>. r+sr=dbaron
layout/reftests/bugs/370525-1-notref.html
layout/reftests/bugs/370525-1-ref.html
layout/reftests/bugs/370525-1.html
layout/reftests/bugs/370525-2-notref.html
layout/reftests/bugs/370525-2-ref.html
layout/reftests/bugs/370525-2.html
layout/reftests/bugs/370525-rowspan-1a-ref.html
layout/reftests/bugs/370525-rowspan-1a.html
layout/reftests/bugs/370525-rowspan-1b-ref.html
layout/reftests/bugs/370525-rowspan-1b.html
layout/reftests/bugs/370525-rowspan-1c-ref.html
layout/reftests/bugs/370525-rowspan-1c.html
layout/reftests/bugs/370525-rowspan-2a-ref.html
layout/reftests/bugs/370525-rowspan-2a.html
layout/reftests/bugs/370525-rowspan-2b-ref.html
layout/reftests/bugs/370525-rowspan-2b.html
layout/reftests/bugs/370525-rowspan-3-ref.html
layout/reftests/bugs/370525-rowspan-3.html
layout/reftests/bugs/370525-rowspan-4-ref.html
layout/reftests/bugs/370525-rowspan-4.html
layout/reftests/bugs/370525-sib-ref.html
layout/reftests/bugs/370525-sib.html
layout/reftests/bugs/370525-style.css
layout/reftests/bugs/reftest.list
layout/tables/nsTableCellFrame.cpp
layout/tables/nsTableFrame.cpp
layout/tables/nsTableFrame.h
layout/tables/nsTableRowFrame.cpp
layout/tables/nsTableRowFrame.h
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/370525-1-notref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Bug 370525 Anti-Reference Testcase</title>
+</head>
+<body>
+  <table style="border: 2px solid blue;">
+    <tr><td style="height: 10%">
+      <table style="height: 100%; border: 1px dotted red;">
+        <tr><td>Table 1</td></tr>
+      </table>
+      <table style="height: 100%; border: 1px dotted red;">
+        <tr><td>Table 2</td></tr>
+      </table>
+    </td></tr>
+  </table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/370525-1-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Bug 370525 Reference Testcase</title>
+</head>
+<body>
+  <table style="border: 2px solid blue;">
+    <tr><td>
+      <table style="border: 1px dotted red;">
+        <tr><td>Table 1</td></tr>
+      </table>
+      <table style="border: 1px dotted red;">
+        <tr><td>Table 2</td></tr>
+      </table>
+    </td></tr>
+  </table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/370525-1.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Bug 370525 Testcase</title>
+</head>
+<body>
+  <table style="border: 2px solid blue;">
+    <tr><td>
+      <table style="height: 100%; border: 1px dotted red;">
+        <tr><td>Table 1</td></tr>
+      </table>
+      <table style="height: 100%; border: 1px dotted red;">
+        <tr><td>Table 2</td></tr>
+      </table>
+    </td></tr>
+  </table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/370525-2-notref.html
@@ -0,0 +1,17 @@
+<html>
+<head>
+  <title>Bug 370525 Anti-Reference Testcase</title>
+</head>
+<body>
+  <table style="border: 2px solid blue;">
+    <tr><td style="height: 10%">
+      <table style="height: 100%; border: 1px dotted red;">
+        <tr><td>Table 1</td></tr>
+      </table>
+      <table style="height: 100%; border: 1px dotted red;">
+        <tr><td>Table 2</td></tr>
+      </table>
+    </td></tr>
+  </table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/370525-2-ref.html
@@ -0,0 +1,17 @@
+<html>
+<head>
+  <title>Bug 370525 Reference Testcase</title>
+</head>
+<body>
+  <table style="border: 2px solid blue;">
+    <tr><td>
+      <table style="border: 1px dotted red;">
+        <tr><td>Table 1</td></tr>
+      </table>
+      <table style="border: 1px dotted red;">
+        <tr><td>Table 2</td></tr>
+      </table>
+    </td></tr>
+  </table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/370525-2.html
@@ -0,0 +1,17 @@
+<html>
+<head>
+  <title>Bug 370525 Testcase</title>
+</head>
+<body>
+  <table style="border: 2px solid blue;">
+    <tr><td>
+      <table style="height: 100%; border: 1px dotted red;">
+        <tr><td>Table 1</td></tr>
+      </table>
+      <table style="height: 100%; border: 1px dotted red;">
+        <tr><td>Table 2</td></tr>
+      </table>
+    </td></tr>
+  </table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/370525-rowspan-1a-ref.html
@@ -0,0 +1,28 @@
+<html>
+<head>
+<link rel="stylesheet" href="370525-style.css"/>
+</head>
+
+<body>
+rowspan=2 on the cell with the percent-height div,
+with specified height on a sibling
+<table>
+ <tr>
+   <td style="background: lightgreen" rowspan="2">
+    <div>
+     height=75% / ignored
+    </div>
+    blah
+   </td>
+   <td  style="background: lightblue" height="200px">
+    height=200px.
+   </td>
+ </tr>
+ <tr>
+   <td style="background: orange">
+   2nd row, 1st column
+   </td>
+ </tr>
+</table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/370525-rowspan-1a.html
@@ -0,0 +1,28 @@
+<html>
+<head>
+<link rel="stylesheet" href="370525-style.css"/>
+</head>
+
+<body>
+rowspan=2 on the cell with the percent-height div, 
+with specified height on a sibling
+<table>
+ <tr>
+   <td style="background: lightgreen" rowspan="2">
+    <div style="height: 75%">
+     height=75% / ignored
+    </div>
+    blah
+   </td>
+   <td  style="background: lightblue" height="200px">
+    height=200px.
+   </td>
+ </tr>
+ <tr>
+   <td style="background: orange">
+   2nd row, 1st column
+   </td>
+ </tr>
+</table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/370525-rowspan-1b-ref.html
@@ -0,0 +1,28 @@
+<html>
+<head>
+<link rel="stylesheet" href="370525-style.css"/>
+</head>
+
+<body>
+rowspan=2 on the cell with the percent-height div,
+with specified height on a sibling
+<table>
+ <tr>
+   <td style="background: lightgreen" rowspan="2">
+    <div>
+     height=75% / ignored
+    </div>
+    blah
+   </td>
+   <td style="background: orange">
+    1st row, 2nd column.
+   </td>
+ </tr>
+ <tr>
+   <td  style="background: lightblue" height="200px">
+    2nd row, 1st column. height=200px.
+   </td>
+ </tr>
+</table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/370525-rowspan-1b.html
@@ -0,0 +1,28 @@
+<html>
+<head>
+<link rel="stylesheet" href="370525-style.css"/>
+</head>
+
+<body>
+rowspan=2 on the cell with the percent-height div,
+with specified height on a sibling
+<table>
+ <tr>
+   <td style="background: lightgreen" rowspan="2">
+    <div style="height: 75%">
+     height=75% / ignored
+    </div>
+    blah
+   </td>
+   <td style="background: orange">
+    1st row, 2nd column.
+   </td>
+ </tr>
+ <tr>
+   <td  style="background: lightblue" height="200px">
+    2nd row, 1st column. height=200px.
+   </td>
+ </tr>
+</table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/370525-rowspan-1c-ref.html
@@ -0,0 +1,23 @@
+<html>
+<head>
+<link rel="stylesheet" href="370525-style.css"/>
+</head>
+
+<body>
+rowspan=2 on the cell with the percent-height div, with specified
+height on a sibling. Also, does not explicitly create 2nd row.
+<table>
+ <tr>
+   <td style="background: lightgreen" rowspan="2">
+    <div style="height: 150px">
+     height=75% / 150px
+    </div>
+    blah
+   </td>
+   <td  style="background: lightblue" height="200px">
+    height=200px.
+   </td>
+ </tr>
+</table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/370525-rowspan-1c.html
@@ -0,0 +1,23 @@
+<html>
+<head>
+<link rel="stylesheet" href="370525-style.css"/>
+</head>
+
+<body>
+rowspan=2 on the cell with the percent-height div, with specified
+height on a sibling. Also, does not explicitly create 2nd row.
+<table>
+ <tr>
+   <td style="background: lightgreen" rowspan="2">
+    <div style="height: 75%">
+     height=75% / 150px
+    </div>
+    blah
+   </td>
+   <td  style="background: lightblue" height="200px">
+    height=200px.
+   </td>
+ </tr>
+</table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/370525-rowspan-2a-ref.html
@@ -0,0 +1,28 @@
+<html>
+<head>
+<link rel="stylesheet" href="370525-style.css"/>
+</head>
+
+<body>
+rowspan=2 and specified height on a sibling of the cell with percent-height div.
+<table>
+ <tr>
+   <td style="background: lightgreen">
+    <div>
+     height=75% / ignored
+    </div>
+    blah
+   </td>
+   <td  style="background: lightblue" height="200px"  rowspan="2">
+    height=200px.
+   </td>
+ </tr>
+ <tr>
+   <td style="background: orange">
+   2nd row, 1st column
+   </td>
+ </tr>
+</table>
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/370525-rowspan-2a.html
@@ -0,0 +1,28 @@
+<html>
+<head>
+<link rel="stylesheet" href="370525-style.css"/>
+</head>
+
+<body>
+rowspan=2 and specified height on a sibling of the cell with percent-height div.
+<table>
+ <tr>
+   <td style="background: lightgreen">
+    <div style="height: 75%">
+     height=75% / ignored
+    </div>
+    blah
+   </td>
+   <td  style="background: lightblue" height="200px"  rowspan="2">
+    height=200px.
+   </td>
+ </tr>
+ <tr>
+   <td style="background: orange">
+   2nd row, 1st column
+   </td>
+ </tr>
+</table>
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/370525-rowspan-2b-ref.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<link rel="stylesheet" href="370525-style.css"/>
+</head>
+
+<body>
+rowspan=2 and specified height on a sibling of the cell with
+percent-height div. Also, does not explicitly create 2nd row.
+<table>
+ <tr>
+   <td style="background: lightgreen">
+    <div style="height: 150px">
+     height=75% / 150px
+    </div>
+    blah
+   </td>
+   <td  style="background: lightblue" height="200px"  rowspan="2">
+    height=200px.
+   </td>
+ </tr>
+</table>
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/370525-rowspan-2b.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<link rel="stylesheet" href="370525-style.css"/>
+</head>
+
+<body>
+rowspan=2 and specified height on a sibling of the cell with
+percent-height div. Also, does not explicitly create 2nd row.
+<table>
+ <tr>
+   <td style="background: lightgreen">
+    <div style="height: 75%">
+     height=75% / 150px
+    </div>
+    blah
+   </td>
+   <td  style="background: lightblue" height="200px"  rowspan="2">
+    height=200px.
+   </td>
+ </tr>
+</table>
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/370525-rowspan-3-ref.html
@@ -0,0 +1,26 @@
+<html>
+<head>
+<link rel="stylesheet" href="370525-style.css"/>
+</head>
+
+<body>
+rowspan=2 on the cell with the percent-height div, 
+with specified height on table
+<table height="200px">
+ <tr>
+   <td style="background: lightgreen" rowspan="2">
+    <div style="height: 150px">
+     height=75% / 150px
+    </div>
+    blah
+   </td>
+   <td style="background: lightblue"> first row, second column </td>
+ </tr>
+ <tr>
+   <td style="background: orange">
+   2nd row, only column
+   </td>
+ </tr>
+</table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/370525-rowspan-3.html
@@ -0,0 +1,26 @@
+<html>
+<head>
+<link rel="stylesheet" href="370525-style.css"/>
+</head>
+
+<body>
+rowspan=2 on the cell with the percent-height div, 
+with specified height on table
+<table height="200px">
+ <tr>
+   <td style="background: lightgreen" rowspan="2">
+    <div style="height: 75%">
+     height=75% / 150px
+    </div>
+    blah
+   </td>
+   <td style="background: lightblue"> first row, second column </td>
+ </tr>
+ <tr>
+   <td style="background: orange">
+   2nd row, only column
+   </td>
+ </tr>
+</table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/370525-rowspan-4-ref.html
@@ -0,0 +1,26 @@
+<html>
+<head>
+<link rel="stylesheet" href="370525-style.css"/>
+</head>
+
+<body>
+rowspan=2 on the cell with the percent-height div, 
+with specified height on row
+<table>
+ <tr height="160px">
+   <td style="background: lightgreen" rowspan="2">
+    <div style="height: 150px;">
+     height=75% / 150px
+    </div>
+    blah
+   </td>
+   <td style="background: lightblue"> first row, second column </td>
+ </tr>
+ <tr height="40px">
+   <td style="background: orange">
+   2nd row, only column
+   </td>
+ </tr>
+</table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/370525-rowspan-4.html
@@ -0,0 +1,26 @@
+<html>
+<head>
+<link rel="stylesheet" href="370525-style.css"/>
+</head>
+
+<body>
+rowspan=2 on the cell with the percent-height div, 
+with specified height on row
+<table>
+ <tr height="160px">
+   <td style="background: lightgreen" rowspan="2">
+    <div style="height: 75%">
+     height=75% / 150px
+    </div>
+    blah
+   </td>
+   <td style="background: lightblue"> first row, second column </td>
+ </tr>
+ <tr height="40px">
+   <td style="background: orange">
+   2nd row, only column
+   </td>
+ </tr>
+</table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/370525-sib-ref.html
@@ -0,0 +1,18 @@
+<html>
+<head>
+<link rel="stylesheet" href="370525-style.css"/>
+</head>
+
+<body>
+Specified height on sibling cell
+<table>
+  <tr>
+   <td style="background: lightgreen">
+    <div style="height: 150px">height=75% / 150px</div>
+    blah
+  </td>
+  <td style="height: 200px; background: lightblue">height=200px</td>
+ </tr>
+</table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/370525-sib.html
@@ -0,0 +1,18 @@
+<html>
+<head>
+<link rel="stylesheet" href="370525-style.css"/>
+</head>
+
+<body>
+Specified height on sibling cell
+<table>
+  <tr>
+   <td style="background: lightgreen">
+    <div style="height: 75%">height=75% / 150px</div>
+    blah
+  </td>
+  <td style="height: 200px; background: lightblue">height=200px</td>
+ </tr>
+</table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/370525-style.css
@@ -0,0 +1,13 @@
+div { 
+  background: yellow; 
+}
+table {
+  background: grey;
+  border-spacing: 0;
+  border-collapse: collapse;
+}
+
+td, th { 
+  padding: 0;
+  vertical-align: top;
+}
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -219,16 +219,29 @@ fails == 368020-4.html 368020-4-ref.html
 == 368247-2.html 368247-2-ref.html
 fails == 368504-1.html 368504-1-ref.html # bug 368504
 == 368622-1.html 368622-1-ref.html
 == 368622-1.html 368622-1-ref.html
 == 368651-1.html 368651-1-ref.html
 == 369975-1.html 369975-1.html
 == 369882.xul 369882-ref.xul
 == 370422-1.html 370422-1-ref.html
+== 370525-1.html 370525-1-ref.html
+!= 370525-1.html 370525-1-notref.html
+== 370525-2.html 370525-2-ref.html
+!= 370525-2.html 370525-2-notref.html
+!= 370525-2.html 370525-2-notref.html
+== 370525-rowspan-1a.html 370525-rowspan-1a-ref.html
+== 370525-rowspan-1b.html 370525-rowspan-1b-ref.html
+== 370525-rowspan-1c.html 370525-rowspan-1c-ref.html
+== 370525-rowspan-2a.html 370525-rowspan-2a-ref.html
+== 370525-rowspan-2b.html 370525-rowspan-2b-ref.html
+== 370525-rowspan-3.html 370525-rowspan-3-ref.html
+== 370525-rowspan-4.html 370525-rowspan-4-ref.html
+== 370525-sib.html 370525-sib-ref.html
 == 370586-1.xhtml 370586-1-ref.xhtml
 == 370629-1.html 370629-1-ref.html
 == 370629-2.html 370629-2-ref.html
 == 370692-1.xhtml 370692-1-ref.xhtml
 == 371041-1.html 371041-1-ref.html
 == 371043-1.html 371043-1-ref.html
 == 371925-1a.html 371925-1-ref.html
 == 371925-1b.html 371925-1-ref.html
--- a/layout/tables/nsTableCellFrame.cpp
+++ b/layout/tables/nsTableCellFrame.cpp
@@ -130,23 +130,33 @@ nsTableCellFrame::NotifyPercentHeight(co
 
   if (cellRS && cellRS->frame == this &&
       (cellRS->mComputedHeight == NS_UNCONSTRAINEDSIZE ||
        cellRS->mComputedHeight == 0)) { // XXXldb Why 0?
     // This is a percentage height on a frame whose percentage heights
     // are based on the height of the cell, since its containing block
     // is the inner cell frame.
 
-    for (const nsHTMLReflowState *rs = aReflowState.parentReflowState;
-         rs != cellRS;
-         rs = rs->parentReflowState) {
-      rs->frame->AddStateBits(NS_FRAME_CONTAINS_RELATIVE_HEIGHT);
+    // We'll only honor the percent height if sibling-cells/ancestors
+    // have specified/pct height. (Also, siblings only count for this if
+    // both this cell and the sibling cell span exactly 1 row.)
+
+    if (nsTableFrame::AncestorsHaveStyleHeight(*cellRS) ||
+        (nsTableFrame::GetTableFrame(this)->GetEffectiveRowSpan(*this) == 1 &&
+         (cellRS->parentReflowState->frame->GetStateBits() &
+          NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT))) {
+
+      for (const nsHTMLReflowState *rs = aReflowState.parentReflowState;
+           rs != cellRS;
+           rs = rs->parentReflowState) {
+        rs->frame->AddStateBits(NS_FRAME_CONTAINS_RELATIVE_HEIGHT);
+      }
+      
+      nsTableFrame::RequestSpecialHeightReflow(*cellRS);
     }
-
-    nsTableFrame::RequestSpecialHeightReflow(*cellRS);
   }
 }
 
 // The cell needs to observe its block and things inside its block but nothing below that
 PRBool 
 nsTableCellFrame::NeedsToObserve(const nsHTMLReflowState& aReflowState)
 {
   const nsHTMLReflowState *rs = aReflowState.parentReflowState;
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -1687,68 +1687,51 @@ nsTableFrame::ComputeAutoSize(nsIRenderi
 {
   // Tables always shrink-wrap.
   nscoord cbBased = aAvailableWidth - aMargin.width - aBorder.width -
                     aPadding.width;
   return nsSize(TableShrinkWidthToFit(aRenderingContext, cbBased),
                 NS_UNCONSTRAINEDSIZE);
 }
 
-// Return true if aStylePosition has a pct height
-static PRBool 
-IsPctStyleHeight(const nsStylePosition* aStylePosition)
-{
-  return (aStylePosition && 
-          (eStyleUnit_Percent == aStylePosition->mHeight.GetUnit()));
-}
-
-// Return true if aStylePosition has a coord height
-static PRBool 
-IsFixedStyleHeight(const nsStylePosition* aStylePosition)
-{
-  return (aStylePosition && 
-          (eStyleUnit_Coord == aStylePosition->mHeight.GetUnit()));
-}
-
-// Return true if any of aReflowState.frame's ancestors within the containing table
-// have a pct or fixed height
-static PRBool
-AncestorsHaveStyleHeight(const nsHTMLReflowState& aReflowState)
-{
-  for (const nsHTMLReflowState* parentRS = aReflowState.parentReflowState;
-       parentRS && parentRS->frame; 
-       parentRS = parentRS->parentReflowState) {
-    nsIAtom* frameType = parentRS->frame->GetType();
-    if (IS_TABLE_CELL(frameType)                         ||
+// Return true if aParentReflowState.frame or any of its ancestors within
+// the containing table have non-auto height. (e.g. pct or fixed height)
+PRBool
+nsTableFrame::AncestorsHaveStyleHeight(const nsHTMLReflowState& aParentReflowState)
+{
+  for (const nsHTMLReflowState* rs = &aParentReflowState;
+       rs && rs->frame; rs = rs->parentReflowState) {
+    nsIAtom* frameType = rs->frame->GetType();
+    if (IS_TABLE_CELL(frameType)                     ||
         (nsGkAtoms::tableRowFrame      == frameType) ||
         (nsGkAtoms::tableRowGroupFrame == frameType)) {
-      if (::IsPctStyleHeight(parentRS->mStylePosition) || ::IsFixedStyleHeight(parentRS->mStylePosition)) {
+      if (rs->mStylePosition->mHeight.GetUnit() != eStyleUnit_Auto) {
         return PR_TRUE;
       }
     }
     else if (nsGkAtoms::tableFrame == frameType) {
       // we reached the containing table, so always return
-      if (::IsPctStyleHeight(parentRS->mStylePosition) || ::IsFixedStyleHeight(parentRS->mStylePosition)) {
+      if (rs->mStylePosition->mHeight.GetUnit() != eStyleUnit_Auto) {
         return PR_TRUE;
       }
       else return PR_FALSE;
     }
   }
   return PR_FALSE;
 }
 
 // See if a special height reflow needs to occur and if so, call RequestSpecialHeightReflow
 void
 nsTableFrame::CheckRequestSpecialHeightReflow(const nsHTMLReflowState& aReflowState)
 {
   if (!aReflowState.frame->GetPrevInFlow() &&  // 1st in flow
       (NS_UNCONSTRAINEDSIZE == aReflowState.mComputedHeight ||  // no computed height
        0                    == aReflowState.mComputedHeight) && 
-      ::IsPctStyleHeight(aReflowState.mStylePosition) && // pct height
-      ::AncestorsHaveStyleHeight(aReflowState)) {
+      eStyleUnit_Percent == aReflowState.mStylePosition->mHeight.GetUnit() && // pct height
+      nsTableFrame::AncestorsHaveStyleHeight(*aReflowState.parentReflowState)) {
     nsTableFrame::RequestSpecialHeightReflow(aReflowState);
   }
 }
 
 // Notify the frame and its ancestors (up to the containing table) that a special
 // height reflow will occur. During a special height reflow, a table, row group,
 // row, or cell returns the last size it was reflowed at. However, the table may 
 // change the height of row groups, rows, cells in DistributeHeightToRows after. 
--- a/layout/tables/nsTableFrame.h
+++ b/layout/tables/nsTableFrame.h
@@ -110,16 +110,20 @@ public:
 
 
   static void* GetProperty(nsIFrame*            aFrame,
                            nsIAtom*             aPropertyName,
                            PRBool               aCreateIfNecessary = PR_FALSE);
 
   static float GetTwipsToPixels(nsPresContext* aPresContext);
 
+  // Return true if aParentReflowState.frame or any of its ancestors within
+  // the containing table have non-auto height. (e.g. pct or fixed height)
+  static PRBool AncestorsHaveStyleHeight(const nsHTMLReflowState& aParentReflowState);
+
   // See if a special height reflow will occur due to having a pct height when
   // the pct height basis may not yet be valid.
   static void CheckRequestSpecialHeightReflow(const nsHTMLReflowState& aReflowState);
 
   // Notify the frame and its ancestors (up to the containing table) that a special
   // height reflow will occur. 
   static void RequestSpecialHeightReflow(const nsHTMLReflowState& aReflowState);
 
--- a/layout/tables/nsTableRowFrame.cpp
+++ b/layout/tables/nsTableRowFrame.cpp
@@ -1029,16 +1029,19 @@ nsTableRowFrame::Reflow(nsPresContext*  
   PRBool collapseRow = (NS_STYLE_VISIBILITY_COLLAPSE == rowVis->mVisible);
   if (collapseRow) {
     tableFrame->SetNeedToCollapse(PR_TRUE);
   }
 
   // see if a special height reflow needs to occur due to having a pct height
   nsTableFrame::CheckRequestSpecialHeightReflow(aReflowState);
 
+  // See if we have a cell with specified/pct height
+  InitHasCellWithStyleHeight(tableFrame);
+
   rv = ReflowChildren(aPresContext, aDesiredSize, aReflowState, *tableFrame,
                       aStatus);
 
   // just set our width to what was available. The table will calculate the width and not use our value.
   aDesiredSize.width = aReflowState.availableWidth;
 
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
   return rv;
@@ -1328,16 +1331,42 @@ void nsTableRowFrame::SetContinuousBCBor
     case NS_SIDE_LEFT:
       mLeftContBorderWidth = aPixelValue;
       return;
     default:
       NS_ERROR("invalid NS_SIDE arg");
   }
 }
 
+/**
+ * Sets the NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT bit to indicate whether
+ * this row has any cells that have non-auto-height.  (Row-spanning
+ * cells are ignored.)
+ */
+void nsTableRowFrame::InitHasCellWithStyleHeight(nsTableFrame* aTableFrame)
+{
+  nsTableIterator iter(*this);
+
+  for (nsIFrame* kidFrame = iter.First(); kidFrame; kidFrame = iter.Next()) {
+    nsIAtom* frameType = kidFrame->GetType();
+    if (!IS_TABLE_CELL(frameType)) {
+      NS_NOTREACHED("Table row has a non-cell child.");
+      continue;
+    }
+    nsTableCellFrame* cellFrame = NS_STATIC_CAST(nsTableCellFrame*, kidFrame);
+    // Ignore row-spanning cells
+    if (aTableFrame->GetEffectiveRowSpan(*cellFrame) == 1 &&
+        cellFrame->GetStylePosition()->mHeight.GetUnit() != eStyleUnit_Auto) {
+      AddStateBits(NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT);
+      return;
+    }
+  }
+  RemoveStateBits(NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT);
+}
+
 /* ----- global methods ----- */
 
 nsIFrame* 
 NS_NewTableRowFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsTableRowFrame(aContext);
 }
 
--- a/layout/tables/nsTableRowFrame.h
+++ b/layout/tables/nsTableRowFrame.h
@@ -40,20 +40,25 @@
 #include "nscore.h"
 #include "nsHTMLContainerFrame.h"
 #include "nsTablePainter.h"
 
 class  nsTableFrame;
 class  nsTableCellFrame;
 struct nsTableCellReflowState;
 
-#define NS_TABLE_ROW_HAS_UNPAGINATED_HEIGHT 0x40000000
 // This is also used on rows, from nsTableRowGroupFrame.h
 // #define NS_REPEATED_ROW_OR_ROWGROUP      0x10000000
 
+// Indicates whether this row has any cells that have
+// non-auto-height and rowspan=1
+#define NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT   0x20000000
+
+#define NS_TABLE_ROW_HAS_UNPAGINATED_HEIGHT 0x40000000
+
 /**
  * nsTableRowFrame is the frame that maps table rows 
  * (HTML tag TR). This class cannot be reused
  * outside of an nsTableRowGroupFrame.  It assumes that its parent is an nsTableRowGroupFrame,  
  * and its children are nsTableCellFrames.
  * 
  * @see nsTableFrame
  * @see nsTableRowGroupFrame
@@ -297,16 +302,24 @@ private:
 
   // border widths in pixels in the collapsing border model of the *inner*
   // half of the border only
   BCPixelSize mTopBorderWidth;
   BCPixelSize mBottomBorderWidth;
   BCPixelSize mRightContBorderWidth;
   BCPixelSize mTopContBorderWidth;
   BCPixelSize mLeftContBorderWidth;
+
+  /**
+   * Sets the NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT bit to indicate whether
+   * this row has any cells that have non-auto-height.  (Row-spanning
+   * cells are ignored.)
+   */
+  void InitHasCellWithStyleHeight(nsTableFrame* aTableFrame);
+
 };
 
 inline PRInt32 nsTableRowFrame::GetRowIndex() const
 {
   return PRInt32(mBits.mRowIndex);
 }
 
 inline void nsTableRowFrame::SetRowIndex (int aRowIndex)