Backed out changeset 0ea22856b5d9 (bug 484448).
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 08 Apr 2009 15:56:43 -0400
changeset 27095 3c7cd3a8f785ec9a09fb4b5244f1c095f26c6fc1
parent 27086 0ea22856b5d9e25e2b687e3fb6f3da557274f42a
child 27096 04eae810df55bdcdc9da060ae951390dd8119eb6
push id6388
push userbzbarsky@mozilla.com
push dateWed, 08 Apr 2009 19:58:02 +0000
treeherdermozilla-central@04eae810df55 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs484448
milestone1.9.2a1pre
backs out0ea22856b5d9e25e2b687e3fb6f3da557274f42a
Backed out changeset 0ea22856b5d9 (bug 484448).
content/base/src/nsGenericDOMDataNode.cpp
content/base/src/nsGenericDOMDataNode.h
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsCSSFrameConstructor.h
layout/generic/nsTextFrameThebes.cpp
layout/mathml/nsMathMLmtableFrame.h
layout/reftests/table-anonymous-boxes/3-blocks-ref.html
layout/reftests/table-anonymous-boxes/3-tables-ref.html
layout/reftests/table-anonymous-boxes/372641-1-ref.xhtml
layout/reftests/table-anonymous-boxes/372641-1a.xhtml
layout/reftests/table-anonymous-boxes/372641-1b.xhtml
layout/reftests/table-anonymous-boxes/372641-1c.xhtml
layout/reftests/table-anonymous-boxes/3x3-cols-ref.html
layout/reftests/table-anonymous-boxes/3x3-ref.html
layout/reftests/table-anonymous-boxes/dynamic-removal-14.html
layout/reftests/table-anonymous-boxes/infer-cells-1.html
layout/reftests/table-anonymous-boxes/reftest.list
layout/reftests/table-anonymous-boxes/white-space-1-ref.html
layout/reftests/table-anonymous-boxes/white-space-1.html
layout/reftests/table-anonymous-boxes/white-space-10.html
layout/reftests/table-anonymous-boxes/white-space-11.html
layout/reftests/table-anonymous-boxes/white-space-12.html
layout/reftests/table-anonymous-boxes/white-space-13.html
layout/reftests/table-anonymous-boxes/white-space-14.html
layout/reftests/table-anonymous-boxes/white-space-15.html
layout/reftests/table-anonymous-boxes/white-space-16.html
layout/reftests/table-anonymous-boxes/white-space-17.html
layout/reftests/table-anonymous-boxes/white-space-18.html
layout/reftests/table-anonymous-boxes/white-space-19.html
layout/reftests/table-anonymous-boxes/white-space-2.html
layout/reftests/table-anonymous-boxes/white-space-20.html
layout/reftests/table-anonymous-boxes/white-space-21.html
layout/reftests/table-anonymous-boxes/white-space-22.html
layout/reftests/table-anonymous-boxes/white-space-23.html
layout/reftests/table-anonymous-boxes/white-space-24.html
layout/reftests/table-anonymous-boxes/white-space-25.html
layout/reftests/table-anonymous-boxes/white-space-26.html
layout/reftests/table-anonymous-boxes/white-space-3.html
layout/reftests/table-anonymous-boxes/white-space-4.html
layout/reftests/table-anonymous-boxes/white-space-5.html
layout/reftests/table-anonymous-boxes/white-space-6.html
layout/reftests/table-anonymous-boxes/white-space-7.html
layout/reftests/table-anonymous-boxes/white-space-8.html
layout/reftests/table-anonymous-boxes/white-space-9.html
layout/reftests/table-anonymous-boxes/white-space-pre-1.html
layout/reftests/table-anonymous-boxes/white-space-pre-ref.html
layout/reftests/table-anonymous-boxes/white-space-ref.html
layout/tables/nsTableColFrame.h
layout/tables/nsTableColGroupFrame.h
layout/tables/nsTableFrame.h
layout/tables/nsTableOuterFrame.h
layout/tables/nsTableRowFrame.h
layout/tables/nsTableRowGroupFrame.h
--- a/content/base/src/nsGenericDOMDataNode.cpp
+++ b/content/base/src/nsGenericDOMDataNode.cpp
@@ -580,20 +580,16 @@ nsGenericDOMDataNode::BindToTree(nsIDocu
                    "Bound to wrong binding parent");
 
   return NS_OK;
 }
 
 void
 nsGenericDOMDataNode::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
 {
-  // Unset FRAMETREE_DEPENDS_ON_CHARS; if we need it again later, it'll get set
-  // again.
-  UnsetFlags(FRAMETREE_DEPENDS_ON_CHARS);
-  
   nsIDocument *document = GetCurrentDoc();
   if (document) {
     // Notify XBL- & nsIAnonymousContentCreator-generated
     // anonymous content that the document is changing.
     // This is needed to update the insertion point.
     document->BindingManager()->ChangeDocumentFor(this, document, nsnull);
   }
 
--- a/content/base/src/nsGenericDOMDataNode.h
+++ b/content/base/src/nsGenericDOMDataNode.h
@@ -38,19 +38,16 @@
 /*
  * Base class for DOM Core's nsIDOMComment, nsIDOMDocumentType, nsIDOMText,
  * nsIDOMCDATASection, and nsIDOMProcessingInstruction nodes.
  */
 
 #ifndef nsGenericDOMDataNode_h___
 #define nsGenericDOMDataNode_h___
 
-// This bit is set if the frame tree depends on whether this node is whitespace
-#define FRAMETREE_DEPENDS_ON_CHARS (1 << NODE_TYPE_SPECIFIC_BITS_OFFSET)
-
 #include "nsIDOMCharacterData.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIDOM3Text.h"
 #include "nsTextFragment.h"
 #include "nsDOMError.h"
 #include "nsIEventListenerManager.h"
 #include "nsGenericElement.h"
 #include "nsCycleCollectionParticipant.h"
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -117,17 +117,16 @@
 #include "nsIObjectLoadingContent.h"
 #include "nsContentErrors.h"
 #include "nsIPrincipal.h"
 #include "nsIDOMWindowInternal.h"
 #include "nsStyleUtil.h"
 #include "nsIFocusEventSuppressor.h"
 #include "nsBox.h"
 #include "nsTArray.h"
-#include "nsGenericDOMDataNode.h"
 
 #ifdef MOZ_XUL
 #include "nsIRootBox.h"
 #include "nsIDOMXULCommandDispatcher.h"
 #include "nsIDOMXULDocument.h"
 #include "nsIXULDocument.h"
 #endif
 #ifdef ACCESSIBILITY
@@ -1919,16 +1918,23 @@ nsCSSFrameConstructor::CreateGeneratedCo
       container->AppendChildTo(content, PR_FALSE);
     }
   }
 
   AddFrameConstructionItemsInternal(aState, container, aParentFrame, elemName,
                                     kNameSpaceID_None, pseudoStyleContext,
                                     ITEM_IS_GENERATED_CONTENT, aItems);
 }
+
+static PRBool
+TextIsOnlyWhitespace(nsIContent* aContent)
+{
+  return aContent->IsNodeOfType(nsINode::eTEXT) &&
+         aContent->TextIsOnlyWhitespace();
+}
     
 /****************************************************
  **  BEGIN TABLE SECTION
  ****************************************************/
 
 // The term pseudo frame is being used instead of anonymous frame, since anonymous
 // frame has been used elsewhere to refer to frames that have generated content
 
@@ -2363,31 +2369,19 @@ NeedFrameFor(nsIFrame*   aParentFrame,
              nsIContent* aChildContent) 
 {
   // don't create a whitespace frame if aParentFrame doesn't want it.
   // always create frames for children in generated content. counter(),
   // quotes, and attr() content can easily change dynamically and we don't
   // want to be reconstructing frames. It's not even clear that these
   // should be considered ignorable just because they evaluate to
   // whitespace.
-
-  // We could handle all this in CreateNeededTablePseudos or some other place
-  // after we build our frame construction items, but that would involve
-  // creating frame construction items for whitespace kids of
-  // eExcludesIgnorableWhitespace frames, where we know we'll be dropping them
-  // all anyway, and involve an extra walk down the frame construction item
-  // list.
-  if (!aParentFrame->IsFrameOfType(nsIFrame::eExcludesIgnorableWhitespace) ||
-      aParentFrame->IsGeneratedContentFrame() ||
-      !aChildContent->IsNodeOfType(nsINode::eTEXT)) {
-    return PR_TRUE;
-  }
-
-  aChildContent->SetFlags(FRAMETREE_DEPENDS_ON_CHARS);
-  return !aChildContent->TextIsOnlyWhitespace();
+  return !aParentFrame->IsFrameOfType(nsIFrame::eExcludesIgnorableWhitespace)
+    || !TextIsOnlyWhitespace(aChildContent)
+    || aParentFrame->IsGeneratedContentFrame();
 }
 
 /***********************************************
  * END TABLE SECTION
  ***********************************************/
 
 static PRBool CheckOverflow(nsPresContext* aPresContext,
                             const nsStyleDisplay* aDisplay)
@@ -6171,17 +6165,16 @@ nsCSSFrameConstructor::ContentAppended(n
 
   nsIAtom* frameType = parentFrame->GetType();
   // We should never get here with fieldsets, since they have multiple
   // insertion points.
   NS_ASSERTION(frameType != nsGkAtoms::fieldSetFrame,
                "Unexpected parent");
 
   // Deal with possible :after generated content on the parent
-  nsIFrame* origParentFrame = parentFrame;
   nsIFrame* parentAfterFrame;
   parentFrame =
     ::AdjustAppendParentForAfterContent(mPresShell->GetPresContext(),
                                         aContainer, parentFrame,
                                         &parentAfterFrame);
   
   // Create some new frames
   nsFrameConstructorState state(mPresShell, mFixedContainingBlock,
@@ -6207,37 +6200,23 @@ nsCSSFrameConstructor::ContentAppended(n
   FrameConstructionItemList items;
   for (PRUint32 i = aNewIndexInContainer, count = aContainer->GetChildCount();
        i < count;
        ++i) {
     AddFrameConstructionItems(state, aContainer->GetChildAt(i), parentFrame,
                               items);
   }
 
-  // Determine whether this is an insert at the beginning
-  PRBool isInsertAtStart = PR_TRUE;
-  nsIFrame* curParent = parentFrame;
-  nsIFrame* curAfterChild = parentAfterFrame;
-  do {
-    if (curParent->GetPrevContinuation() ||
-        curParent->GetFirstChild(nsnull) != curAfterChild) {
-      isInsertAtStart = PR_FALSE;
-      break;
-    }
-    curAfterChild = curParent;
-    curParent = curParent->GetParent();
-  } while (curAfterChild != origParentFrame);
-
   // Perform special check for diddling around with the frames in
   // a special inline frame.
   // If we're appending before :after content, then we're not really
   // appending, so let WipeContainingBlock know that.
   LAYOUT_PHASE_TEMP_EXIT();
   if (WipeContainingBlock(state, containingBlock, parentFrame, items,
-                          !parentAfterFrame, isInsertAtStart, nsnull)) {
+                          !parentAfterFrame, nsnull)) {
     LAYOUT_PHASE_TEMP_REENTER();
     return NS_OK;
   }
   LAYOUT_PHASE_TEMP_REENTER();
 
   nsFrameItems frameItems;
   ConstructFramesFromItemList(state, items, parentFrame, frameItems);
 
@@ -6643,19 +6622,17 @@ nsCSSFrameConstructor::ContentInserted(n
   AddFrameConstructionItems(state, aChild, parentFrame, items);
 
   // Perform special check for diddling around with the frames in
   // a special inline frame.
   // If we're appending before :after content, then we're not really
   // appending, so let WipeContainingBlock know that.
   LAYOUT_PHASE_TEMP_EXIT();
   if (WipeContainingBlock(state, containingBlock, parentFrame, items,
-                          isAppend && !appendAfterFrame,
-                          prevSibling == nsnull,
-                          prevSibling)) {
+                          isAppend && !appendAfterFrame, prevSibling)) {
     LAYOUT_PHASE_TEMP_REENTER();
     return NS_OK;
   }
   LAYOUT_PHASE_TEMP_REENTER();
 
   // if the container is a table and a caption will be appended, it needs to be
   // put in the outer table frame's additional child list.
   nsFrameItems frameItems, captionItems;
@@ -6675,20 +6652,17 @@ nsCSSFrameConstructor::ContentInserted(n
   // If the parent of our current prevSibling is different from the frame we'll
   // actually use as the parent, then the calculated insertion point is now
   // invalid and as it is unknown where to insert correctly we append instead
   // (bug 341858).
   // This can affect our appendAfterFrame, but should not have any effect on
   // the WipeContainingBlock above, since this should only happen when neither
   // parent is a special frame (and in fact, only when one is an outer table
   // and one is an inner table or when the parent is a fieldset or fieldset
-  // content frame).  So it won't affect the {ib} or XUL box cases in
-  // WipeContainingBlock(), and the table pseudo handling will only be affected
-  // by us maybe thinking we're not inserting at the beginning, whereas we
-  // really are.  That would have made us reframe unnecessarily, but that's ok.
+  // content frame).
   // XXXbz we should push our frame construction item code up higher, so we
   // know what our items are by the time we start figuring out previous
   // siblings
   if (prevSibling && frameItems.childList &&
       frameItems.childList->GetParent() != prevSibling->GetParent()) {
 #ifdef DEBUG
     nsIFrame* frame1 = frameItems.childList->GetParent();
     nsIFrame* frame2 = prevSibling->GetParent();
@@ -7476,25 +7450,16 @@ nsCSSFrameConstructor::StyleChangeReflow
 
 nsresult
 nsCSSFrameConstructor::CharacterDataChanged(nsIContent* aContent,
                                             PRBool aAppend)
 {
   AUTO_LAYOUT_PHASE_ENTRY_POINT(mPresShell->GetPresContext(), FrameC);
   nsresult      rv = NS_OK;
 
-  if (aContent->HasFlag(FRAMETREE_DEPENDS_ON_CHARS)) {
-#ifdef DEBUG
-    nsIFrame* frame = mPresShell->GetPrimaryFrameFor(aContent);
-    NS_ASSERTION(!frame || !frame->IsGeneratedContentFrame(),
-                 "Bit should never be set on generated content");
-#endif
-    return RecreateFramesForContent(aContent);
-  }
-
   // Find the child frame
   nsIFrame* frame = mPresShell->GetPrimaryFrameFor(aContent);
 
   // Notify the first frame that maps the content. It will generate a reflow
   // command
 
   // It's possible the frame whose content changed isn't inserted into the
   // frame hierarchy yet, or that there is no frame that maps the content
@@ -8741,38 +8706,16 @@ nsCSSFrameConstructor::MaybeRecreateFram
     frameManager->ChangeUndisplayedContent(aContent, newContext);
     if (newContext->GetStyleDisplay()->mDisplay != NS_STYLE_DISPLAY_NONE) {
       result = RecreateFramesForContent(aContent);
     }
   }
   return result;
 }
 
-static nsIFrame*
-FindFirstNonWhitespaceChild(nsIFrame* aParentFrame)
-{
-  nsIFrame* f = aParentFrame->GetFirstChild(nsnull);
-  while (f && f->GetType() == nsGkAtoms::textFrame &&
-         f->GetContent()->TextIsOnlyWhitespace()) {
-    f = f->GetNextSibling();
-  }
-  return f;
-}
-
-static nsIFrame*
-FindNextNonWhitespaceSibling(nsIFrame* aFrame)
-{
-  nsIFrame* f = aFrame;
-  do {
-    f = f->GetNextSibling();
-  } while (f && f->GetType() == nsGkAtoms::textFrame &&
-           f->GetContent()->TextIsOnlyWhitespace());
-  return f;
-}
-
 PRBool
 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(),
@@ -8796,18 +8739,18 @@ nsCSSFrameConstructor::MaybeRecreateCont
 
   // 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 (FindFirstNonWhitespaceChild(parent) == inFlowFrame ||
-        !FindNextNonWhitespaceSibling(inFlowFrame->GetLastContinuation()) ||
+    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.
@@ -9109,114 +9052,117 @@ nsCSSFrameConstructor::CreateNeededTable
   ParentType ourParentType = GetParentType(aParentFrame);
   if (aItems.AllWantParentType(ourParentType)) {
     // Nothing to do here
     return NS_OK;
   }
 
   FCItemIterator iter(aItems);
   do {
-    if (iter.SkipItemsWantingParentType(ourParentType)) {
-      // Nothing else to do here; we're finished
-      return NS_OK;
-    }
+    NS_ASSERTION(!iter.IsDone(), "How did that happen?");
+
+    // Advance to the next item that wants a different parent type.
+    while (iter.item().DesiredParentType() == ourParentType) {
+      iter.Next();
+      if (iter.IsDone()) {
+        // Nothing else to do here; we're finished
+        return NS_OK;
+      }
+    }
+
+    NS_ASSERTION(!iter.IsDone() &&
+                 iter.item().DesiredParentType() != ourParentType,
+                 "Why did we stop?");
 
     // Now we're pointing to the first child that wants a different parent
-    // type.
+    // type.  Except for generated content, we should have already enforced the
+    // fact that no such items are whitespace (either in this method when
+    // constructing wrapping items, or when constructing the original
+    // FrameConstructionItemList).
+    NS_ASSERTION(aParentFrame->IsGeneratedContentFrame() ||
+                 !iter.item().mIsText ||
+                 !iter.item().mContent->TextIsOnlyWhitespace(),
+                 "Why do we have whitespace under a known-table parent?");
 
     // Now try to figure out what kids we can group together.  We can generally
     // group everything that has a different desired parent type from us.  Two
     // exceptions to this:
     // 1) If our parent type is table, we can't group columns with anything
     //    else other than whitespace.
-    // 2) Whitespace that lies between two things we can group which both want
-    //    a non-block parent should be dropped, even if we can't group them
-    //    with each other and even if the whitespace wants a parent of
-    //    ourParentType.  Ends of the list count as things that don't want a
-    //    block parent (so that for example we'll drop a whitespace-only list).
+    // 2) Whitespace that lies between two things we can group should
+    //    be dropped, even if we can't group them with each other.
+    // XXXbz it's not clear to me that rule 2 is a good one, it's not called
+    // for by the (admittedly vague) spec, and in fact it leads to some pretty
+    // crappy behavior if you have some inlines and whitespace as kids of a
+    // table-row, say, but it's more or less what we used to do.  More
+    // precisely, we shipped all whitespace out to the nearest block parent of
+    // the whole mess, sort of.  In any case this aspect of things, and in fact
+    // this whole function might need changes as the spec here gets
+    // clarified...  I happen to think we should not drop whitespace that comes
+    // between things that want a block parent.
 
     FCItemIterator endIter(iter); /* iterator to find the end of the group */
     ParentType groupingParentType = endIter.item().DesiredParentType();
-    if (aItems.AllWantParentType(groupingParentType) &&
-        groupingParentType != eTypeBlock) {
-      // Just group them all and be done with it.  We need the check for
-      // eTypeBlock here to catch the "all the items are whitespace" case
-      // described above.
-      endIter.SetToEnd();
-    } else {
-      // Locate the end of the group.
-
-      // Keep track of the type the previous item wanted, in case we have to
-      // deal with whitespace.  Start it off with ourParentType, since that's
-      // the last thing |iter| would have skipped over.
-      ParentType prevParentType = ourParentType;
-      do {
-        /* Walk an iterator past any whitespace that we might be able to drop from the list */
-        FCItemIterator spaceEndIter(endIter);
-        if (prevParentType != eTypeBlock &&
-            !aParentFrame->IsGeneratedContentFrame() &&
-            spaceEndIter.item().IsWhitespace()) {
-          PRBool trailingSpaces = spaceEndIter.SkipWhitespace();
-
-          // See whether we can drop the whitespace
-          if (trailingSpaces ||
-              spaceEndIter.item().DesiredParentType() != eTypeBlock) {
-            PRBool updateStart = (iter == endIter);
-            endIter.DeleteItemsTo(spaceEndIter);
-            NS_ASSERTION(trailingSpaces == endIter.IsDone(), "These should match");
-
-            if (updateStart) {
-              iter = endIter;
-            }
-
-            if (trailingSpaces) {
-              break; /* Found group end */
-            }
-
-            if (updateStart) {
-              // Update groupingParentType, since it might have been eTypeBlock
-              // just because of the whitespace.
-              groupingParentType = iter.item().DesiredParentType();
-            }
+    // If we decide to, we could optimize this by checking whether
+    // aItems.AllWantParentType(groupingParentType) and if so just setting
+    // endIter to the end of the list, which is an O(1) operation.  That
+    // requires not dropping whitespace between items that want a block parent,
+    // though, per the XXX comment above, since a whole bunch of spans and
+    // whitespace would test true to all wanting a block parent.
+    do {
+      endIter.Next();
+      if (endIter.IsDone()) {
+        break;
+      }
+
+      if (!aParentFrame->IsGeneratedContentFrame() &&
+          endIter.item().IsWhitespace()) {
+        // Whitespace coming after some groupable items
+        FCItemIterator textSkipIter(endIter);
+        do {
+          textSkipIter.Next();
+        } while (!textSkipIter.IsDone() && textSkipIter.item().IsWhitespace());
+
+        PRBool trailingSpace = textSkipIter.IsDone();
+        if (// Trailing whitespace we can't handle
+            (trailingSpace && ourParentType != eTypeBlock) ||
+            // Whitespace before kids needing wrapping
+            (!trailingSpace &&
+             textSkipIter.item().DesiredParentType() != ourParentType)) {
+          // Drop all the whitespace here so that |endIter| now points to the
+          // same thing as |textSkipIter|.  This doesn't affect where |iter|
+          // points, since that's guaranted to point to before endIter.
+          do {
+            endIter.DeleteItem();
+          } while (endIter != textSkipIter);
+
+          NS_ASSERTION(endIter.IsDone() == trailingSpace,
+                       "endIter == skipIter now!");
+          if (trailingSpace) {
+            break; // The loop advancing endIter
           }
         }
-
-        // Now endIter points to a non-whitespace item or a non-droppable
-        // whitespace item. In the latter case, if this is the end of the group
-        // we'll traverse this whitespace again.  But it'll all just be quick
-        // DesiredParentType() checks which will match ourParentType (that's
-        // what it means that this is the group end), so it's OK.
-        prevParentType = endIter.item().DesiredParentType();
-        if (prevParentType == ourParentType) {
-          // End the group at endIter.
-          break;
-        }
-
-        if (ourParentType == eTypeTable &&
-            (prevParentType == eTypeColGroup) !=
-            (groupingParentType == eTypeColGroup)) {
-          // Either we started with columns and now found something else, or vice
-          // versa.  In any case, end the grouping.
-          break;
-        }
-
-        // Include the whitespace we didn't drop (if any) in the group, since
-        // this is not the end of the group.  Note that this doesn't change
-        // prevParentType, since if we didn't drop the whitespace then we ended
-        // at something that wants a block parent.
-        endIter = spaceEndIter;
-
-        endIter.Next();
-      } while (!endIter.IsDone());
-    }
-
-    if (iter == endIter) {
-      // Nothing to wrap here; just skipped some whitespace
-      continue;
-    }
+      }
+
+      ParentType itemParentType = endIter.item().DesiredParentType();
+
+      if (itemParentType == ourParentType) {
+        break;
+      }
+
+      if (ourParentType == eTypeTable &&
+          (itemParentType == eTypeColGroup) !=
+          (groupingParentType == eTypeColGroup)) {
+        // Either we started with columns and now found something else, or vice
+        // versa.  In any case, end the grouping.
+        break;
+      }
+    } while (1);
+
+    NS_ASSERTION(iter != endIter, "How did that happen?");
 
     // Now group together all the items between iter and endIter.  The right
     // parent type to use depends on ourParentType.
     ParentType wrapperType;
     switch (ourParentType) {
       case eTypeBlock:
         wrapperType = eTypeTable;
         break;
@@ -10822,19 +10768,18 @@ nsCSSFrameConstructor::BuildInlineChildI
 
   aParentItem.mIsAllInline = aParentItem.mChildItems.AreAllItemsInline();
 }
 
 PRBool
 nsCSSFrameConstructor::WipeContainingBlock(nsFrameConstructorState& aState,
                                            nsIFrame* aContainingBlock,
                                            nsIFrame* aFrame,
-                                           FrameConstructionItemList& aItems,
+                                           const FrameConstructionItemList& aItems,
                                            PRBool aIsAppend,
-                                           PRBool aIsInsertAtStart,
                                            nsIFrame* aPrevSibling)
 {
   if (aItems.IsEmpty()) {
     return PR_FALSE;
   }
   
   // Before we go and append the frames, we must check for three
   // special situations.
@@ -10852,112 +10797,28 @@ nsCSSFrameConstructor::WipeContainingBlo
   ParentType parentType = GetParentType(aFrame);
   // If all the kids want a parent of the type that aFrame is, then we're all
   // set to go.  Indeed, there won't be any table pseudo-frames created between
   // aFrame and the kids, so those won't need to be merged with any table
   // pseudo-frames that might already be kids of aFrame.  If aFrame itself is a
   // table pseudo-frame, then all the kids in this list would have wanted a
   // frame of that type wrapping them anyway, so putting them inside it is ok.
   if (!aItems.AllWantParentType(parentType)) {
-    // Don't give up yet.  If parentType is not eTypeBlock and the parent is
-    // not a generated content frame, then try filtering whitespace out of the
-    // list.
-    if (parentType != eTypeBlock && !aFrame->IsGeneratedContentFrame()) {
-      // For leading whitespace followed by a kid that wants our parent type,
-      // there are three cases:
-      // 1) We have a previous sibling.  That means that previous sibling
-      //    wanted a (non-block) parent of the type we're looking at.  Then the
-      //    whitespace comes between two table-internal elements, so should be
-      //    collapsed out.
-      // 2) We have no previous sibling but aIsInsertAtStart is true.  That
-      //    means that we'll be at the beginning of our non-block-type parent,
-      //    and the whitespace is OK to collapse out.  If something is ever
-      //    inserted before us, it'll find our own parent as its parent and if
-      //    it's something that would care about the whitespace it'll want a
-      //    block parent, so it'll trigger a reframe at that point.
-      // 3) We have no previous sibling and aIsInsertAtStart is false.  In this
-      //    case it might be that we're actually in ContentAppended and have a
-      //    previous sibling that will want the whitespace.  We can't filter it
-      //    out in this case.
-      //
-      // XXXbz really, we should figure out the correct prevSibling in
-      // ContentAppended and pass it in here, I would think.  We end up having
-      // to sort it out anyway, eventually...  Then we could just check the
-      // prevSibling to decide on what to do with the whitespace.
-      //
-      // It's always OK to drop whitespace between any two items that want a
-      // parent of type parentType.
-      //
-      // For trailing whitespace, the situation is more complicated.  We might
-      // in fact have a next sibling that would care about the whitespace.  We
-      // just don't know anything about that here.  So leave trailing
-      // whitespace be, unless aIsAppend is true.  If it's true, we have no
-      // next sibling, and if one ever gets added that would care about the
-      // whitespace it'll get us as a previous sibling and trigger a reframe.
-
-      FCItemIterator iter(aItems);
-      FCItemIterator start(iter);
-      do {
-        if (iter.SkipItemsWantingParentType(parentType)) {
-          break;
-        }
-
-        // iter points to an item that wants a different parent.  If it's not
-        // whitespace, we're done; no more point scanning the list.
-        if (!iter.item().IsWhitespace()) {
-          break;
-        }
-
-        if (iter == start && !aPrevSibling && !aIsInsertAtStart) {
-          // Leading whitespace, not inserting at the start, and don't know
-          // whether our previous sibling might want this whitespace.  See the
-          // long comment above.  Need to reframe.
-          break;
-        }
-
-        FCItemIterator spaceEndIter(iter);
-        // Advance spaceEndIter past any whitespace
-        PRBool trailingSpaces = spaceEndIter.SkipWhitespace();
-
-        if ((!trailingSpaces &&
-             spaceEndIter.item().DesiredParentType() == parentType) ||
-            (trailingSpaces && aIsAppend)) {
-          // Drop the whitespace
-          iter.DeleteItemsTo(spaceEndIter);
-        } else {
-          // We're done: we don't want to drop the whitespace, and it has the
-          // wrong parent type.
-          break;
-        }
-
-        // Now loop, since |iter| points to item right after the whitespace we
-        // removed.
-      } while (!iter.IsDone());
-    }
-
     // We might be able to figure out some sort of optimizations here, but they
     // would have to depend on having a correct aPrevSibling and a correct next
     // sibling.  For example, we can probably avoid reframing if none of
     // aFrame, aPrevSibling, and next sibling are table pseudo-frames.  But it
     // doesn't seem worth it to worry about that for now, especially since we
     // in fact do not have a reliable aPrevSibling, nor any next sibling, in
     // this method.
 
-    // aItems might have changed, so recheck the parent type thing.  In fact,
-    // it might be empty, so recheck that too.
-    if (aItems.IsEmpty()) {
-      return PR_FALSE;
-    }
-
-    if (!aItems.AllWantParentType(parentType)) {
-      // Reframing aFrame->GetContent() is good enough, since the content of
-      // table pseudo-frames is the ancestor content.
-      RecreateFramesForContent(aFrame->GetContent());
-      return PR_TRUE;
-    }
+    // Reframing aFrame->GetContent() is good enough, since the content of
+    // table pseudo-frames is the ancestor content.
+    RecreateFramesForContent(aFrame->GetContent());
+    return PR_TRUE;
   }
 
   // Situation #3 is an inline frame that will now contain block
   // frames. This is a no-no and the frame construction logic knows
   // how to fix this.  See defition of IsInlineFrame() for what "an
   // inline" is.  Whether we have "a block" is tested for by
   // AreAllItemsInline.
 
@@ -11670,29 +11531,16 @@ nsCSSFrameConstructor::LazyGenerateChild
 
     // call XBL constructors after the frames are created
     mPresShell->GetDocument()->BindingManager()->ProcessAttachedQueue();
   }
 
   return NS_OK;
 }
 
-//////////////////////////////////////////////////////////
-// nsCSSFrameConstructor::FrameConstructionItem methods //
-//////////////////////////////////////////////////////////
-PRBool
-nsCSSFrameConstructor::FrameConstructionItem::IsWhitespace() const
-{
-  if (!mIsText) {
-    return PR_FALSE;
-  }
-  mContent->SetFlags(FRAMETREE_DEPENDS_ON_CHARS);
-  return mContent->TextIsOnlyWhitespace();
-}
-
 //////////////////////////////////////////////////////////////
 // nsCSSFrameConstructor::FrameConstructionItemList methods //
 //////////////////////////////////////////////////////////////
 void
 nsCSSFrameConstructor::FrameConstructionItemList::
 AdjustCountsForItem(FrameConstructionItem* aItem, PRInt32 aDelta)
 {
   NS_PRECONDITION(aDelta == 1 || aDelta == -1, "Unexpected delta");
@@ -11704,46 +11552,16 @@ AdjustCountsForItem(FrameConstructionIte
     mLineParticipantCount += aDelta;
   }
   mDesiredParentCounts[aItem->DesiredParentType()] += aDelta;
 }
 
 ////////////////////////////////////////////////////////////////////////
 // nsCSSFrameConstructor::FrameConstructionItemList::Iterator methods //
 ////////////////////////////////////////////////////////////////////////
-inline PRBool
-nsCSSFrameConstructor::FrameConstructionItemList::
-Iterator::SkipItemsWantingParentType(ParentType aParentType)
-{
-  NS_PRECONDITION(!IsDone(), "Shouldn't be done yet");
-  while (item().DesiredParentType() == aParentType) {
-    Next();
-    if (IsDone()) {
-      return PR_TRUE;
-    }
-  }
-  return PR_FALSE;
-}
-
-inline PRBool
-nsCSSFrameConstructor::FrameConstructionItemList::
-Iterator::SkipWhitespace()
-{
-  NS_PRECONDITION(!IsDone(), "Shouldn't be done yet");
-  NS_PRECONDITION(item().IsWhitespace(), "Not pointing to whitespace?");
-  do {
-    Next();
-    if (IsDone()) {
-      return PR_TRUE;
-    }
-  } while (item().IsWhitespace());
-
-  return PR_FALSE;
-}
-
 void
 nsCSSFrameConstructor::FrameConstructionItemList::
 Iterator::AppendItemToList(FrameConstructionItemList& aTargetList)
 {
   NS_ASSERTION(&aTargetList != &mList, "Unexpected call");
   NS_PRECONDITION(!IsDone(), "should not be done");
 
   FrameConstructionItem* item = ToItem(mCurrent);
@@ -11796,23 +11614,16 @@ Iterator::InsertItem(FrameConstructionIt
   // Just insert the item before us.  There's no magic here.
   PR_INSERT_BEFORE(aItem, mCurrent);
   mList.AdjustCountsForItem(aItem, 1);
 
   NS_POSTCONDITION(PR_NEXT_LINK(aItem) == mCurrent, "How did that happen?");
 }
 
 void
-nsCSSFrameConstructor::FrameConstructionItemList::
-Iterator::DeleteItemsTo(const Iterator& aEnd)
-{
-  NS_PRECONDITION(mEnd == aEnd.mEnd, "end iterator for some other list?");
-  NS_PRECONDITION(*this != aEnd, "Shouldn't be at aEnd yet");
-
-  do {
-    NS_ASSERTION(!IsDone(), "Ran off end of list?");
-    FrameConstructionItem* item = ToItem(mCurrent);
-    Next();
-    PR_REMOVE_LINK(item);
-    mList.AdjustCountsForItem(item, -1);
-    delete item;
-  } while (*this != aEnd);
-}
+nsCSSFrameConstructor::FrameConstructionItemList::Iterator::DeleteItem()
+{
+  FrameConstructionItem* item = ToItem(mCurrent);
+  Next();
+  PR_REMOVE_LINK(item);
+  mList.AdjustCountsForItem(item, -1);
+  delete item;
+}
--- a/layout/base/nsCSSFrameConstructor.h
+++ b/layout/base/nsCSSFrameConstructor.h
@@ -742,46 +742,30 @@ private:
 
       PRBool operator==(const Iterator& aOther) const {
         NS_ASSERTION(mEnd == aOther.mEnd, "Iterators for different lists?");
         return mCurrent == aOther.mCurrent;
       }
       PRBool operator!=(const Iterator& aOther) const {
         return !(*this == aOther);
       }
-      Iterator& operator=(const Iterator& aOther) {
-        NS_ASSERTION(mEnd == aOther.mEnd, "Iterators for different lists?");
-        mCurrent = aOther.mCurrent;
-        return *this;
-      }
 
       operator FrameConstructionItem& () {
         return item();
       }
 
       FrameConstructionItem& item() {
         return *FrameConstructionItemList::ToItem(mCurrent);
       }
       PRBool IsDone() const { return mCurrent == mEnd; }
       PRBool AtStart() const { return mCurrent == PR_NEXT_LINK(mEnd); }
       void Next() {
         NS_ASSERTION(!IsDone(), "Should have checked IsDone()!");
         mCurrent = PR_NEXT_LINK(mCurrent);
       }
-      void SetToEnd() { mCurrent = mEnd; }
-
-      // Skip over all items that want a parent type different from the given
-      // one.  Return whether the iterator is done after doing that.  The
-      // iterator must not be done when this is called.
-      inline PRBool SkipItemsWantingParentType(ParentType aParentType);
-
-      // Skip over whitespace.  Return whether the iterator is done after doing
-      // that.  The iterator must not be done, and must be pointing to a
-      // whitespace item when this is called.
-      inline PRBool SkipWhitespace();
 
       // Remove the item pointed to by this iterator from its current list and
       // Append it to aTargetList.  This iterator is advanced to point to the
       // next item in its list.  aIter must not be done.  aOther must not be
       // the list this iterator is iterating over..
       void AppendItemToList(FrameConstructionItemList& aTargetList);
 
       // As above, but moves all items starting with this iterator until we
@@ -795,22 +779,19 @@ private:
 
       // Insert aItem in this iterator's list right before the item pointed to
       // by this iterator.  After the insertion, this iterator will continue to
       // point to the item it now points to (the one just after the
       // newly-inserted item).  This iterator is allowed to be done; in that
       // case this call just appends the given item to the list.
       void InsertItem(FrameConstructionItem* aItem);
 
-      // Delete the items between this iterator and aEnd, including the item
-      // this iterator currently points to but not including the item pointed
-      // to by aEnd.  When this returns, this iterator will point to the same
-      // item as aEnd.  This iterator must not equal aEnd when this method is
-      // called.
-      void DeleteItemsTo(const Iterator& aEnd);
+      // Delete the item pointed to by this iterator, and point ourselves to
+      // the next item in the list.
+      void DeleteItem();
 
     private:
       PRCList* mCurrent;
       PRCList* mEnd;
       FrameConstructionItemList& mList;
     };
 
   private:
@@ -854,21 +835,19 @@ private:
         mContent->UnbindFromTree();
         NS_RELEASE(mContent);
       }
     }
 
     ParentType DesiredParentType() {
       return FCDATA_DESIRED_PARENT_TYPE(mFCData->mBits);
     }
-
-    // Don't call this unless the frametree really depends on the answer!
-    // Especially so for generated content, where we don't want to reframe
-    // things.
-    PRBool IsWhitespace() const;
+    PRBool IsWhitespace() const {
+      return mIsText && mContent->TextIsOnlyWhitespace();
+    }
 
     // The FrameConstructionData to use.
     const FrameConstructionData* mFCData;
     // The nsIContent node to use when initializing the new frame.
     nsIContent* mContent;
     // The XBL-resolved tag name to use for frame construction.
     nsIAtom* mTag;
     // The XBL-resolved namespace to use for frame construction.
@@ -1363,27 +1342,24 @@ private:
                                        nsFrameItems& aFrameItems);
 
   // Determine whether we need to wipe out what we just did and start over
   // because we're doing something like adding block kids to an inline frame
   // (and therefore need an {ib} split).  If aIsAppend is true, aPrevSibling is
   // ignored.  Otherwise it may be used to determine whether to reframe when
   // inserting into the block of an {ib} split.  Passing a null aPrevSibling in
   // the non-append case is ok in terms of correctness.  It might reframe when
-  // we don't really need to, but that's it.  Passing in a correct
-  // aIsInsertAtStart is desirable for performance reasons, but if it's hard to
-  // determine passing false is safe in terms of correctness.
+  // we don't really need to, but that's it.
   // @return PR_TRUE if we reconstructed the containing block, PR_FALSE
   // otherwise
   PRBool WipeContainingBlock(nsFrameConstructorState& aState,
                              nsIFrame*                aContainingBlock,
                              nsIFrame*                aFrame,
-                             FrameConstructionItemList& aItems,
+                             const FrameConstructionItemList& aItems,
                              PRBool                   aIsAppend,
-                             PRBool                   aIsInsertAtStart,
                              nsIFrame*                aPrevSibling);
 
   nsresult ReframeContainingBlock(nsIFrame* aFrame);
 
   nsresult StyleChangeReflow(nsIFrame* aFrame);
 
   /** Helper function that searches the immediate child frames 
     * (and their children if the frames are "special")
--- a/layout/generic/nsTextFrameThebes.cpp
+++ b/layout/generic/nsTextFrameThebes.cpp
@@ -3417,18 +3417,16 @@ nsTextFrame::Init(nsIContent*      aCont
   // We're not a continuing frame.
   // mContentOffset = 0; not necessary since we get zeroed out at init
   return nsFrame::Init(aContent, aParent, aPrevInFlow);
 }
 
 void
 nsTextFrame::Destroy()
 {
-  // We might want to clear FRAMETREE_DEPENDS_ON_CHARS on mContent here, since
-  // our parent frame type might be changing.  Not clear whether it's worth it.
   ClearTextRun();
   if (mNextContinuation) {
     mNextContinuation->SetPrevInFlow(nsnull);
   }
   // Let the base class destroy the frame
   nsFrame::Destroy();
 }
 
--- a/layout/mathml/nsMathMLmtableFrame.h
+++ b/layout/mathml/nsMathMLmtableFrame.h
@@ -79,17 +79,18 @@ public:
 
   NS_IMETHOD
   AttributeChanged(PRInt32  aNameSpaceID,
                    nsIAtom* aAttribute,
                    PRInt32  aModType);
 
   virtual PRBool IsFrameOfType(PRUint32 aFlags) const
   {
-    return nsTableOuterFrame::IsFrameOfType(aFlags & ~(nsIFrame::eMathML));
+    return nsTableOuterFrame::IsFrameOfType(aFlags &
+      ~(nsIFrame::eMathML | nsIFrame::eExcludesIgnorableWhitespace));
   }
 
 protected:
   nsMathMLmtableOuterFrame(nsStyleContext* aContext) : nsTableOuterFrame(aContext) {}
   virtual ~nsMathMLmtableOuterFrame();
 
   // helper to find the row frame at a given index, positive or negative, e.g.,
   // 1..n means the first row down to the last row, -1..-n means the last row
@@ -137,17 +138,18 @@ public:
   {
     nsresult rv = nsTableFrame::RemoveFrame(aListName, aOldFrame);
     RestyleTable();
     return rv;
   }
 
   virtual PRBool IsFrameOfType(PRUint32 aFlags) const
   {
-    return nsTableFrame::IsFrameOfType(aFlags & ~(nsIFrame::eMathML));
+    return nsTableFrame::IsFrameOfType(aFlags &
+      ~(nsIFrame::eMathML | nsIFrame::eExcludesIgnorableWhitespace));
   }
 
   // helper to restyle and reflow the table when a row is changed -- since MathML
   // attributes are inter-dependent and row/colspan can affect the table, it is
   // safer (albeit grossly suboptimal) to just relayout the whole thing.
   void RestyleTable();
 
 protected:
@@ -194,17 +196,18 @@ public:
   {
     nsresult rv = nsTableRowFrame::RemoveFrame(aListName, aOldFrame);
     RestyleTable();
     return rv;
   }
 
   virtual PRBool IsFrameOfType(PRUint32 aFlags) const
   {
-    return nsTableRowFrame::IsFrameOfType(aFlags & ~(nsIFrame::eMathML));
+    return nsTableRowFrame::IsFrameOfType(aFlags &
+      ~(nsIFrame::eMathML | nsIFrame::eExcludesIgnorableWhitespace));
   }
 
   // helper to restyle and reflow the table -- @see nsMathMLmtableFrame.
   void RestyleTable()
   {
     nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
     if (tableFrame && tableFrame->IsFrameOfType(nsIFrame::eMathML)) {
       // relayout the table
@@ -230,17 +233,18 @@ public:
   AttributeChanged(PRInt32  aNameSpaceID,
                    nsIAtom* aAttribute,
                    PRInt32  aModType);
 
   virtual PRInt32 GetRowSpan();
   virtual PRInt32 GetColSpan();
   virtual PRBool IsFrameOfType(PRUint32 aFlags) const
   {
-    return nsTableCellFrame::IsFrameOfType(aFlags & ~(nsIFrame::eMathML));
+    return nsTableCellFrame::IsFrameOfType(aFlags &
+      ~(nsIFrame::eMathML | nsIFrame::eExcludesIgnorableWhitespace));
   }
 
 protected:
   nsMathMLmtdFrame(nsStyleContext* aContext) : nsTableCellFrame(aContext) {}
   virtual ~nsMathMLmtdFrame();
 }; // class nsMathMLmtdFrame
 
 // --------------
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/3-blocks-ref.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <body style="font-family: monospace">
-    <div>
-      Row 1, Col 1Row 1, Col 2Row 1, Col 3
-    </div>
-    <div>
-      Row 22, Col 1Row 22, Col 2Row 22, Col 3
-    </div>
-    <div>
-      Row 333, Col 1Row 333, Col 2Row 333, Col 3
-    </div>    
-  </body>
-</html>
--- a/layout/reftests/table-anonymous-boxes/3-tables-ref.html
+++ b/layout/reftests/table-anonymous-boxes/3-tables-ref.html
@@ -1,26 +1,26 @@
 <!DOCTYPE html>
 <html>
   <body style="font-family: monospace">
-    <table cellpadding="0" cellspacing="0" style="margin: 0; padding: 0; border: none">
+    <table cellpadding="0" cellspacing="0">
       <tr>
         <td>Row 1, Col 1</td>
         <td>Row 1, Col 2</td>
         <td>Row 1, Col 3</td>
       </tr>
     </table>
-    <table cellpadding="0" cellspacing="0" style="margin: 0; padding: 0; border: none">
+    <table cellpadding="0" cellspacing="0">
       <tr>
         <td>Row 22, Col 1</td>
         <td>Row 22, Col 2</td>
         <td>Row 22, Col 3</td>
       </tr>
     </table>
-    <table cellpadding="0" cellspacing="0" style="margin: 0; padding: 0; border: none">
+    <table cellpadding="0" cellspacing="0">
       <tr>
         <td>Row 333, Col 1</td>
         <td>Row 333, Col 2</td>
         <td>Row 333, Col 3</td>
       </tr>
     </table>
   </body>
 </html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/372641-1-ref.xhtml
+++ /dev/null
@@ -1,10 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-</head>
-
-<body>
-
-<table border="1"><tbody><tr><td>TD</td></tr></tbody></table>
-
-</body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/372641-1a.xhtml
+++ /dev/null
@@ -1,15 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-</head>
-
-<body>
-
-<table border="1" id="table">XXX<tbody><tr><td>TD</td></tr></tbody></table>
-
-<script>
-document.body.offsetWidth;
-document.getElementById("table").firstChild.data = '';
-</script>
-
-</body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/372641-1b.xhtml
+++ /dev/null
@@ -1,15 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-</head>
-
-<body>
-
-<table border="1"><tbody id="tbody">XXX<tr><td>TD</td></tr></tbody></table>
-
-<script>
-document.body.offsetWidth;
-document.getElementById("tbody").firstChild.data = '';
-</script>
-
-</body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/372641-1c.xhtml
+++ /dev/null
@@ -1,15 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-</head>
-
-<body>
-
-<table border="1"><tbody><tr id="tr">XXX<td>TD</td></tr></tbody></table>
-
-<script>
-document.body.offsetWidth;
-document.getElementById("tr").firstChild.data = '';
-</script>
-
-</body>
-</html>
--- a/layout/reftests/table-anonymous-boxes/3x3-cols-ref.html
+++ b/layout/reftests/table-anonymous-boxes/3x3-cols-ref.html
@@ -1,12 +1,12 @@
 <!DOCTYPE html>
 <html>
   <body style="font-family: monospace">
-    <table cellpadding="0" cellspacing="0" style="margin: 0; padding: 0; border: none">
+    <table cellpadding="0" cellspacing="0">
       <colgroup><col style="background: yellow"><col style="background: cyan"><col style="background: lime"></colgroup>
       <tr>
         <td>Row 1, Col 1</td>
         <td>Row 1, Col 2</td>
         <td>Row 1, Col 3</td>
       </tr>
       <tr>
         <td>Row 22, Col 1</td>
--- a/layout/reftests/table-anonymous-boxes/3x3-ref.html
+++ b/layout/reftests/table-anonymous-boxes/3x3-ref.html
@@ -1,12 +1,12 @@
 <!DOCTYPE html>
 <html>
   <body style="font-family: monospace">
-    <table cellpadding="0" cellspacing="0" style="margin: 0; padding: 0; border: none">
+    <table cellpadding="0" cellspacing="0">
       <tr>
         <td>Row 1, Col 1</td>
         <td>Row 1, Col 2</td>
         <td>Row 1, Col 3</td>
       </tr>
       <tr>
         <td>Row 22, Col 1</td>
         <td>Row 22, Col 2</td>
--- a/layout/reftests/table-anonymous-boxes/dynamic-removal-14.html
+++ b/layout/reftests/table-anonymous-boxes/dynamic-removal-14.html
@@ -1,16 +1,14 @@
 <!DOCTYPE html>
 <html class="reftest-wait">
   <head>
     <script>
       function doTest() {
-        try {
-          document.normalize();
-        } catch(e) {}
+        document.normalize();
         var n = document.getElementById("t").nextSibling;
         n.parentNode.removeChild(n);
         document.documentElement.className = "";
       }
     </script>
   </head>
   <body style="font-family: monospace" onload="doTest()">
     <span style="display: table-row">
--- a/layout/reftests/table-anonymous-boxes/infer-cells-1.html
+++ b/layout/reftests/table-anonymous-boxes/infer-cells-1.html
@@ -1,18 +1,17 @@
 <!DOCTYPE html>
 <html>
   <body style="font-family: monospace">
     <!-- The test in the first row might not be correct, depending on spec
          clarifications -->
     <span style="display: table-row"> 
-      <span>Row 1,</span>
-      <span>Col 1Row 1,</span>
-      <span>Col 2Row 1,</span>
-      <span>Col 3</span>
+      <span>Row 1, Col 1</span>
+      <span>Row 1, Col 2</span>
+      <span>Row 1, Col 3</span>
     </span>
     <span style="display: table-row"> 
       <span style="display: block">Row 22, Col 1Row 22, Col 2Row 22, Col 3</span>
     </span>
     <span style="display: table-row">
       <span>Row 333, Col 1</span><span>Row 333, Col 2</span><span>Row 333, Col 3</span>
     </span>
   </body>
--- a/layout/reftests/table-anonymous-boxes/reftest.list
+++ b/layout/reftests/table-anonymous-boxes/reftest.list
@@ -1,34 +1,31 @@
 == 121142-1a.html 121142-1-ref.html
 == 121142-1b.html 121142-1-ref.html
 == 121142-2.html 121142-2-ref.html
 fails == 156888-1.html 156888-1-ref.html # bug 484825
 == 156888-2.html 156888-2-ref.html
 == 162063-1.xhtml about:blank
-== 203923-1.html white-space-ref.html
-== 203923-2.html white-space-ref.html
+== 203923-1.html white-space-1-ref.html
+== 203923-2.html white-space-1-ref.html
 == 208305-1.html 208305-1-ref.html
-== 208305-2.html white-space-ref.html
-== 208305-3.html white-space-ref.html
-== 208305-4.html white-space-ref.html
+== 208305-2.html white-space-1-ref.html
+== 208305-3.html white-space-1-ref.html
+== 208305-4.html white-space-1-ref.html
 == 277995-1.html 277995-1-ref.html
 == 293576-1.html 293576-1-ref.html
 == 302113-1.html 302113-1-ref.html
 == 315146-1.xhtml 315146-1-ref.xhtml
 == 325543-1a.html 325543-1-ref.html
 == 325543-1b.html 325543-1-ref.html
 == 338735-1.html 338735-1-ref.html
 == 339388-1a.html 339388-1-ref.html
 == 339388-1b.html 339388-1-ref.html
 == 368932-1.html 368932-1-ref.html
 == 371054-1.html 371054-1-ref.html
-== 372641-1a.xhtml 372641-1-ref.xhtml
-== 372641-1b.xhtml 372641-1-ref.xhtml
-== 372641-1c.xhtml 372641-1-ref.xhtml
 == 372649-1.html 372649-1-ref.html
 == 373379-1.html 373379-1-ref.html
 == 394402-1a.html 394402-1-ref.html
 == 394402-1b.html 394402-1-ref.html
 == 407115-1.html 407115-1-ref.html
 == 448111-1.html 448111-1-ref.html
 == infer-first-row.html 3x3-ref.html
 == infer-first-row-and-table.html 3x3-ref.html
@@ -36,17 +33,16 @@ fails == 156888-1.html 156888-1-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
 == infer-table-row-cell.html 3x3-ref.html # Or should it be?  Spec is unclear.
 == infer-table.html 3x3-ref.html
 != 3-tables-ref.html 3x3-ref.html
-== 3-tables-ref.html 3-blocks-ref.html
 == blocks-divide-tables-1.html 3-tables-ref.html
 == 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
@@ -54,52 +50,26 @@ fails == 156888-1.html 156888-1-ref.html
 == dynamic-removal-1.html 3x3-ref.html
 == dynamic-removal-2.html 3x3-ref.html
 == 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-ref.html
-== dynamic-removal-10.html white-space-ref.html
-== dynamic-removal-11.html white-space-ref.html
-== dynamic-removal-12.html white-space-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
 == dynamic-removal-14.html 3x3-ref.html
 == dynamic-insert-cell-1.html 3x3-ref.html
 == dynamic-switch-block-to-cell-1.html 3x3-ref.html
 == dynamic-switch-block-to-cell-2.html 3x3-ref.html
 == dynamic-switch-block-to-cell-3.html 3x3-ref.html
 == dynamic-switch-block-to-cell-4.html 3x3-ref.html
 == dynamic-switch-block-to-cell-5.html 3x3-ref.html
 == dynamic-switch-inline-to-cell-1.html 3x3-ref.html
 == dynamic-switch-inline-to-cell-2.html 3x3-ref.html
 == dynamic-switch-inline-to-cell-3.html 3x3-ref.html
 == dynamic-switch-inline-to-cell-4.html 3x3-ref.html
 == dynamic-switch-inline-to-cell-5.html 3x3-ref.html
-== white-space-1.html 3-tables-ref.html
-== white-space-2.html 3x3-ref.html
-== white-space-3.html 3x3-ref.html
-== white-space-4.html 3x3-ref.html
-== white-space-5.html 3x3-ref.html
-== white-space-6.html 3x3-ref.html
-== white-space-7.html white-space-ref.html
-== white-space-8.html white-space-ref.html
-== white-space-9.html white-space-ref.html
-== white-space-10.html white-space-ref.html
-== white-space-11.html white-space-ref.html
-== white-space-12.html white-space-ref.html
-== white-space-13.html white-space-ref.html
-== white-space-14.html white-space-ref.html
-== white-space-15.html white-space-ref.html
-== white-space-16.html white-space-ref.html
-== white-space-17.html white-space-ref.html
-== white-space-18.html white-space-ref.html
-== white-space-19.html white-space-ref.html
-== white-space-20.html white-space-ref.html
-== white-space-21.html white-space-ref.html
-== white-space-22.html white-space-ref.html
-== white-space-23.html white-space-ref.html
-== white-space-24.html white-space-ref.html
-== white-space-25.html white-space-ref.html
-== white-space-26.html white-space-ref.html
-== white-space-pre-1.html white-space-pre-ref.html
+== white-space-1.html white-space-1-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/white-space-1-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE HTML>
+<html>
+  <body>
+    a bc d
+  </body>
+</html>
--- a/layout/reftests/table-anonymous-boxes/white-space-1.html
+++ b/layout/reftests/table-anonymous-boxes/white-space-1.html
@@ -1,20 +1,11 @@
-<!DOCTYPE html>
-<html class="reftest-wait">
-  <head>
-    <script>
-      function doTest() {
-        var n = document.getElementById("t").nextSibling;
-        n.data = "Row 22, Col 1Row 22, Col 2Row 22, Col 3";
-        document.documentElement.className = "";
-      }
-    </script>
-  </head>
-  <body style="font-family: monospace" onload="doTest()">
-    <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" id="t">Row 1, Col 3</span>
-    <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>
+<!DOCTYPE HTML>
+<html>
+  <body>
+    <span>
+      <span>a</span>
+      <span style="display: table-cell">b</span>
+      <span style="display: table-cell">c</span>
+      <span>d</span>
+    </span>
   </body>
 </html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-10.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!DOCTYPE HTML>
-<html class="reftest-wait">
-  <head>
-    <script>
-      function doTest() {
-        var t = document.getElementById("t1");
-        t.parentNode.removeChild(t);
-        t = document.getElementById("t2");
-        t.parentNode.removeChild(t);
-        document.documentElement.className = "";
-      }
-    </script>
-  </head>
-  <body onload="doTest()">
-    <span>
-      <span>a</span><span style="display: table-cell" id="t1">e</span>
-      <span style="display: table-cell" id="t2">f</span><span>bc d</span>
-    </span>
-  </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-11.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!DOCTYPE HTML>
-<html class="reftest-wait">
-  <head>
-    <script>
-      function doTest() {
-        var t = document.getElementById("t1");
-        t.parentNode.removeChild(t);
-        t = document.getElementById("t2");
-        t.parentNode.removeChild(t);
-        document.documentElement.className = "";
-      }
-    </script>
-  </head>
-  <body onload="doTest()">
-    <span>
-      <span>a</span><span style="display: table-cell" id="t2">e</span>
-      <span style="display: table-cell" id="t1">f</span><span>bc d</span>
-    </span>
-  </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-12.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <body>
-    <span>
-      a
-      <span style="display: table-cell">b</span><span style="display: table-cell">c</span>
-      d
-    </span>
-  </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-13.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <body>
-    <span>
-      a
-      <span style="display: table-cell">b</span>
-      <span style="display: table-cell">c</span>
-      d
-    </span>
-  </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-14.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <head>
-    <style>
-      #t:after { content: "d" }
-    </style>
-  </head>  
-  <body>
-    <span id="t">
-      a
-      <span style="display: table-cell">b</span><span style="display: table-cell">c</span>
-    </span>
-  </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-15.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <head>
-    <style>
-      #t:after { content: "d" }
-    </style>
-  </head>  
-  <body>
-    <span id="t">
-      a
-      <span style="display: table-cell">b</span>
-      <span style="display: table-cell">c</span>
-    </span>
-  </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-16.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <head>
-    <style>
-      #t:after { content: "d" }
-    </style>
-  </head>  
-  <body>
-    <span id="t">
-      a
-      <span style="display: table-cell">b</span><script>document.body.offsetWidth</script><span style="display: table-cell">c</span>
-    </span>
-  </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-17.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <head>
-    <style>
-      #t:after { content: "d" }
-    </style>
-  </head>  
-  <body>
-    <span id="t">
-      a
-      <span style="display: table-cell">b</span>
-      <script>document.body.offsetWidth</script>
-      <span style="display: table-cell">c</span>
-    </span>
-  </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-18.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <head>
-    <style>
-      #t:before { content: "a" }
-    </style>
-  </head>  
-  <body>
-    <span id="t">
-      <span style="display: table-cell">b</span><span style="display: table-cell">c</span>
-      d
-    </span>
-  </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-19.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <head>
-    <style>
-      #t:before { content: "a" }
-    </style>
-  </head>  
-  <body>
-    <span id="t">
-      <span style="display: table-cell">b</span>
-      <span style="display: table-cell">c</span>
-      d
-    </span>
-  </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-2.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!DOCTYPE html>
-<html class="reftest-wait">
-  <head>
-    <script>
-      function doTest() {
-        try {
-          document.normalize();
-        } catch (e) {}
-        var n = document.getElementById("t").nextSibling;
-        n.data = " ";
-        document.documentElement.className = "";
-      }
-    </script>
-  </head>
-  <body style="font-family: monospace" onload="doTest()">
-    <span style="display: table-row">
-      <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" id="t">
-      <span style="display: table-cell">Row 22, Col 1</span>
-      <span style="display: table-cell">Row 22, Col 2</span>
-      <span style="display: table-cell">Row 22, Col 3</span>
-    </span>This is a test<span style="display: table-row">
-      <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>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-20.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <head>
-    <style>
-      #t:before { content: "a" }
-    </style>
-  </head>  
-  <body>
-    <span id="t">
-      <span style="display: table-cell">b</span><script>document.body.offsetWidth</script><span style="display: table-cell">c</span>
-      d
-    </span>
-  </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-21.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <head>
-    <style>
-      #t:before { content: "a" }
-    </style>
-  </head>  
-  <body>
-    <span id="t">
-      <span style="display: table-cell">b</span>
-      <script>document.body.offsetWidth</script>
-      <span style="display: table-cell">c</span>
-      d
-    </span>
-  </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-22.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <body>
-    <span style="display:table-row; white-space: pre"><span style="display: table-cell">a</span> bc <span style="display: table-cell">d</span></span>
-  </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-23.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <body>
-    <span style="display:table-row; white-space: pre"><span style="display: table-cell">a</span> <span>bc</span> <span style="display: table-cell">d</span></span>
-  </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-24.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <body>
-    <span style="display:table-row; white-space: pre"><span style="display: table-cell">a</span> <script>document.body.offsetWidth</script>bc<script>document.body.offsetWidth</script> <span style="display: table-cell">d</span></span>
-  </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-25.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html class="reftest-wait">
-  <head>
-    <script>
-      function doTest() {
-        var t = document.getElementById("t");
-        var parent = t.parentNode;
-        parent.insertBefore(document.createTextNode(" "), t);
-        parent.insertBefore(document.createTextNode("bc"), t);
-        parent.insertBefore(document.createTextNode(" "), t);
-        document.documentElement.className = "";
-      }
-    </script>
-  </head>
-  <body onload="doTest()">
-    <span style="display:table-row; white-space: pre"><span style="display: table-cell">a</span><span id="t" style="display: table-cell">d</span></span>
-  </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-26.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <head>
-    <style>
-      #t:after { display: table-cell; content: "d"; }
-    </style>
-  </head>
-  <body>
-    <span id="t">
-      a<script>document.body.offsetWidth;</script> <span style="display: table-cell; white-space: pre">bc </span></span>
-  </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-3.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<!DOCTYPE html>
-<html class="reftest-wait">
-  <head>
-    <script>
-      function doTest() {
-        try {
-          document.normalize();
-        } catch (e) {}
-        var n = document.getElementById("t").nextSibling;
-        n.data = " ";
-        document.documentElement.className = "";
-      }
-    </script>
-  </head>
-  <body style="font-family: monospace" onload="doTest()">
-    <span style="display: table-row-group">
-      <span style="display: table-row">
-        <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">
-        <span style="display: table-cell" id="t">Row 22, Col 1</span>This is a test<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">
-        <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>
-    </span>
-  </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-4.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!DOCTYPE html>
-<html class="reftest-wait">
-  <head>
-    <script>
-      function doTest() {
-        var n = document.getElementById("t").nextSibling;
-        n.data = "Row 22, Col 1";
-        document.documentElement.className = "";
-      }
-    </script>
-  </head>
-  <body style="font-family: monospace" onload="doTest()">
-    <span style="display: table-row-group">
-      <span style="display: table-row" id="t">
-        <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-cell">Row 22, Col 2</span>
-      <span style="display: table-cell">Row 22, Col 3</span>
-      <span style="display: table-row">
-        <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>
-    </span>
-  </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-5.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!DOCTYPE html>
-<html class="reftest-wait">
-  <head>
-    <script>
-      function doTest() {
-        var n = document.getElementById("t").nextSibling;
-        n.data = "Row 22, Col 2";
-        document.documentElement.className = "";
-      }
-    </script>
-  </head>
-  <body style="font-family: monospace" onload="doTest()">
-    <span style="display: table-row-group">
-      <span style="display: table-row">
-        <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-cell" id="t">Row 22, Col 1</span>
-      <span style="display: table-cell">Row 22, Col 3</span>
-      <span style="display: table-row">
-        <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>
-    </span>
-  </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-6.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!DOCTYPE html>
-<html class="reftest-wait">
-  <head>
-    <script>
-      function doTest() {
-        var n = document.getElementById("t").nextSibling;
-        n.data = "Row 22, Col 3";
-        document.documentElement.className = "";
-      }
-    </script>
-  </head>
-  <body style="font-family: monospace" onload="doTest()">
-    <span style="display: table-row-group">
-      <span style="display: table-row">
-        <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-cell">Row 22, Col 1</span>
-      <span style="display: table-cell" id="t">Row 22, Col 2</span>
-      <span style="display: table-row">
-        <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>
-    </span>
-  </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-7.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-  <body>
-    <span>
-      <span>a</span>
-      <span style="display: table-cell">b</span>
-      <span style="display: table-cell">c</span>
-      <span>d</span>
-    </span>
-  </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-8.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!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 style="display: table-cell" id="t">e</span>
-      <span style="display: table-cell">b</span><span>c d</span>
-    </span>
-  </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-9.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!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 b</span><span style="display: table-cell">c</span>
-      <span style="display: table-cell" id="t">e</span><span>d</span>
-    </span>
-  </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-pre-1.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <head>
-    <style>
-      #x:after { content: " cd"; display: table-cell; }
-    </style>
-    <script>
-      function doTest() {
-        var f = document.getElementById("f");
-        f.parentNode.removeChild(f);
-      }
-    </script>
-  </head>
-  <body onload="doTest()">
-    <div style="font-family: monospace; width: 10em; white-space: pre-wrap"><span id="f" style="float: left; width: 80%; height: 0.5em"></span><span id="x">a <script>document.body.offsetWidth; dump('aa');</script> <span style="display: table-cell">b</span></span></div>
-  </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-pre-ref.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <body>
-    <div style="font-family: monospace; white-space: pre-wrap">a  b cd</div>
-  </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/table-anonymous-boxes/white-space-ref.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-  <body>
-    a bc d
-  </body>
-</html>
--- a/layout/tables/nsTableColFrame.h
+++ b/layout/tables/nsTableColFrame.h
@@ -85,16 +85,22 @@ public:
 
   /**
    * Table columns never paint anything, nor receive events.
    */
   NS_IMETHOD BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                               const nsRect&           aDirtyRect,
                               const nsDisplayListSet& aLists) { return NS_OK; }
 
+  virtual PRBool IsFrameOfType(PRUint32 aFlags) const
+  {
+    return nsSplittableFrame::IsFrameOfType(aFlags &
+      ~(nsIFrame::eExcludesIgnorableWhitespace));
+  }
+
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::tableColFrame
    */
   virtual nsIAtom* GetType() const;
   
 #ifdef DEBUG
--- a/layout/tables/nsTableColGroupFrame.h
+++ b/layout/tables/nsTableColGroupFrame.h
@@ -142,16 +142,22 @@ public:
                     nsHTMLReflowMetrics&     aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
                     nsReflowStatus&          aStatus);
 
   /* needed only because we use Reflow in a hacky way, see
      nsTableFrame::ReflowColGroups */
   virtual PRBool IsContainingBlock() const;
 
+  virtual PRBool IsFrameOfType(PRUint32 aFlags) const
+  {
+    return nsHTMLContainerFrame::IsFrameOfType(aFlags &
+      ~nsIFrame::eExcludesIgnorableWhitespace);
+  }
+
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::tableColGroupFrame
    */
   virtual nsIAtom* GetType() const;
 
   /** Add column frames to the table storages: colframe cache and cellmap
--- a/layout/tables/nsTableFrame.h
+++ b/layout/tables/nsTableFrame.h
@@ -369,16 +369,22 @@ public:
                        nsReflowStatus&          aStatus);
 
   nsFrameList& GetColGroups();
 
   NS_IMETHOD GetParentStyleContextFrame(nsPresContext* aPresContext,
                                         nsIFrame**      aProviderFrame,
                                         PRBool*         aIsChild);
 
+  virtual PRBool IsFrameOfType(PRUint32 aFlags) const
+  {
+    return nsHTMLContainerFrame::IsFrameOfType(aFlags &
+      ~nsIFrame::eExcludesIgnorableWhitespace);
+  }
+
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::tableFrame
    */
   virtual nsIAtom* GetType() const;
 
 #ifdef DEBUG
--- a/layout/tables/nsTableOuterFrame.h
+++ b/layout/tables/nsTableOuterFrame.h
@@ -95,16 +95,22 @@ public:
     * @return           the frame that was created
     */
   friend nsIFrame* NS_NewTableOuterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
   
   // nsIFrame overrides - see there for a description
 
   virtual void Destroy();
   
+  virtual PRBool IsFrameOfType(PRUint32 aFlags) const
+  {
+    return nsHTMLContainerFrame::IsFrameOfType(aFlags &
+      ~nsIFrame::eExcludesIgnorableWhitespace);
+  }
+
   virtual PRBool IsContainingBlock() const;
 
   NS_IMETHOD SetInitialChildList(nsIAtom*        aListName,
                                  nsIFrame*       aChildList);
  
   virtual nsIFrame* GetFirstChild(nsIAtom* aListName) const;
 
   virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const;
--- a/layout/tables/nsTableRowFrame.h
+++ b/layout/tables/nsTableRowFrame.h
@@ -119,16 +119,22 @@ public:
     */
   NS_IMETHOD Reflow(nsPresContext*          aPresContext,
                     nsHTMLReflowMetrics&     aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
                     nsReflowStatus&          aStatus);
 
   void DidResize();
 
+  virtual PRBool IsFrameOfType(PRUint32 aFlags) const
+  {
+    return nsHTMLContainerFrame::IsFrameOfType(aFlags &
+      ~nsIFrame::eExcludesIgnorableWhitespace);
+  }
+
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::tableRowFrame
    */
   virtual nsIAtom* GetType() const;
 
 #ifdef DEBUG
--- a/layout/tables/nsTableRowGroupFrame.h
+++ b/layout/tables/nsTableRowGroupFrame.h
@@ -137,16 +137,22 @@ public:
     *
     * @see nsIFrame::Reflow
     */
   NS_IMETHOD Reflow(nsPresContext*           aPresContext,
                     nsHTMLReflowMetrics&     aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
                     nsReflowStatus&          aStatus);
 
+  virtual PRBool IsFrameOfType(PRUint32 aFlags) const
+  {
+    return nsHTMLContainerFrame::IsFrameOfType(aFlags &
+      ~nsIFrame::eExcludesIgnorableWhitespace);
+  }
+
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::tableRowGroupFrame
    */
   virtual nsIAtom* GetType() const;
 
   virtual PRBool IsContainingBlock() const;