Bug 162063. Remove pseudo-frames as needed when the frame that needs them is removed from the frame tree. r=bernd, sr=roc. Also fixes bug 97506, bug 143397, bug 156888, bug 277995, bug 293576, bug 315146, bug 338735, bug 339388, bug 407115, 473824.
authorBoris Zbarsky <bzbarsky@mit.edu>
Mon, 23 Mar 2009 14:08:03 -0400
changeset 26471 d0d980778f015fe27306df5fe25d689ba3610abc
parent 26470 3fd33e46a2cd5d44ddf3a071d3b5aa2d9b5c567e
child 26472 b307ac6d68c9cd7f06cca78ef2de403b9cc6fd11
push idunknown
push userunknown
push dateunknown
reviewersbernd, roc
bugs162063, 97506, 143397, 156888, 277995, 293576, 315146, 338735, 339388, 407115, 473824
milestone1.9.2a1pre
Bug 162063. Remove pseudo-frames as needed when the frame that needs them is removed from the frame tree. r=bernd, sr=roc. Also fixes bug 97506, bug 143397, bug 156888, bug 277995, bug 293576, bug 315146, bug 338735, bug 339388, bug 407115, 473824.
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsCSSFrameConstructor.h
layout/reftests/bugs/reftest.list
layout/reftests/table-anonymous-boxes/156888-1-ref.html
layout/reftests/table-anonymous-boxes/156888-1.html
layout/reftests/table-anonymous-boxes/156888-2-ref.html
layout/reftests/table-anonymous-boxes/156888-2.html
layout/reftests/table-anonymous-boxes/162063-1.xhtml
layout/reftests/table-anonymous-boxes/208305-1-ref.html
layout/reftests/table-anonymous-boxes/208305-1.html
layout/reftests/table-anonymous-boxes/277995-1-ref.html
layout/reftests/table-anonymous-boxes/277995-1.html
layout/reftests/table-anonymous-boxes/293576-1-ref.html
layout/reftests/table-anonymous-boxes/293576-1.html
layout/reftests/table-anonymous-boxes/315146-1-ref.xhtml
layout/reftests/table-anonymous-boxes/315146-1.xhtml
layout/reftests/table-anonymous-boxes/338735-1-ref.html
layout/reftests/table-anonymous-boxes/338735-1.html
layout/reftests/table-anonymous-boxes/339388-1-ref.html
layout/reftests/table-anonymous-boxes/339388-1a.html
layout/reftests/table-anonymous-boxes/339388-1b.html
layout/reftests/table-anonymous-boxes/373379-1-ref.html
layout/reftests/table-anonymous-boxes/373379-1.html
layout/reftests/table-anonymous-boxes/407115-1-ref.html
layout/reftests/table-anonymous-boxes/407115-1.html
layout/reftests/table-anonymous-boxes/dynamic-removal-1.html
layout/reftests/table-anonymous-boxes/dynamic-removal-10.html
layout/reftests/table-anonymous-boxes/dynamic-removal-11.html
layout/reftests/table-anonymous-boxes/dynamic-removal-12.html
layout/reftests/table-anonymous-boxes/dynamic-removal-13.html
layout/reftests/table-anonymous-boxes/dynamic-removal-2.html
layout/reftests/table-anonymous-boxes/dynamic-removal-3.html
layout/reftests/table-anonymous-boxes/dynamic-removal-4.html
layout/reftests/table-anonymous-boxes/dynamic-removal-5.html
layout/reftests/table-anonymous-boxes/dynamic-removal-6.html
layout/reftests/table-anonymous-boxes/dynamic-removal-7.html
layout/reftests/table-anonymous-boxes/dynamic-removal-8.html
layout/reftests/table-anonymous-boxes/dynamic-removal-9.html
layout/reftests/table-anonymous-boxes/reftest.list
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -1953,16 +1953,44 @@ IsTableRelated(nsIAtom* aParentType)
     nsGkAtoms::tableRowGroupFrame == aParentType ||
     nsGkAtoms::tableRowFrame      == aParentType ||
     nsGkAtoms::tableCaptionFrame  == aParentType ||
     nsGkAtoms::tableColGroupFrame == aParentType ||
     nsGkAtoms::tableColFrame      == aParentType ||
     IS_TABLE_CELL(aParentType);
 }
 
+// Return whether the given frame is a table pseudo-frame.  Note that
+// cell-content and table-outer frames have pseudo-types, but are always
+// created, even for non-anonymous cells and tables respectively.  So for those
+// we have to examine the cell or table frame to see whether it's a pseudo
+// frame.  In particular, a lone table caption will have an outer table as its
+// parent, but will also trigger construction of an empty inner table, which
+// will be the one we can examine to see whether the outer was a pseudo-frame.
+static PRBool
+IsTablePseudo(nsIFrame* aFrame)
+{
+  nsIAtom* pseudoType = aFrame->GetStyleContext()->GetPseudoType();
+  return pseudoType &&
+    (pseudoType == nsCSSAnonBoxes::table ||
+     pseudoType == nsCSSAnonBoxes::inlineTable ||
+     pseudoType == nsCSSAnonBoxes::tableColGroup ||
+     pseudoType == nsCSSAnonBoxes::tableRowGroup ||
+     pseudoType == nsCSSAnonBoxes::tableRow ||
+     pseudoType == nsCSSAnonBoxes::tableCell ||
+     (pseudoType == nsCSSAnonBoxes::cellContent &&
+      aFrame->GetParent()->GetStyleContext()->GetPseudoType() ==
+        nsCSSAnonBoxes::tableCell) ||
+     (pseudoType == nsCSSAnonBoxes::tableOuter &&
+      (aFrame->GetFirstChild(nsnull)->GetStyleContext()->GetPseudoType() ==
+         nsCSSAnonBoxes::table ||
+       aFrame->GetFirstChild(nsnull)->GetStyleContext()->GetPseudoType() ==
+         nsCSSAnonBoxes::inlineTable)));
+}
+
 /* static */
 nsCSSFrameConstructor::ParentType
 nsCSSFrameConstructor::GetParentType(nsIFrame* aParentFrame)
 {
   nsIAtom* type = aParentFrame->GetType();
   if (type == nsGkAtoms::tableFrame) {
     return eTypeTable;
   }
@@ -7015,22 +7043,18 @@ nsCSSFrameConstructor::ContentRemoved(ns
                         mDocument, childFrame, CONTENT_REMOVED))
     return NS_OK;
 
 #endif // MOZ_XUL
 
   if (childFrame) {
     InvalidateCanvasIfNeeded(mPresShell, aChild);
     
-    // If the frame we are manipulating is a special frame then do
-    // something different instead of just inserting newly created
-    // frames.
-    // NOTE: if we are in ReinsertContent, 
-    //       then do not reframe as we are already doing just that!
-    if (MaybeRecreateContainerForIBSplitterFrame(childFrame, &rv)) {
+    // See whether we need to remove more than just childFrame
+    if (MaybeRecreateContainerForFrameRemoval(childFrame, &rv)) {
       *aDidReconstruct = PR_TRUE;
       return rv;
     }
 
     // Get the childFrame's parent frame
     nsIFrame* parentFrame = childFrame->GetParent();
     nsIAtom* parentType = parentFrame->GetType();
 
@@ -7330,17 +7354,17 @@ ApplyRenderingChangeToTree(nsPresContext
   batch.EndUpdateViewBatch(NS_VMREFRESH_NO_SYNC);
 }
 
 /**
  * This method invalidates the canvas when frames are removed or added for a
  * node that might have its background propagated to the canvas, i.e., a
  * document root node or an HTML BODY which is a child of the root node.
  *
- * @param aFrame a frame for a content node about to be removed or a frme that
+ * @param aFrame a frame for a content node about to be removed or a frame that
  *               was just created for a content node that was inserted.
  */ 
 static void
 InvalidateCanvasIfNeeded(nsIPresShell* presShell, nsIContent* node)
 {
   NS_PRECONDITION(presShell->GetRootFrame(), "What happened here?");
   NS_PRECONDITION(presShell->GetPresContext(), "Say what?");
 
@@ -8669,67 +8693,89 @@ nsCSSFrameConstructor::MaybeRecreateFram
     if (newContext->GetStyleDisplay()->mDisplay != NS_STYLE_DISPLAY_NONE) {
       result = RecreateFramesForContent(aContent);
     }
   }
   return result;
 }
 
 PRBool
-nsCSSFrameConstructor::MaybeRecreateContainerForIBSplitterFrame(nsIFrame* aFrame,
-                                                                nsresult* aResult)
+nsCSSFrameConstructor::MaybeRecreateContainerForFrameRemoval(nsIFrame* aFrame,
+                                                             nsresult* aResult)
 {
   NS_PRECONDITION(aFrame, "Must have a frame");
   NS_PRECONDITION(aFrame->GetParent(), "Frame shouldn't be root");
   NS_PRECONDITION(aResult, "Null out param?");
   NS_PRECONDITION(aFrame == aFrame->GetFirstContinuation(),
                   "aFrame not the result of GetPrimaryFrameFor()?");
 
   if (IsFrameSpecial(aFrame)) {
     // The removal functions can't handle removal of an {ib} split directly; we
     // need to rebuild the containing block.
 #ifdef DEBUG
     if (gNoisyContentUpdates) {
-      printf("nsCSSFrameConstructor::MaybeRecreateContainerForIBSplitterFrame: "
+      printf("nsCSSFrameConstructor::MaybeRecreateContainerForFrameRemoval: "
              "frame=");
       nsFrame::ListTag(stdout, aFrame);
       printf(" is special\n");
     }
 #endif
 
     *aResult = ReframeContainingBlock(aFrame);
     return PR_TRUE;
   }
 
-  // We might still need to reconstruct things if the parent of aFrame is
+  // Now check for possibly needing to reconstruct due to a pseudo parent
+  nsIFrame* inFlowFrame =
+    (aFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) ?
+      mPresShell->FrameManager()->GetPlaceholderFrameFor(aFrame) : aFrame;
+  NS_ASSERTION(inFlowFrame, "How did that happen?");
+  nsIFrame* parent = inFlowFrame->GetParent();
+  if (IsTablePseudo(parent)) {
+    if (parent->GetFirstChild(nsnull) == inFlowFrame ||
+        !inFlowFrame->GetLastContinuation()->GetNextSibling() ||
+        // If we're a table-column-group, then the GetFirstChild check above is
+        // not going to catch cases when we're the first child.
+        (inFlowFrame->GetType() == nsGkAtoms::tableColGroupFrame &&
+         parent->GetFirstChild(nsGkAtoms::colGroupList) == inFlowFrame) ||
+        // Similar if we're a table-caption.
+        (inFlowFrame->GetType() == nsGkAtoms::tableCaptionFrame &&
+         parent->GetFirstChild(nsGkAtoms::captionList) == inFlowFrame)) {
+      // We're the first or last frame in the pseudo.  Need to reframe.
+      // Good enough to recreate frames for |parent|'s content
+      *aResult = RecreateFramesForContent(parent->GetContent());
+      return PR_TRUE;
+    }
+  }
+
+  // We might still need to reconstruct things if the parent of inFlowFrame is
   // special, since in that case the removal of aFrame might affect the
   // splitting of its parent.
-  nsIFrame* parent = aFrame->GetParent();
   if (!IsFrameSpecial(parent)) {
     return PR_FALSE;
   }
 
-  // If aFrame is an inline, then it cannot possibly have caused the splitting.
-  // If the frame is being reconstructed and being changed to a block, the
-  // ContentInserted call will handle the containing block reframe.  So in this
-  // case, we don't need to reframe.
-  if (IsInlineOutside(aFrame)) {
+  // If inFlowFrame is an inline, then it cannot possibly have caused the
+  // splitting.  If the frame is being reconstructed and being changed to a
+  // block, the ContentInserted call will handle the containing block reframe.
+  // So in this case, we don't need to reframe.
+  if (IsInlineOutside(inFlowFrame)) {
     return PR_FALSE;
   }
 
   // If aFrame is not the first or last block, then removing it is not
   // going to affect the splitting.
-  if (aFrame != parent->GetFirstChild(nsnull) &&
-      aFrame->GetLastContinuation()->GetNextSibling()) {
+  if (inFlowFrame != parent->GetFirstChild(nsnull) &&
+      inFlowFrame->GetLastContinuation()->GetNextSibling()) {
     return PR_FALSE;
   }
 
 #ifdef DEBUG
   if (gNoisyContentUpdates) {
-    printf("nsCSSFrameConstructor::MaybeRecreateContainerForIBSplitterFrame: "
+    printf("nsCSSFrameConstructor::MaybeRecreateContainerForFrameRemoval: "
            "frame=");
     nsFrame::ListTag(stdout, parent);
     printf(" is special\n");
   }
 #endif
 
   *aResult = ReframeContainingBlock(parent);
   return PR_TRUE;
@@ -8770,17 +8816,17 @@ nsCSSFrameConstructor::RecreateFramesFor
     nsIFrame* nonGeneratedAncestor = nsLayoutUtils::GetNonGeneratedAncestor(frame);
     if (nonGeneratedAncestor->GetContent() != aContent) {
       return RecreateFramesForContent(nonGeneratedAncestor->GetContent());
     }
   }
 
   nsresult rv = NS_OK;
 
-  if (frame && MaybeRecreateContainerForIBSplitterFrame(frame, &rv)) {
+  if (frame && MaybeRecreateContainerForFrameRemoval(frame, &rv)) {
     return rv;
   }
 
   nsCOMPtr<nsIContent> container = aContent->GetParent();
   if (container) {
     // XXXbz what if this is anonymous content?
     PRInt32 indexInContainer = container->IndexOf(aContent);
     // Before removing the frames associated with the content object,
--- a/layout/base/nsCSSFrameConstructor.h
+++ b/layout/base/nsCSSFrameConstructor.h
@@ -1225,25 +1225,25 @@ private:
                         PRBool                   aBuildCombobox,
                         nsFrameItems&            aFrameItems);
 
   nsresult MaybeRecreateFramesForContent(nsIContent*      aContent);
 
   nsresult RecreateFramesForContent(nsIContent*      aContent);
 
   // If removal of aFrame from the frame tree requires reconstruction of some
-  // containing block (either of aFrame or of its parent) due to {ib} splits,
-  // recreate the relevant containing block.  The return value indicates
-  // whether this happened.  If this method returns true, *aResult is the
-  // return value of ReframeContainingBlock.  If this method returns false, the
-  // value of *aResult is no affected.  aFrame and aResult must not be null.
-  // aFrame must be the result of a GetPrimaryFrameFor() call (which means its
-  // parent is also not null).
-  PRBool MaybeRecreateContainerForIBSplitterFrame(nsIFrame* aFrame,
-                                                  nsresult* aResult);
+  // containing block (either of aFrame or of its parent) due to {ib} splits or
+  // table pseudo-frames, recreate the relevant frame subtree.  The return value
+  // indicates whether this happened.  If this method returns true, *aResult is
+  // the return value of ReframeContainingBlock or RecreateFramesForContent.
+  // If this method returns false, the value of *aResult is no affected.
+  // aFrame and aResult must not be null.  aFrame must be the result of a
+  // GetPrimaryFrameFor() call (which means its parent is also not null).
+  PRBool MaybeRecreateContainerForFrameRemoval(nsIFrame* aFrame,
+                                               nsresult* aResult);
 
   nsresult CreateContinuingOuterTableFrame(nsIPresShell*    aPresShell, 
                                            nsPresContext*  aPresContext,
                                            nsIFrame*        aFrame,
                                            nsIFrame*        aParentFrame,
                                            nsIContent*      aContent,
                                            nsStyleContext*  aStyleContext,
                                            nsIFrame**       aContinuingFrame);
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -223,17 +223,17 @@ skip-if(MOZ_WIDGET_TOOLKIT=="cocoa") != 
 == 271747-1b.html 271747-1-ref.html
 == 272646-1.xul 272646-1-ref.xul
 == 272646-2a.xul 272646-2-ref.xul
 == 272646-2b.xul 272646-2-ref.xul
 == 272646-2c.xul 272646-2-ref.xul
 == 273681-1.html 273681-1-ref.html
 == 278266-1a.html 278266-1-ref.html
 == 278266-1b.html 278266-1-ref.html
-fails == 280708-1a.html 280708-1-ref.html # bug 473824
+== 280708-1a.html 280708-1-ref.html
 == 280708-1b.html 280708-1-ref.html
 == 283686-1.html about:blank
 == 283686-2.html 283686-2-ref.html
 == 283686-3.html about:blank
 fails-if(MOZ_WIDGET_TOOLKIT!="cocoa") HTTP == 289480.html#top 289480-ref.html # basically-verbatim acid2 test, HTTP for a 404 page -- bug 409329 for the non-Mac failures
 == 290129-1.html 290129-1-ref.html
 == 291078-1.html 291078-1-ref.html
 == 291078-2.html 291078-2-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/156888-1-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <table border="5">
+      <tr>
+        <td>Row 1</td>
+      </tr>
+      <tr>
+        <td>Row 2</td>
+      </tr>
+      <tr>
+        <td>Row 3</td>
+      </tr>
+      <tr>
+        <td style="display: inline">Row 4</td>
+      </tr>
+    </table>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/156888-1.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <script language="javascript">
+      function toggleRow(rowId)
+      {
+        var r = document.getElementById(rowId);
+        if (r.style.display == "none")
+          r.style.display = "inline";
+        else
+          r.style.display = "none";
+      }
+
+      function doTest() {
+        toggleRow('row4');
+        document.body.offsetWidth;
+        toggleRow('row4');
+        document.body.offsetWidth;
+        toggleRow('row4');
+      }
+    </script>
+  </head>
+  <body onload="doTest()">
+    <table border="5">
+      <tr>
+        <td>Row 1</td>
+      </tr>
+      <tr>
+        <td>Row 2</td>
+      </tr>
+      <tr>
+        <td>Row 3</td>
+      </tr>
+      <tr>
+        <td id="row4" style="display: none">Row 4</td>
+      </tr>
+    </table>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/156888-2-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <table border="5">
+      <tr>
+        <td>Row 1</td>
+      </tr>
+      <tr>
+        <td>Row 2</td>
+      </tr>
+      <tr>
+        <td>Row 3</td>
+      </tr>
+      <tr style="display: inline">
+        <td>Row 4</td>
+      </tr>
+    </table>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/156888-2.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <script language="javascript">
+      function toggleRow(rowId)
+      {
+        var r = document.getElementById(rowId);
+        if (r.style.display == "none")
+          r.style.display = "inline";
+        else
+          r.style.display = "none";
+      }
+
+      function doTest() {
+        toggleRow('row4');
+        document.body.offsetWidth;
+        toggleRow('row4');
+        document.body.offsetWidth;
+        toggleRow('row4');
+        document.body.offsetWidth;
+        toggleRow('row4');
+        document.body.offsetWidth;
+        toggleRow('row4');
+        document.body.offsetWidth;
+        toggleRow('row4');
+        document.body.offsetWidth;
+        toggleRow('row4');
+        document.body.offsetWidth;
+        toggleRow('row4');
+        document.body.offsetWidth;
+        toggleRow('row4');
+      }
+    </script>
+  </head>
+  <body onload="doTest()">
+    <table border="5">
+      <tr>
+        <td>Row 1</td>
+      </tr>
+      <tr>
+        <td>Row 2</td>
+      </tr>
+      <tr>
+        <td>Row 3</td>
+      </tr>
+      <tr id="row4" style="display: none">
+        <td>Row 4</td>
+      </tr>
+    </table>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/162063-1.xhtml
@@ -0,0 +1,122 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" class="reftest-wait">
+<head>
+<script type="text/javascript">
+/* <![CDATA[ */
+function boom()
+{
+  var numTest = 17;
+  for (i = 1; i<= numTest; i++) {
+    var target = "target" + i; 
+    var q = document.getElementById(target);
+    remove(q);
+  }
+   document.documentElement.className = "";
+
+}
+
+function remove(n)
+{
+  n.parentNode.removeChild(n);
+}
+/* ]]> */
+</script>
+<title> test for pseudo removal</title>
+</head>
+
+<body onload="boom();">
+ <div style="display:table; border-spacing:10px; background-color:red">
+ <div id="target1">target</div>
+ </div>
+ 
+ <div style="display:table; border-spacing:10px; background-color:blue">
+ <div id="target2" style="float:left">target</div>
+ </div>
+ 
+ <div style="display:table; border-spacing:10px; background-color:green">
+ <div id="target3" style="float:right">target</div>
+ </div>
+ 
+ <div style="display:table; border-spacing:10px; background-color:pink">
+ <div id="target4" style="position:absolute">target</div>
+ </div>
+
+ <div style="display:table; border-spacing:10px; background-color:magenta">
+ <div id="target5" style="position:relative">target</div>
+ </div> 
+ 
+ <div style="display:table; border-spacing:10px; background-color:orange">
+ <div id="target6" style="position:fixed">target</div>
+ </div>
+ 
+ <div style="display:table; border-spacing:10px; background-color:yellow">
+ <div style="display:table-row;">
+ <div id="target7" style="display:table">target</div>
+ </div> 
+ </div>
+ 
+  <div style="display:table; border-spacing:10px; background-color:silver">
+ <div style="display:table-row;">
+ <div id="target8" style="display:table-caption">target</div>
+ </div> 
+ </div>
+ 
+ <div style="display:table; border-spacing:10px; background-color:navy">
+ <div id="target9" style="display:-moz-column">target</div>
+ </div>
+ 
+ <div style="display:table; border-spacing:10px; background-color:teal">
+ <div id="target10" style="display:-moz-popup">target</div>
+ </div>
+ 
+ <div style="display:table; border-spacing:10px; background-color:Maroon">
+     <math xmlns="http://www.w3.org/1998/Math/MathML" id="target11">
+        <msup>
+          <mfenced>
+            <mrow>
+              <mi>a</mi>
+              <mo>+</mo>
+              <mi>b</mi>
+            </mrow>
+          </mfenced>
+          <mn>2</mn>
+        </msup>
+    </math>
+ </div>
+ 
+ <div style="display:table; border-spacing:10px; background-color:SkyBlue ">
+  <svg xmlns="http://www.w3.org/2000/svg" width="300" height="200" id="target12">
+      <circle cx="150" cy="100" r="50" />
+    </svg>
+</div>
+
+ 
+ <div style="display:table; border-spacing:10px; background-color:Peru">
+  <div style="display:table-row;">
+  <div id="target13" style="display:table-row-group; overflow:scroll">target</div>
+  </div>
+</div>
+ 
+ <div style="display:table; border-spacing:10px; background-color:Tomato">
+  <div style="display:table-row;">
+  <input type="button" value="OK" id="target14"></input>
+  </div>
+</div>
+ 
+ <div style="display:table; border-spacing:10px; background-color:DarkSeaGreen ">
+  <div style="display:table-row;">
+   <div id="target15" style="display:table-column;"/>
+  </div>
+</div>
+
+<div style="display:table; border-spacing:10px; background-color:MistyRose">
+  <div style="display:table-row;">
+   <div id="target16" style="display:table-column-group;"/>
+  </div>
+</div>
+
+<div style="display:table; border-spacing:10px; background-color:Indigo">
+ <div id="target17" style="display:-moz-box">target</div>
+ </div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/208305-1-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+</head>
+
+<body>
+<div>foo</div><div>bar</div><div>baz</div>
+</body>
+
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/208305-1.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<style type="text/css">
+.cell {display:table-cell}
+</style>
+<script type="text/javascript">
+function doTest() {
+ss = document.styleSheets[0];
+ss.cssRules[0].style.display="block";
+}
+</script>
+</head>
+
+<body onload="doTest()">
+<div class="cell">foo</div><div class="cell">bar</div><div class="cell">baz</div>
+</body>
+
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/277995-1-ref.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body onload="doTest()">
+<table>
+  <tr>
+    <td>
+      <div style="display: table">
+        <div id="data" style="display: table-row-group">
+          <div style="display: table-row">
+            <div style="display: table-cell">
+              More Data
+            </div>
+          </div>
+          <div style="display: table-row">
+            <div style="display: table-cell">
+              More Data
+            </div>
+          </div>
+          <div style="display: table-row">
+            <div style="display: table-cell">
+              More Data
+            </div>
+          </div>
+          <div style="display: table-row">
+            <div style="display: table-cell">
+              More Data
+            </div>
+          </div>
+          <div style="display: table-row">
+            <div style="display: table-cell">
+              More Data
+            </div>
+          </div>
+          <div style="display: table-row">
+            <div style="display: table-cell">
+              More Data
+            </div>
+          </div>
+          <div style="display: table-row">
+            <div style="display: table-cell">
+              More Data
+            </div>
+          </div>
+          <div style="display: table-row">
+            <div style="display: table-cell">
+              More Data
+            </div>
+          </div>
+          <div style="display: table-row">
+            <div style="display: table-cell">
+              More Data
+            </div>
+          </div>
+          <div style="display: table-row">
+            <div style="display: table-cell">
+              More Data
+            </div>
+          </div>
+        </div>
+      </div>
+    </td>
+  </tr>
+</table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/277995-1.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+  <script type="text/javascript" language="javascript">
+    function doMore(data) {
+      while(data.hasChildNodes()) 
+        data.removeChild(data.firstChild);
+      for (var i = 0; i < 10; i++) {
+	append(data);
+      }
+    }
+
+    function append(data) {
+      var row = document.createElement("div");
+      row.setAttribute("class", "row");
+
+      var cell = document.createElement("span");
+      cell.appendChild(document.createTextNode("More Data"));
+      cell.setAttribute("style", "cell");
+      row.appendChild(cell);
+      data.appendChild(row);
+    }
+
+    function doTest() {
+      for (var i = 0; i < 10; ++i) {
+        document.body.offsetWidth;
+        doMore(document.getElementById('data'));
+      }
+      document.documentElement.className = '';
+    }
+  </script>
+  <style>
+    .table {
+      display: table;
+    }
+    .row {
+      display: table-row;
+
+    }
+    .cell {
+      display: table-cell;
+    }
+  </style>
+</head>
+<body onload="doTest()">
+<table>
+  <tr>
+    <td>
+      <div id="data" class="table">
+      </div>
+    </td>
+  </tr>
+</table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/293576-1-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <table border="5"><tbody><tr><td id="t">Some text</td></tr></tbody></table>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/293576-1.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+  <head>
+    <script>
+      function doTest() {
+        var t = document.getElementById("t");
+        for (var i = 0; i < 10; ++i) {
+          document.body.offsetWidth;
+          t.style.display = "table-caption";
+          document.body.offsetWidth;
+          t.style.display = "";
+        }
+        document.documentElement.className = '';
+      }
+    </script>
+  </head>
+  <body onload="doTest()">
+    <table border="5"><tbody><tr><td id="t">Some text</td></tr></tbody></table>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/315146-1-ref.xhtml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<body>
+<table id="table" border="5"><tr><td>A cell</td></tr></table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/315146-1.xhtml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en" class="reftest-wait">
+<head>
+	<script type="text/javascript"><![CDATA[
+	function DeleteRow(container) {
+		if (container.firstChild)
+			container.removeChild(container.firstChild);
+	}
+
+	function AddRow(container) {
+		var tr = document.createElement("tr");
+		var td = document.createElement("td");
+		td.appendChild(document.createTextNode("A cell"));
+		tr.appendChild(td);
+		container.appendChild(tr);
+	}
+
+        function doTest() {
+          for (var i = 0; i < 10; ++i) {
+            document.body.offsetWidth;
+            AddRow(document.getElementById('table'));
+            document.body.offsetWidth;
+            DeleteRow(document.getElementById('table'));
+          }
+          document.documentElement.className = '';
+        }
+	]]></script>
+</head>
+<body onload="doTest()">
+<table id="table" border="5"><tr><td>A cell</td></tr></table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/338735-1-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<body>
+<table style="width: 100%;" border="5">
+  <tr>
+          <td>First row</td>
+  </tr>
+  <tr>
+          <td>Second row</td>
+  </tr>
+</table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/338735-1.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<style>
+  #t {
+    display: none;
+  }
+</style>
+<script lang="JavaScript">
+  function toggleLayer(id) {
+      var s = document.getElementById(id).style;
+      s.display = s.display ? "" : "block";
+  }
+
+  function doTest() {
+    toggleLayer('t');
+    document.body.offsetWidth;
+    toggleLayer('t');
+    document.body.offsetWidth;
+    toggleLayer('t');
+    document.documentElement.className = "";
+  }
+</script>
+</head>
+<body onload="doTest()">
+<table style="width: 100%;" border="5">
+  <tr>
+          <td id="t">First row</td>
+  </tr>
+  <tr>
+          <td>Second row</td>
+  </tr>
+</table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/339388-1-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <table border="5">
+      <tr>
+        <td id="n">TD</td>
+      </tr>
+    </table>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/339388-1a.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+  <head>
+    <script>
+      function doTest() {
+        var n = document.getElementById("n");
+        for (var i = 0; i < 5; ++i) {
+          n.style.cssFloat = "left";
+          document.body.offsetWidth;
+          n.style.cssFloat = "";
+          document.body.offsetWidth;
+        }
+        document.documentElement.className = "";
+      }
+    </script>
+  </head>
+
+  <body onload="doTest()">
+    <table border="5">
+      <tr>
+        <td id="n">TD</td>
+      </tr>
+    </table>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/339388-1b.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+  <head>
+    <script>
+      function doTest() {
+        var n = document.getElementById("n");
+        for (var i = 0; i < 5; ++i) {
+          n.style.position = "absolute";
+          document.body.offsetWidth;
+          n.style.position = "";
+          document.body.offsetWidth;
+        }
+        document.documentElement.className = "";
+      }
+    </script>
+  </head>
+
+  <body onload="doTest()">
+    <table border="5">
+      <tr>
+        <td id="n">TD</td>
+      </tr>
+    </table>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/373379-1-ref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+ <head>
+  <style type="text/css">
+
+   .border { border: 1px solid blue; }
+
+  </style>
+ </head>
+ <body>
+
+   <span class="border">
+      <span>x</span>
+   </span>
+  
+ </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/373379-1.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+ <head>
+  <style type="text/css">
+
+   #tablecell {
+     display: table-cell;
+   }
+   .border { border: 1px solid blue; }
+
+  </style>
+ </head>
+ <body>
+
+   <span class="border">
+      <span id="tablecell">x</span>
+   </span>
+  
+   <script>
+
+   document.body.offsetWidth;
+   document.getElementById("tablecell").removeAttribute("id");
+
+   </script>
+ </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/407115-1-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<style>
+.outer { border: 1px solid black; }
+.cell { display: table-cell; border: 1px solid green; }
+.marg { margin: 1em 0; }
+</style>
+</head>
+<body>
+
+<div class="outer">
+<div class="marg"></div>
+<div class="marg"><span class="cell"><b>Hello Kitty</b></span></div>
+<div class="marg"><span class="cell"><b>Hello Kitty</b></span></div>
+<div class="marg"><span class="cell"><b>Hello Kitty</b></span></div>
+</div>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/407115-1.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<style>
+.outer { border: 1px solid black; }
+.cell { display: table-cell; border: 1px solid green; }
+.marg { margin: 1em 0; }
+</style>
+</head>
+<body onload="var c1 = document.getElementById('c1'); c1.parentNode.removeChild(c1);">
+
+<div class="outer">
+<div class="marg"><span id="c1" class="cell"><b>Hello Kitty</b></span></div>
+<div class="marg"><span class="cell"><b>Hello Kitty</b></span></div>
+<div class="marg"><span class="cell"><b>Hello Kitty</b></span></div>
+<div class="marg"><span class="cell"><b>Hello Kitty</b></span></div>
+</div>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/dynamic-removal-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+  <head>
+    <script>
+      function doTest() {
+        var t = document.getElementById("t");
+        t.parentNode.removeChild(t);
+        document.documentElement.className = "";
+      }
+    </script>
+  </head>
+  <body style="font-family: monospace" onload="doTest()">
+    <span style="display: table-row-group"> 
+      <span style="display: table-cell">Row 1, Col 1</span>
+      <span style="display: table-cell">Row 1, Col 2</span>
+      <span style="display: table-cell">Row 1, Col 3</span>
+    </span>
+    <span style="display: table-row-group"> 
+      <span style="display: table-cell">Row 22, Col 1</span>
+      <span id="t">To be removed</span>
+      <span style="display: table-cell">Row 22, Col 2</span>
+      <span style="display: table-cell">Row 22, Col 3</span>
+    </span>
+    <span style="display: table-row-group"> 
+      <span style="display: table-cell">Row 333, Col 1</span>
+      <span style="display: table-cell">Row 333, Col 2</span>
+      <span style="display: table-cell">Row 333, Col 3</span>
+    </span>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/dynamic-removal-10.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+  <head>
+    <script>
+      function doTest() {
+        var t = document.getElementById("t");
+        t.parentNode.removeChild(t);
+        document.documentElement.className = "";
+      }
+    </script>
+  </head>
+  <body onload="doTest()">
+    <span>
+      <span>a</span><span id="t" style="display: table-column-group"></span>
+      <span style="display: table-column-group"></span><span>bc d</span>
+    </span>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/dynamic-removal-11.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+  <head>
+    <script>
+      function doTest() {
+        var t = document.getElementById("t");
+        t.parentNode.removeChild(t);
+        document.documentElement.className = "";
+      }
+    </script>
+  </head>
+  <body onload="doTest()">
+    <span>
+      <span>a</span><span id="t" style="display: table-caption"></span>
+      <span style="display: table-caption"></span><span>bc d</span>
+    </span>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/dynamic-removal-12.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+  <head>
+    <script>
+      function doTest() {
+        var t = document.getElementById("t");
+        t.parentNode.removeChild(t);
+        document.documentElement.className = "";
+      }
+    </script>
+  </head>
+  <body onload="doTest()">
+    <div>
+      <span>a b</span><span id="t" style="display: table-row"></span><span>c d</span>
+    </div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/dynamic-removal-13.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+  <head>
+    <script>
+      function doTest() {
+        var t = document.getElementById("t");
+        t.parentNode.removeChild(t);
+        document.documentElement.className = "";
+      }
+    </script>
+  </head>
+  <body style="font-family: monospace" onload="doTest()">
+    <span style="display: table-row-group"> 
+      <span style="display: table-cell">Row 1, Col 1</span>
+      <span style="display: table-cell">Row 1, Col 2</span>
+      <span style="display: table-cell">Row 1, Col 3</span>
+    </span>
+    <span style="display: table-row-group"> 
+      <span style="display: table-cell">Row 22, Col 1</span>
+      <span id="t" style="position: absolute">To be removed</span>
+      <span style="display: table-cell">Row 22, Col 2</span>
+      <span style="display: table-cell">Row 22, Col 3</span>
+    </span>
+    <span style="display: table-row-group"> 
+      <span style="display: table-cell">Row 333, Col 1</span>
+      <span style="display: table-cell">Row 333, Col 2</span>
+      <span style="display: table-cell">Row 333, Col 3</span>
+    </span>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/dynamic-removal-2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+  <head>
+    <script>
+      function doTest() {
+        var t = document.getElementById("t");
+        t.parentNode.removeChild(t);
+        document.documentElement.className = "";
+      }
+    </script>
+  </head>
+  <body style="font-family: monospace" onload="doTest()">
+    <span style="display: table-row-group"> 
+      <span style="display: table-cell">Row 1, Col 1</span>
+      <span style="display: table-cell">Row 1, Col 2</span>
+      <span style="display: table-cell">Row 1, Col 3</span>
+    </span>
+    <span style="display: table-row-group"> 
+      <span style="display: table-cell">Row 22, Col 1</span>
+      <span id="t" style="display: table-cell">To be removed</span>
+      <span style="display: table-cell">Row 22, Col 2</span>
+      <span style="display: table-cell">Row 22, Col 3</span>
+    </span>
+    <span style="display: table-row-group"> 
+      <span style="display: table-cell">Row 333, Col 1</span>
+      <span style="display: table-cell">Row 333, Col 2</span>
+      <span style="display: table-cell">Row 333, Col 3</span>
+    </span>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/dynamic-removal-3.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+  <head>
+    <script>
+      function doTest() {
+        var t = document.getElementById("t");
+        t.parentNode.removeChild(t);
+        document.documentElement.className = "";
+      }
+    </script>
+  </head>
+  <body style="font-family: monospace" onload="doTest()">
+    <span style="display: table-row-group"> 
+      <span style="display: table-cell">Row 1, Col 1</span>
+      <span style="display: table-cell">Row 1, Col 2</span>
+      <span style="display: table-cell">Row 1, Col 3</span>
+    </span>
+    <span style="display: table-row-group"> 
+      <span style="display: table-cell">Row 22, Col 1</span>
+      <span id="t" style="display: table-row">To be removed</span>
+      <span style="display: table-cell">Row 22, Col 2</span>
+      <span style="display: table-cell">Row 22, Col 3</span>
+    </span>
+    <span style="display: table-row-group"> 
+      <span style="display: table-cell">Row 333, Col 1</span>
+      <span style="display: table-cell">Row 333, Col 2</span>
+      <span style="display: table-cell">Row 333, Col 3</span>
+    </span>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/dynamic-removal-4.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+  <head>
+    <script>
+      function doTest() {
+        var t = document.getElementById("t");
+        t.parentNode.removeChild(t);
+        document.documentElement.className = "";
+      }
+    </script>
+  </head>
+  <body style="font-family: monospace" onload="doTest()">
+    <span style="display: table-row-group"> 
+      <span style="display: table-cell">Row 1, Col 1</span>
+      <span style="display: table-cell">Row 1, Col 2</span>
+      <span style="display: table-cell">Row 1, Col 3</span>
+    </span>
+    <span style="display: table-row-group"> 
+      <span style="display: table-cell">Row 22, Col 1</span>
+      <span id="t" style="display: table-row-group">To be removed</span>
+      <span style="display: table-cell">Row 22, Col 2</span>
+      <span style="display: table-cell">Row 22, Col 3</span>
+    </span>
+    <span style="display: table-row-group"> 
+      <span style="display: table-cell">Row 333, Col 1</span>
+      <span style="display: table-cell">Row 333, Col 2</span>
+      <span style="display: table-cell">Row 333, Col 3</span>
+    </span>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/dynamic-removal-5.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+  <head>
+    <script>
+      function doTest() {
+        var t = document.getElementById("t");
+        t.parentNode.removeChild(t);
+        document.documentElement.className = "";
+      }
+    </script>
+  </head>
+  <body style="font-family: monospace" onload="doTest()">
+    <span style="display: table-row-group"> 
+      <span style="display: table-cell">Row 1, Col 1</span>
+      <span style="display: table-cell">Row 1, Col 2</span>
+      <span style="display: table-cell">Row 1, Col 3</span>
+    </span>
+    <span style="display: table-row-group"> 
+      <span style="display: table-cell">Row 22, Col 1</span>
+      <span id="t" style="display: table">To be removed</span>
+      <span style="display: table-cell">Row 22, Col 2</span>
+      <span style="display: table-cell">Row 22, Col 3</span>
+    </span>
+    <span style="display: table-row-group"> 
+      <span style="display: table-cell">Row 333, Col 1</span>
+      <span style="display: table-cell">Row 333, Col 2</span>
+      <span style="display: table-cell">Row 333, Col 3</span>
+    </span>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/dynamic-removal-6.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+  <head>
+    <script>
+      function doTest() {
+        var t = document.getElementById("t");
+        t.parentNode.removeChild(t);
+        document.documentElement.className = "";
+      }
+    </script>
+  </head>
+  <body style="font-family: monospace" onload="doTest()">
+    <span style="display: table-row-group"> 
+      <span style="display: table-cell">Row 1, Col 1</span>
+      <span style="display: table-cell">Row 1, Col 2</span>
+      <span style="display: table-cell">Row 1, Col 3</span>
+    </span>
+    <span style="display: table-row-group"> 
+      <span style="display: table-cell">Row 22, Col 1</span>
+      <span id="t" style="display: table-column">To be removed</span>
+      <span style="display: table-cell">Row 22, Col 2</span>
+      <span style="display: table-cell">Row 22, Col 3</span>
+    </span>
+    <span style="display: table-row-group"> 
+      <span style="display: table-cell">Row 333, Col 1</span>
+      <span style="display: table-cell">Row 333, Col 2</span>
+      <span style="display: table-cell">Row 333, Col 3</span>
+    </span>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/dynamic-removal-7.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+  <head>
+    <script>
+      function doTest() {
+        var t = document.getElementById("t");
+        t.parentNode.removeChild(t);
+        document.documentElement.className = "";
+      }
+    </script>
+  </head>
+  <body style="font-family: monospace" onload="doTest()">
+    <span style="display: table-row-group"> 
+      <span style="display: table-cell">Row 1, Col 1</span>
+      <span style="display: table-cell">Row 1, Col 2</span>
+      <span style="display: table-cell">Row 1, Col 3</span>
+    </span>
+    <span style="display: table-row-group"> 
+      <span style="display: table-cell">Row 22, Col 1</span>
+      <span id="t" style="display: table-column-group">To be removed</span>
+      <span style="display: table-cell">Row 22, Col 2</span>
+      <span style="display: table-cell">Row 22, Col 3</span>
+    </span>
+    <span style="display: table-row-group"> 
+      <span style="display: table-cell">Row 333, Col 1</span>
+      <span style="display: table-cell">Row 333, Col 2</span>
+      <span style="display: table-cell">Row 333, Col 3</span>
+    </span>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/dynamic-removal-8.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+  <head>
+    <script>
+      function doTest() {
+        var t = document.getElementById("t");
+        t.parentNode.removeChild(t);
+        document.documentElement.className = "";
+      }
+    </script>
+  </head>
+  <body style="font-family: monospace" onload="doTest()">
+    <span style="display: table-row-group"> 
+      <span style="display: table-cell">Row 1, Col 1</span>
+      <span style="display: table-cell">Row 1, Col 2</span>
+      <span style="display: table-cell">Row 1, Col 3</span>
+    </span>
+    <span style="display: table-row-group"> 
+      <span style="display: table-cell">Row 22, Col 1</span>
+      <span id="t" style="display: table-caption">To be removed</span>
+      <span style="display: table-cell">Row 22, Col 2</span>
+      <span style="display: table-cell">Row 22, Col 3</span>
+    </span>
+    <span style="display: table-row-group"> 
+      <span style="display: table-cell">Row 333, Col 1</span>
+      <span style="display: table-cell">Row 333, Col 2</span>
+      <span style="display: table-cell">Row 333, Col 3</span>
+    </span>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/dynamic-removal-9.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+  <head>
+    <script>
+      function doTest() {
+        var t = document.getElementById("t");
+        t.parentNode.removeChild(t);
+        document.documentElement.className = "";
+      }
+    </script>
+  </head>
+  <body onload="doTest()">
+    <div>
+      <span>a b</span><span id="t" style="display: table-cell"></span><span>c d</span>
+    </div>
+  </body>
+</html>
--- a/layout/reftests/table-anonymous-boxes/reftest.list
+++ b/layout/reftests/table-anonymous-boxes/reftest.list
@@ -1,8 +1,20 @@
+fails == 156888-1.html 156888-1-ref.html # bug 484825
+== 156888-2.html 156888-2-ref.html
+== 162063-1.xhtml about:blank
+== 208305-1.html 208305-1-ref.html
+== 277995-1.html 277995-1-ref.html
+== 293576-1.html 293576-1-ref.html
+== 315146-1.xhtml 315146-1-ref.xhtml
+== 338735-1.html 338735-1-ref.html
+== 339388-1a.html 339388-1-ref.html
+== 339388-1b.html 339388-1-ref.html
+== 373379-1.html 373379-1-ref.html
+== 407115-1.html 407115-1-ref.html
 == infer-first-row.html 3x3-ref.html
 == infer-first-row-and-table.html 3x3-ref.html
 == infer-second-row.html 3x3-ref.html
 == infer-second-row-and-table.html 3x3-ref.html
 == infer-table-around-headers-footers-1.html 3x3-ref.html
 == infer-table-around-headers-footers-2.html 3x3-ref.html
 == infer-table-around-headers-footers-3.html 3x3-ref.html
 == infer-rows-inside-rowgroups.html 3x3-ref.html
@@ -13,9 +25,22 @@
 == blocks-divide-tables-2.html 3-tables-ref.html
 == infer-cells-1.html 3-tables-ref.html
 == infer-cells-2.html 3x3-ref.html
 == infer-cells-3.html 3x3-ref.html
 == infer-cells-4.html 3x3-ref.html
 == cols-test-1.html 3x3-cols-ref.html
 == cols-test-2.html 3x3-cols-ref.html
 == cols-test-3.html 3x3-cols-ref.html
+== dynamic-removal-1.html 3x3-ref.html
+== dynamic-removal-2.html 3x3-ref.html
+fails == dynamic-removal-3.html 3x3-ref.html
+== dynamic-removal-4.html 3x3-ref.html
+== dynamic-removal-5.html 3x3-ref.html
+== dynamic-removal-6.html 3x3-ref.html
+== dynamic-removal-7.html 3x3-ref.html
+== dynamic-removal-8.html 3x3-ref.html
+== dynamic-removal-9.html white-space-1-ref.html
+== dynamic-removal-10.html white-space-1-ref.html
+== dynamic-removal-11.html white-space-1-ref.html
+== dynamic-removal-12.html white-space-1-ref.html
+== dynamic-removal-13.html 3x3-ref.html
 == white-space-1.html white-space-1-ref.html