Merge mozilla-central into mozilla-inbound
authorEhsan Akhgari <ehsan@mozilla.com>
Thu, 29 Sep 2011 17:26:09 -0400
changeset 77883 ce204f8626bcf47e07f9efb47b476f3460bee786
parent 77882 fa844d57e842993c8d3fb94837bcdcc89d254cc8 (current diff)
parent 77849 af3668a8901595106cc3e3ff90cd202484d9babc (diff)
child 77884 3bb95f690d75fb95d5404c14e7327a4fa039de8c
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
milestone10.0a1
Merge mozilla-central into mozilla-inbound
content/base/src/nsObjectLoadingContent.cpp
content/events/public/nsEventStates.h
dom/plugins/base/nsPluginHost.cpp
embedding/android/GeckoApp.java
layout/style/nsCSSPseudoClassList.h
mobile/app/mobile.js
mobile/chrome/content/browser.js
mobile/chrome/content/content.js
toolkit/locales/en-US/chrome/mozapps/plugins/plugins.dtd
toolkit/mozapps/plugins/content/pluginProblem.xml
toolkit/mozapps/plugins/content/pluginProblemBinding.css
toolkit/mozapps/plugins/content/pluginProblemContent.css
toolkit/themes/pinstripe/mozapps/plugins/pluginProblem.css
toolkit/themes/winstripe/mozapps/plugins/pluginProblem.css
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -1738,17 +1738,16 @@ GK_ATOM(menuBarFrame,"MenuBarFrame")
 GK_ATOM(menuFrame,"MenuFrame")
 GK_ATOM(menuPopupFrame,"MenuPopupFrame")
 GK_ATOM(objectFrame, "ObjectFrame")
 GK_ATOM(pageFrame, "PageFrame")
 GK_ATOM(pageBreakFrame, "PageBreakFrame")
 GK_ATOM(pageContentFrame, "PageContentFrame")
 GK_ATOM(placeholderFrame, "PlaceholderFrame")
 GK_ATOM(popupSetFrame, "PopupSetFrame")
-GK_ATOM(positionedInlineFrame, "PositionedInlineFrame")
 GK_ATOM(canvasFrame, "CanvasFrame")
 GK_ATOM(rootFrame, "RootFrame")
 GK_ATOM(scrollFrame, "ScrollFrame")
 GK_ATOM(scrollbarFrame, "ScrollbarFrame")
 GK_ATOM(sequenceFrame, "SequenceFrame")
 GK_ATOM(sliderFrame, "sliderFrame")
 GK_ATOM(tableCaptionFrame, "TableCaptionFrame")
 GK_ATOM(tableCellFrame, "TableCellFrame")
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -100,16 +100,20 @@
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo* gObjectLog = PR_NewLogModule("objlc");
 #endif
 
 #define LOG(args) PR_LOG(gObjectLog, PR_LOG_DEBUG, args)
 #define LOG_ENABLED() PR_LOG_TEST(gObjectLog, PR_LOG_DEBUG)
 
+#ifdef ANDROID
+#include "nsXULAppAPI.h"
+#endif
+
 class nsAsyncInstantiateEvent : public nsRunnable {
 public:
   // This stores both the content and the frame so that Instantiate calls can be
   // avoided if the frame changed in the meantime.
   nsObjectLoadingContent *mContent;
   nsWeakFrame             mFrame;
   nsCString               mContentType;
   nsCOMPtr<nsIURI>        mURI;
@@ -1044,16 +1048,22 @@ nsObjectLoadingContent::AsyncOnChannelRe
   cb->OnRedirectVerifyCallback(NS_OK);
   return NS_OK;
 }
 
 // <public>
 nsEventStates
 nsObjectLoadingContent::ObjectState() const
 {
+#ifdef ANDROID
+  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+    return NS_EVENT_STATE_TYPE_CLICK_TO_PLAY;
+  }
+#endif
+
   switch (mType) {
     case eType_Loading:
       return NS_EVENT_STATE_LOADING;
     case eType_Image:
       return ImageState();
     case eType_Plugin:
     case eType_Document:
       // These are OK. If documents start to load successfully, they display
--- a/content/events/public/nsEventStates.h
+++ b/content/events/public/nsEventStates.h
@@ -259,16 +259,18 @@ private:
 #define NS_EVENT_STATE_MOZ_SUBMITINVALID NS_DEFINE_EVENT_STATE_MACRO(31)
 // UI friendly version of :invalid pseudo-class.
 #define NS_EVENT_STATE_MOZ_UI_INVALID NS_DEFINE_EVENT_STATE_MACRO(32)
 // UI friendly version of :valid pseudo-class.
 #define NS_EVENT_STATE_MOZ_UI_VALID NS_DEFINE_EVENT_STATE_MACRO(33)
 // Content is the full screen element, or a frame containing the
 // current full-screen element.
 #define NS_EVENT_STATE_FULL_SCREEN   NS_DEFINE_EVENT_STATE_MACRO(34)
+// Handler for click to play plugin
+#define NS_EVENT_STATE_TYPE_CLICK_TO_PLAY NS_DEFINE_EVENT_STATE_MACRO(35)
 
 /**
  * NOTE: do not go over 63 without updating nsEventStates::InternalType!
  */
 
 #define ESM_MANAGED_STATES (NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS |     \
                             NS_EVENT_STATE_HOVER | NS_EVENT_STATE_DRAGOVER |   \
                             NS_EVENT_STATE_URLTARGET | NS_EVENT_STATE_FOCUSRING | \
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -89,16 +89,17 @@
 #include "nsIWritablePropertyBag2.h"
 #include "nsPluginStreamListenerPeer.h"
 
 #include "nsEnumeratorUtils.h"
 #include "nsXPCOM.h"
 #include "nsXPCOMCID.h"
 #include "nsISupportsPrimitives.h"
 
+#include "nsXULAppAPI.h"
 #include "nsIXULRuntime.h"
 
 // for the dialog
 #include "nsIStringBundle.h"
 #include "nsIWindowWatcher.h"
 #include "nsPIDOMWindow.h"
 
 #include "nsIScriptGlobalObject.h"
@@ -2246,16 +2247,21 @@ nsresult nsPluginHost::ScanPluginsDirect
       if (!aCreatePluginList && *aPluginsChanged)
         break;
     }
     return NS_OK;
 }
 
 nsresult nsPluginHost::LoadPlugins()
 {
+#ifdef ANDROID
+  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+    return NS_OK;
+  }
+#endif
   // do not do anything if it is already done
   // use ReloadPlugins() to enforce loading
   if (mPluginsLoaded)
     return NS_OK;
 
   if (mPluginsDisabled)
     return NS_OK;
 
--- a/embedding/android/GeckoApp.java
+++ b/embedding/android/GeckoApp.java
@@ -146,40 +146,36 @@ abstract public class GeckoApp
 
     private static final String PLUGIN_SYSTEM_LIB = "/system/lib/plugins/";
 
     private static final String PLUGIN_TYPE = "type";
     private static final String TYPE_NATIVE = "native";
     public ArrayList<PackageInfo> mPackageInfoCache = new ArrayList<PackageInfo>();
 
     String[] getPluginDirectories() {
-
         ArrayList<String> directories = new ArrayList<String>();
         PackageManager pm = this.mAppContext.getPackageManager();
         List<ResolveInfo> plugins = pm.queryIntentServices(new Intent(PLUGIN_ACTION),
                 PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
 
         synchronized(mPackageInfoCache) {
-
             // clear the list of existing packageInfo objects
             mPackageInfoCache.clear();
 
-
             for (ResolveInfo info : plugins) {
 
                 // retrieve the plugin's service information
                 ServiceInfo serviceInfo = info.serviceInfo;
                 if (serviceInfo == null) {
                     Log.w(LOGTAG, "Ignore bad plugin");
                     continue;
                 }
 
                 Log.w(LOGTAG, "Loading plugin: " + serviceInfo.packageName);
 
-
                 // retrieve information from the plugin's manifest
                 PackageInfo pkgInfo;
                 try {
                     pkgInfo = pm.getPackageInfo(serviceInfo.packageName,
                                     PackageManager.GET_PERMISSIONS
                                     | PackageManager.GET_SIGNATURES);
                 } catch (Exception e) {
                     Log.w(LOGTAG, "Can't find plugin: " + serviceInfo.packageName);
--- a/layout/base/crashtests/crashtests.list
+++ b/layout/base/crashtests/crashtests.list
@@ -27,17 +27,17 @@ load 191272-1.html
 load 199696-1.html
 load 217903-1.html
 load 223064-1.html
 load 234851-1.html
 load 234851-2.html
 load 241300-1.html
 load 243159-1.html
 load 243159-2.xhtml
-asserts(1) load 243519-1.html # bug 536692
+load 243519-1.html
 load 244490-1.html
 load 254367-1.html
 load 263359-1.html
 load 265027-1.html
 load 265736-1.html
 load 265736-2.html
 asserts(2) load 265899-1.html # bug 575011
 load 265973-1.html
@@ -102,17 +102,17 @@ load 344057-1.xhtml
 load 344064-1.html
 load 344300-1.html
 load 344300-2.html
 load 344340-1.xul
 asserts-if(browserIsRemote,1) load 347898-1.html # bug 622188
 load 348126-1.html
 load 348688-1.html
 load 348708-1.xhtml
-asserts(2) load 348729-1.html # bug 548836
+asserts(4) load 348729-1.html # bug 548836
 load 349095-1.xhtml
 load 350128-1.xhtml
 load 350267-1.html
 load 354133-1.html
 load 354766-1.xhtml
 load 354771-1.xul
 load 355989-1.xhtml
 load 355993-1.xhtml
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -1018,16 +1018,20 @@ nsFrameConstructorState::PushAbsoluteCon
   mAbsoluteItems = 
     nsAbsoluteItems(AdjustAbsoluteContainingBlock(aNewAbsoluteContainingBlock));
 
   /* See if we're wiring the fixed-pos and abs-pos lists together.  This happens iff
    * we're a transformed element.
    */
   mFixedPosIsAbsPos = (aNewAbsoluteContainingBlock &&
                        aNewAbsoluteContainingBlock->GetStyleDisplay()->HasTransform());
+
+  if (aNewAbsoluteContainingBlock) {
+    aNewAbsoluteContainingBlock->MarkAsAbsoluteContainingBlock();
+  }
 }
 
 void
 nsFrameConstructorState::PushFloatContainingBlock(nsIFrame* aNewFloatContainingBlock,
                                                   nsFrameConstructorSaveState& aSaveState)
 {
   NS_PRECONDITION(!aNewFloatContainingBlock ||
                   aNewFloatContainingBlock->IsFloatContainingBlock(),
@@ -1213,17 +1217,24 @@ nsFrameConstructorState::ProcessFrameIns
   
   // Insert the frames hanging out in aItems.  We can use SetInitialChildList()
   // if the containing block hasn't been reflowed yet (so NS_FRAME_FIRST_REFLOW
   // is set) and doesn't have any frames in the aChildListID child list yet.
   const nsFrameList& childList = containingBlock->GetChildList(aChildListID);
   nsresult rv = NS_OK;
   if (childList.IsEmpty() &&
       (containingBlock->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
-    rv = containingBlock->SetInitialChildList(aChildListID, aFrameItems);
+    // If we're injecting absolutely positioned frames, inject them on the
+    // absolute containing block
+    if (aChildListID == containingBlock->GetAbsoluteListID()) {
+      rv = containingBlock->GetAbsoluteContainingBlock()->
+           SetInitialChildList(containingBlock, aChildListID, aFrameItems);
+    } else {
+      rv = containingBlock->SetInitialChildList(aChildListID, aFrameItems);
+    }
   } else {
     // Note that whether the frame construction context is doing an append or
     // not is not helpful here, since it could be appending to some frame in
     // the middle of the document, which means we're not necessarily
     // appending to the children of the containing block.
     //
     // We need to make sure the 'append to the end of document' case is fast.
     // So first test the last child of the containing block
@@ -1231,33 +1242,33 @@ nsFrameConstructorState::ProcessFrameIns
 
     // CompareTreePosition uses placeholder hierarchy for out of flow frames,
     // so this will make out-of-flows respect the ordering of placeholders,
     // which is great because it takes care of anonymous content.
     nsIFrame* firstNewFrame = aFrameItems.FirstChild();  
     if (!lastChild ||
         nsLayoutUtils::CompareTreePosition(lastChild, firstNewFrame, containingBlock) < 0) {
       // no lastChild, or lastChild comes before the new children, so just append
-      rv = containingBlock->AppendFrames(aChildListID, aFrameItems);
+      rv = mFrameManager->AppendFrames(containingBlock, aChildListID, aFrameItems);
     } else {
       // try the other children
       nsIFrame* insertionPoint = nsnull;
       for (nsIFrame* f = childList.FirstChild(); f != lastChild;
            f = f->GetNextSibling()) {
         PRInt32 compare =
           nsLayoutUtils::CompareTreePosition(f, firstNewFrame, containingBlock);
         if (compare > 0) {
           // f comes after the new children, so stop here and insert after
           // the previous frame
           break;
         }
         insertionPoint = f;
       }
-      rv = containingBlock->InsertFrames(aChildListID, insertionPoint,
-                                         aFrameItems);
+      rv = mFrameManager->InsertFrames(containingBlock, aChildListID,
+                                       insertionPoint, aFrameItems);
     }
   }
 
   NS_POSTCONDITION(aFrameItems.IsEmpty(), "How did that happen?");
 
   // XXXbz And if NS_FAILED(rv), what?  I guess we need to clean up the list
   // and deal with all the placeholders... but what if the placeholders aren't
   // in the document yet?  Could that happen?
@@ -1733,30 +1744,16 @@ nsCSSFrameConstructor::CreateGeneratedCo
     
 /****************************************************
  **  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
 
-static bool
-IsTableRelated(nsIAtom* aParentType)
-{
-  return
-    nsGkAtoms::tableOuterFrame    == aParentType ||
-    nsGkAtoms::tableFrame         == 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 bool
@@ -1928,16 +1925,25 @@ nsCSSFrameConstructor::ConstructTable(ns
 
   if (!mRootElementFrame) {
     // The frame we're constructing will be the root element frame.
     // Set mRootElementFrame before processing children.
     mRootElementFrame = newFrame;
   }
 
   nsFrameItems childItems;
+
+  // Process children
+  nsFrameConstructorSaveState absoluteSaveState;
+  const nsStyleDisplay* display = outerStyleContext->GetStyleDisplay();
+
+  // Mark the table frame as an absolute container if needed
+  if (display->IsPositioned()) {
+    aState.PushAbsoluteContainingBlock(newFrame, absoluteSaveState);
+  }
   if (aItem.mFCData->mBits & FCDATA_USE_CHILD_ITEMS) {
     rv = ConstructFramesFromItemList(aState, aItem.mChildItems,
                                      innerFrame, childItems);
   } else {
     rv = ProcessChildren(aState, content, styleContext, innerFrame,
                          PR_TRUE, childItems, PR_FALSE, aItem.mPendingBinding);
   }
   // XXXbz what about cleaning up?
@@ -2545,16 +2551,18 @@ nsCSSFrameConstructor::ConstructRootFram
 
   nsContainerFrame::SyncFrameViewProperties(mPresShell->GetPresContext(), viewportFrame,
                                             viewportPseudoStyle, rootView);
   nsContainerFrame::SyncWindowProperties(mPresShell->GetPresContext(), viewportFrame,
                                          rootView);
 
   // The viewport is the containing block for 'fixed' elements
   mFixedContainingBlock = viewportFrame;
+  // Make it an absolute container for fixed-pos elements
+  mFixedContainingBlock->MarkAsAbsoluteContainingBlock();
 
   *aNewFrame = viewportFrame;
   return NS_OK;
 }
 
 nsresult
 nsCSSFrameConstructor::SetUpDocElementContainingBlock(nsIContent* aDocElement)
 {
@@ -2829,16 +2837,18 @@ nsCSSFrameConstructor::ConstructPageFram
   nsIFrame* prevPageContentFrame = nsnull;
   if (aPrevPageFrame) {
     prevPageContentFrame = aPrevPageFrame->GetFirstPrincipalChild();
     NS_ASSERTION(prevPageContentFrame, "missing page content frame");
   }
   pageContentFrame->Init(nsnull, aPageFrame, prevPageContentFrame);
   SetInitialSingleChild(aPageFrame, pageContentFrame);
   mFixedContainingBlock = pageContentFrame;
+  // Make it an absolute container for fixed-pos elements
+  mFixedContainingBlock->MarkAsAbsoluteContainingBlock();
 
   nsRefPtr<nsStyleContext> canvasPseudoStyle;
   canvasPseudoStyle = styleSet->ResolveAnonymousBoxStyle(nsCSSAnonBoxes::canvas,
                                                          pageContentPseudoStyle);
 
   aCanvasFrame = NS_NewCanvasFrame(aPresShell, canvasPseudoStyle);
   if (NS_UNLIKELY(!aCanvasFrame))
     return NS_ERROR_OUT_OF_MEMORY;
@@ -2978,19 +2988,17 @@ nsCSSFrameConstructor::ConstructButtonFr
 #endif
   
   if (!isLeaf) { 
     // Process children
     nsFrameConstructorSaveState absoluteSaveState;
     nsFrameItems                childItems;
 
     if (aStyleDisplay->IsPositioned()) {
-      // The area frame becomes a container for child frames that are
-      // absolutely positioned
-      aState.PushAbsoluteContainingBlock(blockFrame, absoluteSaveState);
+      aState.PushAbsoluteContainingBlock(buttonFrame, absoluteSaveState);
     }
 
 #ifdef DEBUG
     // Make sure that anonymous child creation will have no effect in this case
     nsIAnonymousContentCreator* creator = do_QueryFrame(blockFrame);
     NS_ASSERTION(!creator, "Shouldn't be an anonymous content creator!");
 #endif
 
@@ -3203,25 +3211,18 @@ nsCSSFrameConstructor::InitializeSelectF
                    geometricParent, scrollFrame);
 
   if (aState.mFrameState && aState.mFrameManager) {
     // Restore frame state for the scroll frame
     aState.mFrameManager->RestoreFrameStateFor(scrollFrame, aState.mFrameState);
   }
 
   // Process children
-  nsFrameConstructorSaveState absoluteSaveState;
   nsFrameItems                childItems;
 
-  if (display->IsPositioned()) {
-    // The area frame becomes a container for child frames that are
-    // absolutely positioned
-    aState.PushAbsoluteContainingBlock(scrolledFrame, absoluteSaveState);
-  }
-
   ProcessChildren(aState, aContent, aStyleContext, scrolledFrame, PR_FALSE,
                   childItems, PR_FALSE, aPendingBinding);
 
   // Set the scrolled frame's initial child lists
   scrolledFrame->SetInitialChildList(kPrincipalList, childItems);
   return NS_OK;
 }
 
@@ -3262,21 +3263,17 @@ nsCSSFrameConstructor::ConstructFieldSet
     return rv;
   }
   
   // Process children
   nsFrameConstructorSaveState absoluteSaveState;
   nsFrameItems                childItems;
 
   if (aStyleDisplay->IsPositioned()) {
-    // The area frame becomes a container for child frames that are
-    // absolutely positioned
-    // XXXbz this is probably wrong, and once arbitrary frames can be absolute
-    // containing blocks we should fix this..
-    aState.PushAbsoluteContainingBlock(blockFrame, absoluteSaveState);
+    aState.PushAbsoluteContainingBlock(newFrame, absoluteSaveState);
   }
 
   ProcessChildren(aState, content, styleContext, blockFrame, PR_TRUE,
                   childItems, PR_TRUE, aItem.mPendingBinding);
 
   nsFrameItems fieldsetKids;
   fieldsetKids.AddChild(blockFrame);
 
@@ -5495,65 +5492,61 @@ nsCSSFrameConstructor::GetFrameFor(nsICo
 
   return insertionFrame;
 }
 
 nsIFrame*
 nsCSSFrameConstructor::GetAbsoluteContainingBlock(nsIFrame* aFrame)
 {
   NS_PRECONDITION(nsnull != mRootElementFrame, "no root element frame");
-  
+
   // Starting with aFrame, look for a frame that is absolutely positioned or
   // relatively positioned
-  nsIFrame* containingBlock = nsnull;
-  for (nsIFrame* frame = aFrame; frame && !containingBlock;
-       frame = frame->GetParent()) {
+  for (nsIFrame* frame = aFrame; frame; frame = frame->GetParent()) {
     if (frame->IsFrameOfType(nsIFrame::eMathML)) {
       // If it's mathml, bail out -- no absolute positioning out from inside
       // mathml frames.  Note that we don't make this part of the loop
       // condition because of the stuff at the end of this method...
       return nsnull;
     }
-    
-    // Is it positioned?
-    // If it's table-related then ignore it, because for the time
-    // being table-related frames are not containers for absolutely
-    // positioned child frames.
+
+    // If the frame is positioned, we will probably return it as the containing
+    // block (see the exceptions below).  Otherwise, we'll start looking at the
+    // parent frame, unless we're dealing with a scrollframe.
+    // Scrollframes are special since they're not positioned, but their
+    // scrolledframe might be.  So, we need to check this special case to return
+    // the correct containing block (the scrolledframe) in that case.
     const nsStyleDisplay* disp = frame->GetStyleDisplay();
-
-    if (disp->IsPositioned() && !IsTableRelated(frame->GetType())) {
-      // Find the outermost wrapped block under this frame
-      for (nsIFrame* wrappedFrame = aFrame; wrappedFrame != frame->GetParent();
-           wrappedFrame = wrappedFrame->GetParent()) {
-        nsIAtom* frameType = wrappedFrame->GetType();
-        if (nsGkAtoms::blockFrame == frameType ||
-#ifdef MOZ_XUL
-            nsGkAtoms::XULLabelFrame == frameType ||
-#endif
-            nsGkAtoms::positionedInlineFrame == frameType) {
-          containingBlock = wrappedFrame;
-        } else if (nsGkAtoms::fieldSetFrame == frameType) {
-          // If the positioned frame is a fieldset, use the area frame inside it.
-          // We don't use GetContentInsertionFrame for fieldsets yet.
-          containingBlock = GetFieldSetBlockFrame(wrappedFrame);
-        }
-      }
-
-      // We sometimes have a null containing block here because we
-      // haven't yet fixed bug 455338.  Once we fix that we shouldn't
-      // have to loop here.
-    }
-  }
-
-  // If we found an absolutely positioned containing block, then use the
-  // first-continuation.
-  if (containingBlock)
-    return AdjustAbsoluteContainingBlock(containingBlock);
-
-  // If we didn't find it, then use the document element containing block
+    if (!disp->IsPositioned()) {
+      continue;
+    }
+    nsIFrame* absPosCBCandidate = nsnull;
+    if (frame->GetType() == nsGkAtoms::scrollFrame) {
+      nsIScrollableFrame* scrollFrame = do_QueryFrame(frame);
+      absPosCBCandidate = scrollFrame->GetScrolledFrame();
+    } else {
+      // Only first continuations can be containing blocks.
+      absPosCBCandidate = frame->GetFirstContinuation();
+    }
+    // Is the frame really an absolute container?
+    if (!absPosCBCandidate || !absPosCBCandidate->IsAbsoluteContainer()) {
+      continue;
+    }
+
+    // For tables, return the outer table frame.
+    if (absPosCBCandidate->GetType() == nsGkAtoms::tableFrame) {
+      return absPosCBCandidate->GetParent();
+    }
+    // For outer table frames, we can just return absPosCBCandidate.
+    return absPosCBCandidate;
+  }
+
+  // It is possible for the search for the containing block to fail, because
+  // no absolute container can be found in the parent chain.  In those cases,
+  // we fall back to the document element's containing block.
   return mHasRootAbsPosContainingBlock ? mDocElementContainingBlock : nsnull;
 }
 
 nsIFrame*
 nsCSSFrameConstructor::GetFloatContainingBlock(nsIFrame* aFrame)
 {
   // Starting with aFrame, look for a frame that is a float containing block.
   // IF we hit a mathml frame, bail out; we don't allow floating out of mathml
@@ -8482,23 +8475,16 @@ nsCSSFrameConstructor::CreateContinuingF
     }
 #endif  
   } else if (nsGkAtoms::columnSetFrame == frameType) {
     newFrame = NS_NewColumnSetFrame(shell, styleContext, 0);
 
     if (newFrame) {
       newFrame->Init(content, aParentFrame, aFrame);
     }
-  
-  } else if (nsGkAtoms::positionedInlineFrame == frameType) {
-    newFrame = NS_NewPositionedInlineFrame(shell, styleContext);
-
-    if (newFrame) {
-      newFrame->Init(content, aParentFrame, aFrame);
-    }
 
   } else if (nsGkAtoms::pageFrame == frameType) {
     nsIFrame* canvasFrame;
     rv = ConstructPageFrame(shell, aPresContext, aParentFrame, aFrame,
                             newFrame, canvasFrame);
   } else if (nsGkAtoms::tableOuterFrame == frameType) {
     rv = CreateContinuingOuterTableFrame(shell, aPresContext, aFrame, aParentFrame,
                                          content, styleContext, &newFrame);
@@ -10639,17 +10625,17 @@ nsCSSFrameConstructor::ConstructBlock(ns
   // positioning must be computed with respect to the CSS dimensions
   // of the element, which are the dimensions of the outer block. But
   // we can't really do that because only blocks can have absolute
   // children. So use the block and try to compensate with hacks
   // in nsBlockFrame::CalculateContainingBlockSizeForAbsolutes.
   nsFrameConstructorSaveState absoluteSaveState;
   if (aAbsPosContainer) {
     //    NS_ASSERTION(aRelPos, "should have made area frame for this");
-    aState.PushAbsoluteContainingBlock(blockFrame, absoluteSaveState);
+    aState.PushAbsoluteContainingBlock(*aNewFrame, absoluteSaveState);
   }
 
   // Process the child content
   nsFrameItems childItems;
   rv = ProcessChildren(aState, aContent, aStyleContext, blockFrame, PR_TRUE,
                        childItems, PR_TRUE, aPendingBinding);
 
   // Set the frame's initial child list
@@ -10726,30 +10712,26 @@ nsCSSFrameConstructor::ConstructInline(n
   nsStyleContext* const styleContext = aItem.mStyleContext;
 
   nsIFrame *newFrame;
 
   bool positioned =
     NS_STYLE_DISPLAY_INLINE == aDisplay->mDisplay &&
     (NS_STYLE_POSITION_RELATIVE == aDisplay->mPosition ||
      aDisplay->HasTransform());
-  if (positioned) {
-    newFrame = NS_NewPositionedInlineFrame(mPresShell, styleContext);
-  } else {
-    newFrame = NS_NewInlineFrame(mPresShell, styleContext);
-  }
+  newFrame = NS_NewInlineFrame(mPresShell, styleContext);
 
   // Initialize the frame
   InitAndRestoreFrame(aState, content, aParentFrame, nsnull, newFrame);
 
   nsFrameConstructorSaveState absoluteSaveState;  // definition cannot be inside next block
                                                   // because the object's destructor is significant
                                                   // this is part of the fix for bug 42372
 
-  if (positioned) {                            
+  if (positioned) {
     // Relatively positioned frames becomes a container for child
     // frames that are positioned
     aState.PushAbsoluteContainingBlock(newFrame, absoluteSaveState);
   }
 
   // Process the child content
   nsFrameItems childItems;
   nsresult rv = ConstructFramesFromItemList(aState, aItem.mChildItems, newFrame,
@@ -10843,27 +10825,25 @@ nsCSSFrameConstructor::CreateIBSiblings(
 
     MoveChildrenTo(aState.mPresContext, aInitialInline, blockFrame, blockKids);
 
     SetFrameIsSpecial(lastNewInline, blockFrame);
     aSiblings.AddChild(blockFrame);
 
     // Now grab the initial inlines in aChildItems and put them into an inline
     // frame
-    nsIFrame* inlineFrame;
-    if (aIsPositioned) {
-      inlineFrame = NS_NewPositionedInlineFrame(mPresShell, styleContext);
-    }
-    else {
-      inlineFrame = NS_NewInlineFrame(mPresShell, styleContext);
-    }
+    nsIFrame* inlineFrame = NS_NewInlineFrame(mPresShell, styleContext);
 
     InitAndRestoreFrame(aState, content, parentFrame, nsnull, inlineFrame,
                         PR_FALSE);
 
+    if (aIsPositioned) {
+      inlineFrame->MarkAsAbsoluteContainingBlock();
+    }
+
     if (aChildItems.NotEmpty()) {
       nsFrameList::FrameLinkEnumerator firstBlock(aChildItems);
       FindFirstBlock(firstBlock);
       nsFrameList inlineKids = aChildItems.ExtractHead(firstBlock);
 
       MoveChildrenTo(aState.mPresContext, aInitialInline, inlineFrame,
                      inlineKids);
     }
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -2544,18 +2544,17 @@ PrepareBackgroundLayer(nsPresContext* aP
   }
 
   // Compute background origin area relative to aBorderArea now as we may need
   // it to compute the effective image size for a CSS gradient.
   nsRect bgPositioningArea(0, 0, 0, 0);
 
   nsIAtom* frameType = aForFrame->GetType();
   nsIFrame* geometryFrame = aForFrame;
-  if (frameType == nsGkAtoms::inlineFrame ||
-      frameType == nsGkAtoms::positionedInlineFrame) {
+  if (frameType == nsGkAtoms::inlineFrame) {
     // XXXjwalden Strictly speaking this is not quite faithful to how
     // background-break is supposed to interact with background-origin values,
     // but it's a non-trivial amount of work to make it fully conformant, and
     // until the specification is more finalized (and assuming background-break
     // even makes the cut) it doesn't make sense to hammer out exact behavior.
     switch (aBackground.mBackgroundInlinePolicy) {
     case NS_STYLE_BG_INLINE_POLICY_EACH_BOX:
       bgPositioningArea = nsRect(nsPoint(0,0), aBorderArea.Size());
--- a/layout/base/nsFrameManager.cpp
+++ b/layout/base/nsFrameManager.cpp
@@ -87,16 +87,17 @@
 #include "nsReadableUtils.h"
 #include "nsUnicharUtils.h"
 #include "nsLayoutErrors.h"
 #include "nsLayoutUtils.h"
 #include "nsAutoPtr.h"
 #include "imgIRequest.h"
 #include "nsTransitionManager.h"
 #include "RestyleTracker.h"
+#include "nsAbsoluteContainingBlock.h"
 
 #include "nsFrameManager.h"
 #include "nsRuleProcessorData.h"
 
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
 
@@ -465,29 +466,48 @@ nsFrameManager::ClearAllUndisplayedConte
       if (child->GetParent() != aParentContent) {
         ClearUndisplayedContentIn(child, child->GetParent());
       }
     }
   }
 }
 
 //----------------------------------------------------------------------
+nsresult
+nsFrameManager::AppendFrames(nsIFrame*       aParentFrame,
+                             ChildListID     aListID,
+                             nsFrameList&    aFrameList)
+{
+  if (aParentFrame->IsAbsoluteContainer() &&
+      aListID == aParentFrame->GetAbsoluteListID()) {
+    return aParentFrame->GetAbsoluteContainingBlock()->
+           AppendFrames(aParentFrame, aListID, aFrameList);
+  } else {
+    return aParentFrame->AppendFrames(aListID, aFrameList);
+  }
+}
 
 nsresult
 nsFrameManager::InsertFrames(nsIFrame*       aParentFrame,
                              ChildListID     aListID,
                              nsIFrame*       aPrevFrame,
                              nsFrameList&    aFrameList)
 {
   NS_PRECONDITION(!aPrevFrame || (!aPrevFrame->GetNextContinuation()
                   || IS_TRUE_OVERFLOW_CONTAINER(aPrevFrame->GetNextContinuation()))
                   && !IS_TRUE_OVERFLOW_CONTAINER(aPrevFrame),
                   "aPrevFrame must be the last continuation in its chain!");
 
-  return aParentFrame->InsertFrames(aListID, aPrevFrame, aFrameList);
+  if (aParentFrame->IsAbsoluteContainer() &&
+      aListID == aParentFrame->GetAbsoluteListID()) {
+    return aParentFrame->GetAbsoluteContainingBlock()->
+           InsertFrames(aParentFrame, aListID, aPrevFrame, aFrameList);
+  } else {
+    return aParentFrame->InsertFrames(aListID, aPrevFrame, aFrameList);
+  }
 }
 
 nsresult
 nsFrameManager::RemoveFrame(ChildListID     aListID,
                             nsIFrame*       aOldFrame)
 {
   bool wasDestroyingFrames = mIsDestroyingFrames;
   mIsDestroyingFrames = PR_TRUE;
@@ -502,17 +522,25 @@ nsFrameManager::RemoveFrame(ChildListID 
 
   NS_ASSERTION(!aOldFrame->GetPrevContinuation() ||
                // exception for nsCSSFrameConstructor::RemoveFloatingFirstLetterFrames
                aOldFrame->GetType() == nsGkAtoms::textFrame,
                "Must remove first continuation.");
   NS_ASSERTION(!(aOldFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW &&
                  GetPlaceholderFrameFor(aOldFrame)),
                "Must call RemoveFrame on placeholder for out-of-flows.");
-  nsresult rv = aOldFrame->GetParent()->RemoveFrame(aListID, aOldFrame);
+  nsresult rv = NS_OK;
+  nsIFrame* parentFrame = aOldFrame->GetParent();
+  if (parentFrame->IsAbsoluteContainer() &&
+      aListID == parentFrame->GetAbsoluteListID()) {
+    parentFrame->GetAbsoluteContainingBlock()->
+      RemoveFrame(parentFrame, aListID, aOldFrame);
+  } else {
+    rv = parentFrame->RemoveFrame(aListID, aOldFrame);
+  }
 
   mIsDestroyingFrames = wasDestroyingFrames;
 
   return rv;
 }
 
 //----------------------------------------------------------------------
 
--- a/layout/base/nsFrameManager.h
+++ b/layout/base/nsFrameManager.h
@@ -120,20 +120,17 @@ public:
                                             nsStyleContext* aStyleContext);
   NS_HIDDEN_(void) ClearUndisplayedContentIn(nsIContent* aContent,
                                              nsIContent* aParentContent);
   NS_HIDDEN_(void) ClearAllUndisplayedContentIn(nsIContent* aParentContent);
 
   // Functions for manipulating the frame model
   NS_HIDDEN_(nsresult) AppendFrames(nsIFrame*       aParentFrame,
                                     ChildListID     aListID,
-                                    nsFrameList&    aFrameList)
-  {
-    return aParentFrame->AppendFrames(aListID, aFrameList);
-  }
+                                    nsFrameList&    aFrameList);
 
   NS_HIDDEN_(nsresult) InsertFrames(nsIFrame*       aParentFrame,
                                     ChildListID     aListID,
                                     nsIFrame*       aPrevFrame,
                                     nsFrameList&    aFrameList);
 
   NS_HIDDEN_(nsresult) RemoveFrame(ChildListID     aListID,
                                    nsIFrame*       aOldFrame);
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -2103,20 +2103,17 @@ static bool GetAbsoluteCoord(const nsSty
 static bool
 GetPercentHeight(const nsStyleCoord& aStyle,
                  nsIFrame* aFrame,
                  nscoord& aResult)
 {
   if (eStyleUnit_Percent != aStyle.GetUnit())
     return PR_FALSE;
 
-  nsIFrame *f;
-  for (f = aFrame->GetParent(); f && !f->IsContainingBlock();
-       f = f->GetParent())
-    ;
+  nsIFrame *f = aFrame->GetContainingBlock();
   if (!f) {
     NS_NOTREACHED("top of frame tree not a containing block");
     return PR_FALSE;
   }
 
   const nsStylePosition *pos = f->GetStylePosition();
   nscoord h;
   if (!GetAbsoluteCoord(pos->mHeight, h) &&
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -775,16 +775,23 @@ public:
   static nsIFrame* GetNonGeneratedAncestor(nsIFrame* aFrame);
 
   /**
    * Cast aFrame to an nsBlockFrame* or return null if it's not
    * an nsBlockFrame.
    */
   static nsBlockFrame* GetAsBlock(nsIFrame* aFrame);
 
+  /*
+   * Whether the frame is an nsBlockFrame which is not a wrapper block.
+   */
+  static bool IsNonWrapperBlock(nsIFrame* aFrame) {
+    return GetAsBlock(aFrame) && !aFrame->IsBlockWrapper();
+  }
+
   /**
    * If aFrame is an out of flow frame, return its placeholder, otherwise
    * return its parent.
    */
   static nsIFrame* GetParentOrPlaceholderFor(nsFrameManager* aFrameManager,
                                              nsIFrame* aFrame);
 
   /**
--- a/layout/doc/frame_reflow_debug.html
+++ b/layout/doc/frame_reflow_debug.html
@@ -168,17 +168,16 @@ The entries in the reflow log can be con
  <tr><td>img</td><td>image</td></tr>
  <tr><td>inline</td><td>inline</td></tr>
  <tr><td>letter</td><td>letter</td></tr>
  <tr><td>line</td><td>line</td></tr>
  <tr><td>select</td><td>select</td></tr>
  <tr><td>obj</td><td>object</td></tr>
  <tr><td>page</td><td>page</td></tr>
  <tr><td>place</td><td>placeholder</td></tr>
- <tr><td>posInline</td><td>positionedInline</td></tr>
  <tr><td>canvas</td><td>canvas</td></tr>
  <tr><td>root</td><td>root</td></tr>
  <tr><td>scroll</td><td>scroll</td></tr>
  <tr><td>caption</td><td>tableCaption</td></tr>
  <tr><td>cell</td><td>tableCell</td></tr>
  <tr><td>bcCell</td><td>bcTableCell</td></tr>
  <tr><td>col</td><td>tableCol</td></tr>
  <tr><td>colG</td><td>tableColGroup</td></tr>
--- a/layout/forms/nsFieldSetFrame.cpp
+++ b/layout/forms/nsFieldSetFrame.cpp
@@ -79,16 +79,17 @@ public:
                       nsLayoutUtils::IntrinsicWidthType);
   virtual nscoord GetMinWidth(nsRenderingContext* aRenderingContext);
   virtual nscoord GetPrefWidth(nsRenderingContext* aRenderingContext);
   virtual nsSize ComputeSize(nsRenderingContext *aRenderingContext,
                              nsSize aCBSize, nscoord aAvailableWidth,
                              nsSize aMargin, nsSize aBorder, nsSize aPadding,
                              bool aShrinkWrap);
   virtual nscoord GetBaseline() const;
+  virtual void DestroyFrom(nsIFrame* aDestructRoot);
 
   NS_IMETHOD Reflow(nsPresContext*           aPresContext,
                     nsHTMLReflowMetrics&     aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
                     nsReflowStatus&          aStatus);
                                
   NS_IMETHOD BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                               const nsRect&           aDirtyRect,
@@ -101,17 +102,16 @@ public:
                           nsFrameList&   aFrameList);
   NS_IMETHOD InsertFrames(ChildListID    aListID,
                           nsIFrame*      aPrevFrame,
                           nsFrameList&   aFrameList);
   NS_IMETHOD RemoveFrame(ChildListID    aListID,
                          nsIFrame*      aOldFrame);
 
   virtual nsIAtom* GetType() const;
-  virtual bool IsContainingBlock() const;
 
 #ifdef ACCESSIBILITY  
   virtual already_AddRefed<nsAccessible> CreateAccessible();
 #endif
 
 #ifdef DEBUG
   NS_IMETHOD GetFrameName(nsAString& aResult) const {
     return MakeFrameName(NS_LITERAL_STRING("FieldSet"), aResult);
@@ -140,28 +140,29 @@ NS_IMPL_FRAMEARENA_HELPERS(nsFieldSetFra
 nsFieldSetFrame::nsFieldSetFrame(nsStyleContext* aContext)
   : nsHTMLContainerFrame(aContext)
 {
   mContentFrame = nsnull;
   mLegendFrame  = nsnull;
   mLegendSpace  = 0;
 }
 
+void
+nsFieldSetFrame::DestroyFrom(nsIFrame* aDestructRoot)
+{
+  DestroyAbsoluteFrames(aDestructRoot);
+  nsHTMLContainerFrame::DestroyFrom(aDestructRoot);
+}
+
 nsIAtom*
 nsFieldSetFrame::GetType() const
 {
   return nsGkAtoms::fieldSetFrame;
 }
 
-bool
-nsFieldSetFrame::IsContainingBlock() const
-{
-  return PR_TRUE;
-}
-
 NS_IMETHODIMP
 nsFieldSetFrame::SetInitialChildList(ChildListID    aListID,
                                      nsFrameList&   aChildList)
 {
   // Get the content and legend frames.
   if (!aChildList.OnlyChild()) {
     NS_ASSERTION(aChildList.GetLength() == 2, "Unexpected child list");
     mContentFrame = aChildList.LastChild();
@@ -598,17 +599,17 @@ nsFieldSetFrame::Reflow(nsPresContext*  
       aDesiredSize.height = min;
   }
   aDesiredSize.width = contentRect.width + borderPadding.LeftRight();
   aDesiredSize.SetOverflowAreasToDesiredBounds();
   if (mLegendFrame)
     ConsiderChildOverflow(aDesiredSize.mOverflowAreas, mLegendFrame);
   if (mContentFrame)
     ConsiderChildOverflow(aDesiredSize.mOverflowAreas, mContentFrame);
-  FinishAndStoreOverflow(&aDesiredSize);
+  FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus);
 
   Invalidate(aDesiredSize.VisualOverflow());
 
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
   return NS_OK;
 }
 
 PRIntn
--- a/layout/forms/nsHTMLButtonControlFrame.cpp
+++ b/layout/forms/nsHTMLButtonControlFrame.cpp
@@ -83,16 +83,17 @@ nsHTMLButtonControlFrame::nsHTMLButtonCo
 nsHTMLButtonControlFrame::~nsHTMLButtonControlFrame()
 {
 }
 
 void
 nsHTMLButtonControlFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
   nsFormControlFrame::RegUnRegAccessKey(static_cast<nsIFrame*>(this), PR_FALSE);
+  DestroyAbsoluteFrames(aDestructRoot);
   nsHTMLContainerFrame::DestroyFrom(aDestructRoot);
 }
 
 NS_IMETHODIMP
 nsHTMLButtonControlFrame::Init(
               nsIContent*      aContent,
               nsIFrame*        aParent,
               nsIFrame*        aPrevInFlow)
@@ -276,17 +277,17 @@ nsHTMLButtonControlFrame::Reflow(nsPresC
                                       aReflowState.mComputedMinHeight,
                                       aReflowState.mComputedMaxHeight);
 
   aDesiredSize.ascent +=
     aReflowState.mComputedBorderPadding.top + focusPadding.top;
 
   aDesiredSize.SetOverflowAreasToDesiredBounds();
   ConsiderChildOverflow(aDesiredSize.mOverflowAreas, firstKid);
-  FinishAndStoreOverflow(&aDesiredSize);
+  FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus);
 
   aStatus = NS_FRAME_COMPLETE;
 
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
   return NS_OK;
 }
 
 void
@@ -356,22 +357,16 @@ nsHTMLButtonControlFrame::ReflowButtonCo
   if (aDesiredSize.ascent == nsHTMLReflowMetrics::ASK_FOR_BASELINE)
     aDesiredSize.ascent = aFirstKid->GetBaseline();
 
   // Adjust the baseline by our offset (since we moved the child's
   // baseline by that much).
   aDesiredSize.ascent += yoff;
 }
 
-/* virtual */ bool
-nsHTMLButtonControlFrame::IsContainingBlock() const
-{
-  return PR_TRUE;
-}
-
 PRIntn
 nsHTMLButtonControlFrame::GetSkipSides() const
 {
   return 0;
 }
 
 nsresult nsHTMLButtonControlFrame::SetFormProperty(nsIAtom* aName, const nsAString& aValue)
 {
--- a/layout/forms/nsHTMLButtonControlFrame.h
+++ b/layout/forms/nsHTMLButtonControlFrame.h
@@ -74,18 +74,16 @@ public:
 
   virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext);
 
   NS_IMETHOD Reflow(nsPresContext*          aPresContext,
                     nsHTMLReflowMetrics&     aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
                     nsReflowStatus&          aStatus);
 
-  virtual bool IsContainingBlock() const;
-  
   NS_IMETHOD HandleEvent(nsPresContext* aPresContext, 
                          nsGUIEvent* aEvent,
                          nsEventStatus* aEventStatus);
 
   NS_IMETHOD  Init(nsIContent*      aContent,
                    nsIFrame*        aParent,
                    nsIFrame*        asPrevInFlow);
 
--- a/layout/forms/nsListControlFrame.cpp
+++ b/layout/forms/nsListControlFrame.cpp
@@ -1753,25 +1753,16 @@ nsListControlFrame::DidReflow(nsPresCont
 }
 
 nsIAtom*
 nsListControlFrame::GetType() const
 {
   return nsGkAtoms::listControlFrame; 
 }
 
-bool
-nsListControlFrame::IsContainingBlock() const
-{
-  // We are in fact the containing block for our options.  They should
-  // certainly not use our parent block (or worse yet our parent combobox) for
-  // their sizing.
-  return PR_TRUE;
-}
-
 void
 nsListControlFrame::InvalidateInternal(const nsRect& aDamageRect,
                                        nscoord aX, nscoord aY, nsIFrame* aForChild,
                                        PRUint32 aFlags)
 {
   if (!IsInDropDownMode()) {
     nsHTMLScrollFrame::InvalidateInternal(aDamageRect, aX, aY, this, aFlags);
     return;
--- a/layout/forms/nsListControlFrame.h
+++ b/layout/forms/nsListControlFrame.h
@@ -119,18 +119,16 @@ public:
   virtual nsIAtom* GetType() const;
 
   virtual bool IsFrameOfType(PRUint32 aFlags) const
   {
     return nsHTMLScrollFrame::IsFrameOfType(aFlags &
       ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
   }
 
-  virtual bool IsContainingBlock() const;
-
   virtual void InvalidateInternal(const nsRect& aDamageRect,
                                   nscoord aX, nscoord aY, nsIFrame* aForChild,
                                   PRUint32 aFlags);
 
 #ifdef DEBUG
   NS_IMETHOD GetFrameName(nsAString& aResult) const;
 #endif
 
new file mode 100644
--- /dev/null
+++ b/layout/generic/crashtests/536692-1.xhtml
@@ -0,0 +1,5 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<body onload="document.removeChild(document.documentElement);">
+<table style="position: fixed;"><tr style="position: absolute;"></tr></table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/generic/crashtests/656130-1.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<head>
+<script>
+
+function boom()
+{
+  var b = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
+  b.style.position = "absolute";
+  document.getElementById("a").appendChild(b);
+}
+
+</script>
+</head>
+
+<body onload="boom();"><div id="a" style="display: -moz-inline-stack; position: relative">x</div></body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/layout/generic/crashtests/656130-2.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+function doe() {
+document.getElementById('b').setAttribute('style', 'position: absolute;');
+document.body.offsetHeight;
+document.body.setAttribute('style', 'position: relative;');
+document.body.offsetHeight;
+document.getElementById('b').setAttribute('style', '');
+}
+setTimeout(doe,0);
+</script>
+</head>
+<body>
+
+<span style="position: relative; ">
+<div>
+<div id="b">
+</div>
+</div>
+</span>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/generic/crashtests/660451-1.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+function doe() {
+document.getElementById('b').setAttribute('style', 'position: absolute;');
+document.body.offsetHeight;
+document.body.setAttribute('style', 'position: relative;');
+document.body.offsetHeight;
+document.getElementById('b').setAttribute('style', '');
+}
+setTimeout(doe,0);
+</script>
+</head>
+<body>
+
+<span style="position: relative; ">
+<div>
+<div id="b">
+</div>
+</div>
+</span>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/generic/crashtests/665853.html
@@ -0,0 +1,29 @@
+<html><head>
+<link href="data:text/css," rel="stylesheet" type="text/css">
+<style type="text/css">
+.Big_Preview_Download {
+  display:inline;
+  position:relative;
+}
+.cma {
+  position: absolute;
+}
+</style>
+</head>
+
+<body>
+
+<div class="Big_Preview_Download">
+  <table>
+    <tbody>
+      <tr>
+        <td>
+          <script type="text/javascript"> </script>
+          <div class="cma"></div>
+        </td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+
+</body></html>
--- a/layout/generic/crashtests/crashtests.list
+++ b/layout/generic/crashtests/crashtests.list
@@ -312,16 +312,17 @@ load 515811-1.html
 load 517968.html
 load 519031.xhtml
 load 520340.html
 load 533379-1.html
 load 533379-2.html
 load 534082-1.html
 load 534366-1.html
 load 534366-2.html
+load 536692-1.xhtml
 load 541277-1.html
 load 541277-2.html
 load 541714-1.html
 load 541714-2.html
 load 542136-1.html
 load 545571-1.html
 load 547338.xul
 load 547843-1.xhtml
@@ -355,17 +356,21 @@ load 604843.html
 load 605340.html
 load 621841-1.html
 load 645072-1.html
 load 645072-2.html
 load 646561-1.html
 load 646983-1.html
 load 647332-1.html
 load 650499-1.html
+load 656130-1.html
+load 656130-2.html
 load 660416.html
+load 660451-1.html
+load 665853.html
 load text-overflow-form-elements.html
 load text-overflow-iframe.html
 load text-overflow-bug666751-1.html
 load text-overflow-bug666751-2.html
 asserts(2) load text-overflow-bug670564.xhtml # asserts(2) for bug 436470
 load text-overflow-bug671796.xhtml
 load 667025.html
 asserts(14) asserts-if(Android,8) load 673770.html # bug 569193 and bug 459597
--- a/layout/generic/nsAbsoluteContainingBlock.cpp
+++ b/layout/generic/nsAbsoluteContainingBlock.cpp
@@ -422,17 +422,17 @@ nsAbsoluteContainingBlock::ReflowAbsolut
                                    aContainingBlockHeight);
 
   // Send the WillReflow() notification and position the frame
   aKidFrame->WillReflow(aPresContext);
 
   bool constrainHeight = (aReflowState.availableHeight != NS_UNCONSTRAINEDSIZE)
     && aConstrainHeight
        // Don't split if told not to (e.g. for fixed frames)
-    && (aDelegatingFrame->GetType() != nsGkAtoms::positionedInlineFrame)
+    && (aDelegatingFrame->GetType() != nsGkAtoms::inlineFrame)
        //XXX we don't handle splitting frames for inline absolute containing blocks yet
     && (aKidFrame->GetRect().y <= aReflowState.availableHeight);
        // Don't split things below the fold. (Ideally we shouldn't *have*
        // anything totally below the fold, but we can't position frames
        // across next-in-flow breaks yet.
   if (constrainHeight) {
     kidReflowState.availableHeight = aReflowState.availableHeight - border.top
                                      - kidReflowState.mComputedMargin.top;
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -302,17 +302,17 @@ NS_IMPL_FRAMEARENA_HELPERS(nsBlockFrame)
 
 nsBlockFrame::~nsBlockFrame()
 {
 }
 
 void
 nsBlockFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
-  mAbsoluteContainer.DestroyFrames(this, aDestructRoot);
+  DestroyAbsoluteFrames(aDestructRoot);
   // Outside bullets are not in our child-list so check for them here
   // and delete them when present.
   if (mBullet && HaveOutsideBullet()) {
     mBullet->DestroyFrom(aDestructRoot);
     mBullet = nsnull;
   }
 
   mFloats.DestroyFramesFrom(aDestructRoot);
@@ -581,18 +581,16 @@ nsBlockFrame::GetChildList(ChildListID a
     case kOverflowList: {
       // XXXbz once we start using nsFrameList for our overflow list, we
       // could switch GetChildList to returning a |const nsFrameList&|.
       nsLineList* overflowLines = GetOverflowLines();
       return overflowLines ? nsFrameList(overflowLines->front()->mFirstChild,
                                          overflowLines->back()->LastChild())
                            : nsFrameList::EmptyList();
     }
-    case kAbsoluteList:
-      return mAbsoluteContainer.GetChildList();
     case kFloatList:
       return mFloats;
     case kOverflowOutOfFlowList: {
       const nsFrameList* list = GetOverflowOutOfFlows();
       return list ? *list : nsFrameList::EmptyList();
     }
     case kPushedFloatsList: {
       const nsFrameList* list = GetPushedFloats();
@@ -620,40 +618,23 @@ nsBlockFrame::GetChildLists(nsTArray<Chi
   if (list) {
     list->AppendIfNonempty(aLists, kOverflowOutOfFlowList);
   }
   mFloats.AppendIfNonempty(aLists, kFloatList);
   if (HaveOutsideBullet()) {
     nsFrameList bullet(mBullet, mBullet);
     bullet.AppendIfNonempty(aLists, kBulletList);
   }
-  mAbsoluteContainer.AppendChildList(aLists, kAbsoluteList);
   list = GetPushedFloats();
   if (list) {
     list->AppendIfNonempty(aLists, kPushedFloatsList);
   }
 }
 
 /* virtual */ bool
-nsBlockFrame::IsContainingBlock() const
-{
-  // The block wrappers we use to wrap blocks inside inlines aren't
-  // described in the CSS spec.  We need to make them not be containing
-  // blocks for the cases where we care about the 'direction' property
-  // of an element's containing block.
-  // Since the parent of such a block is either a normal block or
-  // another such pseudo, this shouldn't cause anything bad to happen.
-  // Also the anonymous blocks inside table cells are not containing blocks.
-  nsIAtom *pseudoType = GetStyleContext()->GetPseudo();
-  return pseudoType != nsCSSAnonBoxes::mozAnonymousBlock &&
-         pseudoType != nsCSSAnonBoxes::mozAnonymousPositionedBlock &&
-         pseudoType != nsCSSAnonBoxes::cellContent;
-}
-
-/* virtual */ bool
 nsBlockFrame::IsFloatContainingBlock() const
 {
   return PR_TRUE;
 }
 
 static void ReparentFrame(nsIFrame* aFrame, nsIFrame* aOldParent,
                           nsIFrame* aNewParent) {
   NS_ASSERTION(aOldParent == aFrame->GetParent(),
@@ -1157,30 +1138,31 @@ nsBlockFrame::Reflow(nsPresContext*     
   // condition 1.
   // XXX checking oldSize is bogus, there are various reasons we might have
   // reflowed but our size might not have been changed to what we
   // asked for (e.g., we ended up being pushed to a new page)
   // When WillReflowAgainForClearance is true, we will reflow again without
   // resetting the size. Because of this, we must not reflow our abs-pos children
   // in that situation --- what we think is our "new size"
   // will not be our real new size. This also happens to be more efficient.
-  if (mAbsoluteContainer.HasAbsoluteFrames()) {
+  if (HasAbsolutelyPositionedChildren()) {
+    nsAbsoluteContainingBlock* absoluteContainer = GetAbsoluteContainingBlock();
     bool haveInterrupt = aPresContext->HasPendingInterrupt();
     if (reflowState->WillReflowAgainForClearance() ||
         haveInterrupt) {
       // Make sure that when we reflow again we'll actually reflow all the abs
       // pos frames that might conceivably depend on our size (or all of them,
       // if we're dirty right now and interrupted; in that case we also need
       // to mark them all with NS_FRAME_IS_DIRTY).  Sadly, we can't do much
       // better than that, because we don't really know what our size will be,
       // and it might in fact not change on the followup reflow!
       if (haveInterrupt && (GetStateBits() & NS_FRAME_IS_DIRTY)) {
-        mAbsoluteContainer.MarkAllFramesDirty();
+        absoluteContainer->MarkAllFramesDirty();
       } else {
-        mAbsoluteContainer.MarkSizeDependentFramesDirty();
+        absoluteContainer->MarkSizeDependentFramesDirty();
       }
     } else {
       nsSize containingBlockSize =
         CalculateContainingBlockSizeForAbsolutes(*reflowState,
                                                  nsSize(aMetrics.width,
                                                         aMetrics.height));
 
       // Mark frames that depend on changes we just made to this frame as dirty:
@@ -1194,22 +1176,22 @@ nsBlockFrame::Reflow(nsPresContext*     
       // If isRoot and we have auto height, then we are the initial
       // containing block and the containing block height is the
       // viewport height, which can't change during incremental
       // reflow.
       bool cbHeightChanged =
         !(isRoot && NS_UNCONSTRAINEDSIZE == reflowState->ComputedHeight()) &&
         aMetrics.height != oldSize.height;
 
-      rv = mAbsoluteContainer.Reflow(this, aPresContext, *reflowState,
-                                     state.mReflowStatus,
-                                     containingBlockSize.width,
-                                     containingBlockSize.height, PR_TRUE,
-                                     cbWidthChanged, cbHeightChanged,
-                                     &aMetrics.mOverflowAreas);
+      absoluteContainer->Reflow(this, aPresContext, *reflowState,
+                                state.mReflowStatus,
+                                containingBlockSize.width,
+                                containingBlockSize.height, true,
+                                cbWidthChanged, cbHeightChanged,
+                                &aMetrics.mOverflowAreas);
 
       //XXXfr Why isn't this rv (and others in this file) checked/returned?
     }
   }
 
   // Determine if we need to repaint our border, background or outline
   CheckInvalidateSizeChange(aMetrics);
 
@@ -4677,17 +4659,17 @@ NS_IMETHODIMP
 nsBlockFrame::AppendFrames(ChildListID  aListID,
                            nsFrameList& aFrameList)
 {
   if (aFrameList.IsEmpty()) {
     return NS_OK;
   }
   if (aListID != kPrincipalList) {
     if (kAbsoluteList == aListID) {
-      return mAbsoluteContainer.AppendFrames(this, aListID, aFrameList);
+      return nsContainerFrame::AppendFrames(aListID, aFrameList);
     }
     else if (kFloatList == aListID) {
       mFloats.AppendFrames(nsnull, aFrameList);
       return NS_OK;
     }
     else {
       NS_ERROR("unexpected child list");
       return NS_ERROR_INVALID_ARG;
@@ -4725,18 +4707,17 @@ nsBlockFrame::InsertFrames(ChildListID a
                            nsIFrame* aPrevFrame,
                            nsFrameList& aFrameList)
 {
   NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this,
                "inserting after sibling frame with different parent");
 
   if (aListID != kPrincipalList) {
     if (kAbsoluteList == aListID) {
-      return mAbsoluteContainer.InsertFrames(this, aListID, aPrevFrame,
-                                             aFrameList);
+      return nsContainerFrame::InsertFrames(aListID, aPrevFrame, aFrameList);
     }
     else if (kFloatList == aListID) {
       mFloats.InsertFrames(this, aPrevFrame, aFrameList);
       return NS_OK;
     }
 #ifdef IBMBIDI
     else if (kNoReflowPrincipalList == aListID) {}
 #endif // IBMBIDI
@@ -5009,17 +4990,17 @@ nsBlockFrame::RemoveFrame(ChildListID aL
   if (aListID == kPrincipalList) {
     bool hasFloats = BlockHasAnyFloats(aOldFrame);
     rv = DoRemoveFrame(aOldFrame, REMOVE_FIXED_CONTINUATIONS);
     if (hasFloats) {
       MarkSameFloatManagerLinesDirty(this);
     }
   }
   else if (kAbsoluteList == aListID) {
-    mAbsoluteContainer.RemoveFrame(this, aListID, aOldFrame);
+    nsContainerFrame::RemoveFrame(aListID, aOldFrame);
     return NS_OK;
   }
   else if (kFloatList == aListID) {
     // Make sure to mark affected lines dirty for the float frame
     // we are removing; this way is a bit messy, but so is the rest of the code.
     // See bug 390762.
     NS_ASSERTION(!aOldFrame->GetPrevContinuation(),
                  "RemoveFrame should not be called on pushed floats.");
@@ -5054,19 +5035,19 @@ nsBlockFrame::DoRemoveOutOfFlowFrame(nsI
 {
   // The containing block is always the parent of aFrame.
   nsBlockFrame* block = (nsBlockFrame*)aFrame->GetParent();
 
   // Remove aFrame from the appropriate list.
   const nsStyleDisplay* display = aFrame->GetStyleDisplay();
   if (display->IsAbsolutelyPositioned()) {
     // This also deletes the next-in-flows
-    block->mAbsoluteContainer.RemoveFrame(block,
-                                          kAbsoluteList,
-                                          aFrame);
+    block->GetAbsoluteContainingBlock()->RemoveFrame(block,
+                                                     kAbsoluteList,
+                                                     aFrame);
   }
   else {
     // First remove aFrame's next-in-flows
     nsIFrame* nif = aFrame->GetNextInFlow();
     if (nif) {
       static_cast<nsContainerFrame*>(nif->GetParent())
         ->DeleteNextInFlowChild(aFrame->PresContext(), nif, PR_FALSE);
     }
@@ -6184,18 +6165,16 @@ nsBlockFrame::BuildDisplayList(nsDisplay
     DisplayOverflowContainers(aBuilder, aDirtyRect, aLists);
     for (nsIFrame* f = mFloats.FirstChild(); f; f = f->GetNextSibling()) {
       if (f->GetStateBits() & NS_FRAME_IS_PUSHED_FLOAT)
          BuildDisplayListForChild(aBuilder, f, aDirtyRect, aLists);
     }
   }
 
   aBuilder->MarkFramesForDisplayList(this, mFloats, aDirtyRect);
-  aBuilder->MarkFramesForDisplayList(this, mAbsoluteContainer.GetChildList(),
-                                     aDirtyRect);
 
   // Prepare for text-overflow processing.
   nsAutoPtr<TextOverflow> textOverflow(
     TextOverflow::WillProcessLines(aBuilder, aLists, this));
 
   // Don't use the line cursor if we might have a descendant placeholder ...
   // it might skip lines that contain placeholders but don't themselves
   // intersect with the dirty area.
@@ -6450,17 +6429,17 @@ nsBlockFrame::Init(nsIContent*      aCon
 
 NS_IMETHODIMP
 nsBlockFrame::SetInitialChildList(ChildListID     aListID,
                                   nsFrameList&    aChildList)
 {
   nsresult rv = NS_OK;
 
   if (kAbsoluteList == aListID) {
-    mAbsoluteContainer.SetInitialChildList(this, aListID, aChildList);
+    nsContainerFrame::SetInitialChildList(aListID, aChildList);
   }
   else if (kFloatList == aListID) {
     mFloats.SetFrames(aChildList);
   }
   else {
     nsPresContext* presContext = PresContext();
 
 #ifdef DEBUG
@@ -6992,107 +6971,35 @@ nsBlockFrame::WidthToClearPastFloats(nsB
                                      const nsRect& aFloatAvailableSpace,
                                      nsIFrame* aFrame)
 {
   nscoord leftOffset, rightOffset;
   nsCSSOffsetState offsetState(aFrame, aState.mReflowState.rendContext,
                                aState.mContentArea.width);
 
   ReplacedElementWidthToClear result;
-  // A table outer frame is an exception in that it is a block child
-  // that is not a containing block for its children.
-  if (aFrame->GetType() == nsGkAtoms::tableOuterFrame) {
-    nsIFrame *innerTable = aFrame->GetFirstPrincipalChild();
-    nsIFrame *caption = aFrame->GetFirstChild(kCaptionList);
-
-    nsMargin tableMargin, captionMargin;
-    {
-      nsCSSOffsetState tableOS(innerTable, aState.mReflowState.rendContext,
-                               aState.mContentArea.width);
-      tableMargin = tableOS.mComputedMargin;
-    }
-
-    if (caption) {
-      nsCSSOffsetState captionOS(caption, aState.mReflowState.rendContext,
-                                 aState.mContentArea.width);
-      captionMargin = captionOS.mComputedMargin;
-    }
-
-    PRUint8 captionSide;
-    if (!caption ||
-        ((captionSide = caption->GetStyleTableBorder()->mCaptionSide)
-           == NS_STYLE_CAPTION_SIDE_TOP ||
-         captionSide == NS_STYLE_CAPTION_SIDE_BOTTOM)) {
-      result.marginLeft = tableMargin.left;
-      result.marginRight = tableMargin.right;
-    } else if (captionSide == NS_STYLE_CAPTION_SIDE_TOP_OUTSIDE ||
-               captionSide == NS_STYLE_CAPTION_SIDE_BOTTOM_OUTSIDE) {
-      // FIXME:  This doesn't treat the caption and table independently,
-      // since we adjust by only the smaller margin, and the table outer
-      // frame doesn't know about it.
-      result.marginLeft  = NS_MIN(tableMargin.left,  captionMargin.left);
-      result.marginRight = NS_MIN(tableMargin.right, captionMargin.right);
-    } else {
-      NS_ASSERTION(captionSide == NS_STYLE_CAPTION_SIDE_LEFT ||
-                   captionSide == NS_STYLE_CAPTION_SIDE_RIGHT,
-                   "unexpected caption-side");
-      if (captionSide == NS_STYLE_CAPTION_SIDE_LEFT) {
-        result.marginLeft = captionMargin.left;
-        result.marginRight = tableMargin.right;
-      } else {
-        result.marginLeft = tableMargin.left;
-        result.marginRight = captionMargin.right;
-      }
-    }
-
-    aState.ComputeReplacedBlockOffsetsForFloats(aFrame, aFloatAvailableSpace,
-                                                leftOffset, rightOffset,
-                                                &result);
-
-    // result.marginLeft has already been subtracted from leftOffset (etc.)
-    nscoord availWidth = aState.mContentArea.width - leftOffset - rightOffset;
-    // Force the outer frame to shrink-wrap (otherwise it just sizes to
-    // the available width unconditionally).
-    result.borderBoxWidth =
-      aFrame->ComputeSize(aState.mReflowState.rendContext,
-                          nsSize(aState.mContentArea.width,
-                                 NS_UNCONSTRAINEDSIZE),
-                          availWidth,
-                          nsSize(offsetState.mComputedMargin.LeftRight(),
-                                 offsetState.mComputedMargin.TopBottom()),
-                          nsSize(offsetState.mComputedBorderPadding.LeftRight() -
-                                   offsetState.mComputedPadding.LeftRight(),
-                                 offsetState.mComputedBorderPadding.TopBottom() -
-                                   offsetState.mComputedPadding.TopBottom()),
-                          nsSize(offsetState.mComputedPadding.LeftRight(),
-                                 offsetState.mComputedPadding.TopBottom()),
-                          PR_TRUE).width +
-      offsetState.mComputedBorderPadding.LeftRight() -
-      (result.marginLeft + result.marginRight);
-  } else {
-    aState.ComputeReplacedBlockOffsetsForFloats(aFrame, aFloatAvailableSpace,
-                                                leftOffset, rightOffset);
-    nscoord availWidth = aState.mContentArea.width - leftOffset - rightOffset;
-
-    // We actually don't want the min width here; see bug 427782; we only
-    // want to displace if the width won't compute to a value small enough
-    // to fit.
-    // All we really need here is the result of ComputeSize, and we
-    // could *almost* get that from an nsCSSOffsetState, except for the
-    // last argument.
-    nsSize availSpace(availWidth, NS_UNCONSTRAINEDSIZE);
-    nsHTMLReflowState reflowState(aState.mPresContext, aState.mReflowState,
-                                  aFrame, availSpace);
-    result.borderBoxWidth = reflowState.ComputedWidth() +
-                            reflowState.mComputedBorderPadding.LeftRight();
-    // Use the margins from offsetState rather than reflowState so that
-    // they aren't reduced by ignoring margins in overconstrained cases.
-    result.marginLeft  = offsetState.mComputedMargin.left;
-    result.marginRight = offsetState.mComputedMargin.right;
-  }
+  aState.ComputeReplacedBlockOffsetsForFloats(aFrame, aFloatAvailableSpace,
+                                              leftOffset, rightOffset);
+  nscoord availWidth = aState.mContentArea.width - leftOffset - rightOffset;
+
+  // We actually don't want the min width here; see bug 427782; we only
+  // want to displace if the width won't compute to a value small enough
+  // to fit.
+  // All we really need here is the result of ComputeSize, and we
+  // could *almost* get that from an nsCSSOffsetState, except for the
+  // last argument.
+  nsSize availSpace(availWidth, NS_UNCONSTRAINEDSIZE);
+  nsHTMLReflowState reflowState(aState.mPresContext, aState.mReflowState,
+                                aFrame, availSpace);
+  result.borderBoxWidth = reflowState.ComputedWidth() +
+                          reflowState.mComputedBorderPadding.LeftRight();
+  // Use the margins from offsetState rather than reflowState so that
+  // they aren't reduced by ignoring margins in overconstrained cases.
+  result.marginLeft  = offsetState.mComputedMargin.left;
+  result.marginRight = offsetState.mComputedMargin.right;
   return result;
 }
  
 /* static */
 nsBlockFrame*
 nsBlockFrame::GetNearestAncestorBlock(nsIFrame* aCandidate)
 {
   nsBlockFrame* block = nsnull;
--- a/layout/generic/nsBlockFrame.h
+++ b/layout/generic/nsBlockFrame.h
@@ -176,17 +176,16 @@ public:
   NS_IMETHOD  RemoveFrame(ChildListID     aListID,
                           nsIFrame*       aOldFrame);
   virtual nsFrameList GetChildList(ChildListID aListID) const;
   virtual void GetChildLists(nsTArray<ChildList>* aLists) const;
   virtual nscoord GetBaseline() const;
   virtual nscoord GetCaretBaseline() const;
   virtual void DestroyFrom(nsIFrame* aDestructRoot);
   virtual nsSplittableType GetSplittableType() const;
-  virtual bool IsContainingBlock() const;
   virtual bool IsFloatContainingBlock() const;
   NS_IMETHOD BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                               const nsRect&           aDirtyRect,
                               const nsDisplayListSet& aLists);
   virtual void InvalidateInternal(const nsRect& aDamageRect,
                                   nscoord aX, nscoord aY, nsIFrame* aForChild,
                                   PRUint32 aFlags);
   virtual nsIAtom* GetType() const;
@@ -329,17 +328,16 @@ public:
    */
   static nsBlockFrame* GetNearestAncestorBlock(nsIFrame* aCandidate);
   
 protected:
   nsBlockFrame(nsStyleContext* aContext)
     : nsHTMLContainerFrame(aContext)
     , mMinWidth(NS_INTRINSIC_WIDTH_UNKNOWN)
     , mPrefWidth(NS_INTRINSIC_WIDTH_UNKNOWN)
-    , mAbsoluteContainer(kAbsoluteList)
   {
 #ifdef DEBUG
   InitDebugFlags();
 #endif
   }
   virtual ~nsBlockFrame();
 
 #ifdef DEBUG
@@ -746,20 +744,16 @@ protected:
 
   // XXX_fix_me: subclass one more time!
   // For list-item frames, this is the bullet frame.
   nsBulletFrame* mBullet;
 
   friend class nsBlockReflowState;
   friend class nsBlockInFlowLineIterator;
 
-private:
-  nsAbsoluteContainingBlock mAbsoluteContainer;
-
-
 #ifdef DEBUG
 public:
   static bool gLamePaintMetrics;
   static bool gLameReflowMetrics;
   static bool gNoisy;
   static bool gNoisyDamageRepair;
   static bool gNoisyIntrinsic;
   static bool gNoisyReflow;
--- a/layout/generic/nsBlockReflowState.cpp
+++ b/layout/generic/nsBlockReflowState.cpp
@@ -163,58 +163,45 @@ nsBlockReflowState::FreeLineBox(nsLineBo
     aLine->Destroy(mPresContext->PresShell());
   }
 }
 
 void
 nsBlockReflowState::ComputeReplacedBlockOffsetsForFloats(nsIFrame* aFrame,
                                                          const nsRect& aFloatAvailableSpace,
                                                          nscoord& aLeftResult,
-                                                         nscoord& aRightResult,
-                                                         nsBlockFrame::
-                                                      ReplacedElementWidthToClear
-                                                                 *aReplacedWidth)
+                                                         nscoord& aRightResult)
 {
   // The frame is clueless about the float manager and therefore we
   // only give it free space. An example is a table frame - the
   // tables do not flow around floats.
   // However, we can let its margins intersect floats.
   NS_ASSERTION(aFloatAvailableSpace.x >= mContentArea.x, "bad avail space rect x");
   NS_ASSERTION(aFloatAvailableSpace.width == 0 ||
                aFloatAvailableSpace.XMost() <= mContentArea.XMost(),
                "bad avail space rect width");
 
   nscoord leftOffset, rightOffset;
   if (aFloatAvailableSpace.width == mContentArea.width) {
     // We don't need to compute margins when there are no floats around.
     leftOffset = 0;
     rightOffset = 0;
   } else {
-    // We pass in aReplacedWidth to make handling outer table frames
-    // work correctly.  For outer table frames, we need to subtract off
-    // the margin that's going to be at the edge of them, since we're
-    // dealing with margin that it's really the child's responsibility
-    // to place.
+    nsMargin frameMargin;
     nsCSSOffsetState os(aFrame, mReflowState.rendContext, mContentArea.width);
-    NS_ASSERTION(!aReplacedWidth ||
-                 aFrame->GetType() == nsGkAtoms::tableOuterFrame ||
-                 (aReplacedWidth->marginLeft  == os.mComputedMargin.left &&
-                  aReplacedWidth->marginRight == os.mComputedMargin.right),
-                 "unexpected aReplacedWidth");
+    frameMargin = os.mComputedMargin;
 
     nscoord leftFloatXOffset = aFloatAvailableSpace.x - mContentArea.x;
-    leftOffset = NS_MAX(leftFloatXOffset, os.mComputedMargin.left) -
-                 (aReplacedWidth ? aReplacedWidth->marginLeft
-                                 : os.mComputedMargin.left);
+    leftOffset = NS_MAX(leftFloatXOffset, frameMargin.left) -
+                 frameMargin.left;
     leftOffset = NS_MAX(leftOffset, 0); // in case of negative margin
     nscoord rightFloatXOffset =
       mContentArea.XMost() - aFloatAvailableSpace.XMost();
-    rightOffset = NS_MAX(rightFloatXOffset, os.mComputedMargin.right) -
-                  (aReplacedWidth ? aReplacedWidth->marginRight
-                                  : os.mComputedMargin.right);
+    rightOffset = NS_MAX(rightFloatXOffset, frameMargin.right) -
+                  frameMargin.right;
     rightOffset = NS_MAX(rightOffset, 0); // in case of negative margin
   }
   aLeftResult = leftOffset;
   aRightResult = rightOffset;
 }
 
 // Compute the amount of available space for reflowing a block frame
 // at the current Y coordinate. This method assumes that
@@ -280,29 +267,19 @@ nsBlockReflowState::ComputeBlockAvailSpa
       // Since there are no floats present the float-edge property
       // doesn't matter therefore give the block element all of the
       // available space since it will flow around the float itself.
       aResult.x = mContentArea.x;
       aResult.width = mContentArea.width;
     }
   }
   else {
-    nsBlockFrame::ReplacedElementWidthToClear replacedWidthStruct;
-    nsBlockFrame::ReplacedElementWidthToClear *replacedWidth = nsnull;
-    if (aFrame->GetType() == nsGkAtoms::tableOuterFrame) {
-      replacedWidth = &replacedWidthStruct;
-      replacedWidthStruct =
-        nsBlockFrame::WidthToClearPastFloats(*this, aFloatAvailableSpace.mRect,
-                                             aFrame);
-    }
-
     nscoord leftOffset, rightOffset;
     ComputeReplacedBlockOffsetsForFloats(aFrame, aFloatAvailableSpace.mRect,
-                                         leftOffset, rightOffset,
-                                         replacedWidth);
+                                         leftOffset, rightOffset);
     aResult.x = mContentArea.x + leftOffset;
     aResult.width = mContentArea.width - leftOffset - rightOffset;
   }
 
 #ifdef REALLY_NOISY_REFLOW
   printf("  CBAS: result %d %d %d %d\n", aResult.x, aResult.y, aResult.width, aResult.height);
 #endif
 }
--- a/layout/generic/nsBlockReflowState.h
+++ b/layout/generic/nsBlockReflowState.h
@@ -147,24 +147,21 @@ public:
   const nsMargin& Margin() const {
     return mReflowState.mComputedMargin;
   }
 
   // Reconstruct the previous bottom margin that goes above |aLine|.
   void ReconstructMarginAbove(nsLineList::iterator aLine);
 
   // Caller must have called GetAvailableSpace for the correct position
-  // (which need not be the current mY).  Callers need only pass
-  // aReplacedWidth for outer table frames.
+  // (which need not be the current mY).
   void ComputeReplacedBlockOffsetsForFloats(nsIFrame* aFrame,
                                             const nsRect& aFloatAvailableSpace,
                                             nscoord& aLeftResult,
-                                            nscoord& aRightResult,
-                                       nsBlockFrame::ReplacedElementWidthToClear
-                                                      *aReplacedWidth = nsnull);
+                                            nscoord& aRightResult);
 
   // Caller must have called GetAvailableSpace for the current mY
   void ComputeBlockAvailSpace(nsIFrame* aFrame,
                               const nsStyleDisplay* aDisplay,
                               const nsFlowAreaRect& aFloatAvailableSpace,
                               bool aBlockAvoidsFloats,
                               nsRect& aResult);
 
--- a/layout/generic/nsCanvasFrame.cpp
+++ b/layout/generic/nsCanvasFrame.cpp
@@ -47,48 +47,44 @@
 #include "nsRenderingContext.h"
 #include "nsGUIEvent.h"
 #include "nsStyleConsts.h"
 #include "nsGkAtoms.h"
 #include "nsEventStateManager.h"
 #include "nsIPresShell.h"
 #include "nsIScrollPositionListener.h"
 #include "nsDisplayList.h"
-#include "nsAbsoluteContainingBlock.h"
 #include "nsCSSFrameConstructor.h"
 #include "nsFrameManager.h"
 
 // for focus
 #include "nsIScrollableFrame.h"
 #include "nsIDocShell.h"
 
 #ifdef DEBUG_rods
 //#define DEBUG_CANVAS_FOCUS
 #endif
 
-#define CANVAS_ABS_POS_CHILD_LIST NS_CONTAINER_LIST_COUNT_INCL_OC
-
 
 nsIFrame*
 NS_NewCanvasFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsCanvasFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsCanvasFrame)
 
 NS_QUERYFRAME_HEAD(nsCanvasFrame)
   NS_QUERYFRAME_ENTRY(nsCanvasFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsHTMLContainerFrame)
 
 void
 nsCanvasFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
-  mAbsoluteContainer.DestroyFrames(this, aDestructRoot);
-
+  DestroyAbsoluteFrames(aDestructRoot);
   nsIScrollableFrame* sf =
     PresContext()->GetPresShell()->GetRootScrollFrameAsScrollable();
   if (sf) {
     sf->RemoveScrollPositionListener(this);
   }
 
   nsHTMLContainerFrame::DestroyFrom(aDestructRoot);
 }
@@ -120,34 +116,30 @@ nsCanvasFrame::SetHasFocus(bool aHasFocu
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasFrame::SetInitialChildList(ChildListID     aListID,
                                    nsFrameList&    aChildList)
 {
-  if (kAbsoluteList == aListID)
-    return mAbsoluteContainer.SetInitialChildList(this, aListID, aChildList);
-
   NS_ASSERTION(aListID != kPrincipalList ||
                aChildList.IsEmpty() || aChildList.OnlyChild(),
                "Primary child list can have at most one frame in it");
   return nsHTMLContainerFrame::SetInitialChildList(aListID, aChildList);
 }
 
 NS_IMETHODIMP
 nsCanvasFrame::AppendFrames(ChildListID     aListID,
                             nsFrameList&    aFrameList)
 {
-  if (kAbsoluteList == aListID)
-    return mAbsoluteContainer.AppendFrames(this, aListID, aFrameList);
-
-  NS_ASSERTION(aListID == kPrincipalList, "unexpected child list ID");
-  NS_PRECONDITION(mFrames.IsEmpty(), "already have a child frame");
+  NS_ASSERTION(aListID == kPrincipalList ||
+               aListID == kAbsoluteList, "unexpected child list ID");
+  NS_PRECONDITION(aListID != kAbsoluteList ||
+                  mFrames.IsEmpty(), "already have a child frame");
   if (aListID != kPrincipalList) {
     // We only support the Principal and Absolute child lists.
     return NS_ERROR_INVALID_ARG;
   }
 
   if (!mFrames.IsEmpty()) {
     // We only allow a single principal child frame.
     return NS_ERROR_INVALID_ARG;
@@ -168,39 +160,32 @@ nsCanvasFrame::AppendFrames(ChildListID 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasFrame::InsertFrames(ChildListID     aListID,
                             nsIFrame*       aPrevFrame,
                             nsFrameList&    aFrameList)
 {
-  if (kAbsoluteList == aListID)
-    return mAbsoluteContainer.InsertFrames(this, aListID, aPrevFrame, aFrameList);
-
   // Because we only support a single child frame inserting is the same
   // as appending
   NS_PRECONDITION(!aPrevFrame, "unexpected previous sibling frame");
   if (aPrevFrame)
     return NS_ERROR_UNEXPECTED;
 
   return AppendFrames(aListID, aFrameList);
 }
 
 NS_IMETHODIMP
 nsCanvasFrame::RemoveFrame(ChildListID     aListID,
                            nsIFrame*       aOldFrame)
 {
-  if (kAbsoluteList == aListID) {
-    mAbsoluteContainer.RemoveFrame(this, aListID, aOldFrame);
-    return NS_OK;
-  }
-
-  NS_ASSERTION(aListID == kPrincipalList, "unexpected child list ID");
-  if (aListID != kPrincipalList) {
+  NS_ASSERTION(aListID == kPrincipalList ||
+               aListID == kAbsoluteList, "unexpected child list ID");
+  if (aListID != kPrincipalList || aListID != kAbsoluteList) {
     // We only support the Principal and Absolute child lists.
     return NS_ERROR_INVALID_ARG;
   }
 
   if (aOldFrame != mFrames.FirstChild())
     return NS_ERROR_FAILURE;
 
   // It's our one and only child frame
@@ -213,32 +198,16 @@ nsCanvasFrame::RemoveFrame(ChildListID  
   mFrames.DestroyFrame(aOldFrame);
 
   PresContext()->PresShell()->
     FrameNeedsReflow(this, nsIPresShell::eTreeChange,
                      NS_FRAME_HAS_DIRTY_CHILDREN);
   return NS_OK;
 }
 
-nsFrameList
-nsCanvasFrame::GetChildList(ChildListID aListID) const
-{
-  if (kAbsoluteList == aListID)
-    return mAbsoluteContainer.GetChildList();
-
-  return nsHTMLContainerFrame::GetChildList(aListID);
-}
-
-void
-nsCanvasFrame::GetChildLists(nsTArray<ChildList>* aLists) const
-{
-  nsHTMLContainerFrame::GetChildLists(aLists);
-  mAbsoluteContainer.AppendChildList(aLists, kAbsoluteList);
-}
-
 nsRect nsCanvasFrame::CanvasArea() const
 {
   // Not clear which overflow rect we want here, but it probably doesn't
   // matter.
   nsRect result(GetVisualOverflowRect());
 
   nsIScrollableFrame *scrollableFrame = do_QueryFrame(GetParent());
   if (scrollableFrame) {
@@ -307,19 +276,16 @@ nsCanvasFrame::BuildDisplayList(nsDispla
                                 const nsDisplayListSet& aLists)
 {
   nsresult rv;
 
   if (GetPrevInFlow()) {
     DisplayOverflowContainers(aBuilder, aDirtyRect, aLists);
   }
 
-  aBuilder->MarkFramesForDisplayList(this, mAbsoluteContainer.GetChildList(),
-                                     aDirtyRect);
-  
   // Force a background to be shown. We may have a background propagated to us,
   // in which case GetStyleBackground wouldn't have the right background
   // and the code in nsFrame::DisplayBorderBackgroundOutline might not give us
   // a background.
   // We don't have any border or outline, and our background draws over
   // the overflow area, so just add nsDisplayCanvasBackground instead of
   // calling DisplayBorderBackgroundOutline.
   if (IsVisibleForPainting(aBuilder)) { 
@@ -546,25 +512,16 @@ nsCanvasFrame::Reflow(nsPresContext*    
     } else {
       aDesiredSize.height = aReflowState.ComputedHeight();
     }
 
     aDesiredSize.SetOverflowAreasToDesiredBounds();
     aDesiredSize.mOverflowAreas.UnionWith(
       kidDesiredSize.mOverflowAreas + kidPt);
 
-    if (mAbsoluteContainer.HasAbsoluteFrames()) {
-      bool widthChanged = aDesiredSize.width != mRect.width;
-      bool heightChanged = aDesiredSize.height != mRect.height;
-      mAbsoluteContainer.Reflow(this, aPresContext, aReflowState, aStatus,
-                                aDesiredSize.width, aDesiredSize.height,
-                                PR_TRUE, widthChanged, heightChanged,
-                                &aDesiredSize.mOverflowAreas);
-    }
-
     // Handle invalidating fixed-attachment backgrounds propagated to the
     // canvas when the canvas size (and therefore the background positioning
     // area's size) changes.  Such backgrounds are not invalidated in the
     // normal manner because the size of the original frame for that background
     // may not have changed.
     //
     // This isn't the right fix for this issue, taken more generally.  In
     // particular, this doesn't handle fixed-attachment backgrounds that are *not*
@@ -595,17 +552,17 @@ nsCanvasFrame::Reflow(nsPresContext*    
   }
 
   if (prevCanvasFrame) {
     ReflowOverflowContainerChildren(aPresContext, aReflowState,
                                     aDesiredSize.mOverflowAreas, 0,
                                     aStatus);
   }
 
-  FinishAndStoreOverflow(&aDesiredSize);
+  FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus);
 
   NS_FRAME_TRACE_REFLOW_OUT("nsCanvasFrame::Reflow", aStatus);
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
   return NS_OK;
 }
 
 PRIntn
 nsCanvasFrame::GetSkipSides() const
--- a/layout/generic/nsCanvasFrame.h
+++ b/layout/generic/nsCanvasFrame.h
@@ -37,17 +37,16 @@
 
 /* rendering object that goes directly inside the document's scrollbars */
 
 #ifndef nsCanvasFrame_h___
 #define nsCanvasFrame_h___
 
 #include "nsHTMLContainerFrame.h"
 #include "nsIScrollPositionListener.h"
-#include "nsAbsoluteContainingBlock.h"
 #include "nsDisplayList.h"
 #include "nsGkAtoms.h"
 
 class nsPresContext;
 class nsRenderingContext;
 class nsEvent;
 
 /**
@@ -59,18 +58,17 @@ class nsEvent;
  */
 class nsCanvasFrame : public nsHTMLContainerFrame,
                       public nsIScrollPositionListener
 {
 public:
   nsCanvasFrame(nsStyleContext* aContext)
   : nsHTMLContainerFrame(aContext),
     mDoPaintFocus(PR_FALSE),
-    mAddedScrollPositionListener(PR_FALSE),
-    mAbsoluteContainer(kAbsoluteList) {}
+    mAddedScrollPositionListener(false) {}
 
   NS_DECL_QUERYFRAME_TARGET(nsCanvasFrame)
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
 
   virtual void DestroyFrom(nsIFrame* aDestructRoot);
 
@@ -79,26 +77,22 @@ public:
   NS_IMETHOD AppendFrames(ChildListID     aListID,
                           nsFrameList&    aFrameList);
   NS_IMETHOD InsertFrames(ChildListID     aListID,
                           nsIFrame*       aPrevFrame,
                           nsFrameList&    aFrameList);
   NS_IMETHOD RemoveFrame(ChildListID     aListID,
                          nsIFrame*       aOldFrame);
 
-  virtual nsFrameList GetChildList(ChildListID aListID) const;
-  virtual void GetChildLists(nsTArray<ChildList>* aLists) const;
-
   virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext);
   virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext);
   NS_IMETHOD Reflow(nsPresContext*          aPresContext,
                     nsHTMLReflowMetrics&     aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
                     nsReflowStatus&          aStatus);
-  virtual bool IsContainingBlock() const { return true; }
   virtual bool IsFrameOfType(PRUint32 aFlags) const
   {
     return nsHTMLContainerFrame::IsFrameOfType(aFlags &
              ~(nsIFrame::eCanContainOverflowContainers));
   }
 
   /** SetHasFocus tells the CanvasFrame to draw with focus ring
    *  @param aHasFocus PR_TRUE to show focus ring, PR_FALSE to hide it
@@ -146,17 +140,16 @@ public:
   nsRect CanvasArea() const;
 
 protected:
   virtual PRIntn GetSkipSides() const;
 
   // Data members
   bool                      mDoPaintFocus;
   bool                      mAddedScrollPositionListener;
-  nsAbsoluteContainingBlock mAbsoluteContainer;
 };
 
 /**
  * Override nsDisplayBackground methods so that we pass aBGClipRect to
  * PaintBackground, covering the whole overflow area.
  * We can also paint an "extra background color" behind the normal
  * background.
  */
--- a/layout/generic/nsColumnSetFrame.cpp
+++ b/layout/generic/nsColumnSetFrame.cpp
@@ -69,16 +69,17 @@ public:
   NS_IMETHOD  AppendFrames(ChildListID     aListID,
                            nsFrameList&    aFrameList);
   NS_IMETHOD  InsertFrames(ChildListID     aListID,
                            nsIFrame*       aPrevFrame,
                            nsFrameList&    aFrameList);
   NS_IMETHOD  RemoveFrame(ChildListID     aListID,
                           nsIFrame*       aOldFrame);
 
+  virtual void DestroyFrom(nsIFrame* aDestructRoot);
   virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext);  
   virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext);
 
   virtual nsIFrame* GetContentInsertionFrame() {
     nsIFrame* frame = GetFirstPrincipalChild();
 
     // if no children return nsnull
     if (!frame)
@@ -197,16 +198,23 @@ NS_NewColumnSetFrame(nsIPresShell* aPres
 NS_IMPL_FRAMEARENA_HELPERS(nsColumnSetFrame)
 
 nsColumnSetFrame::nsColumnSetFrame(nsStyleContext* aContext)
   : nsHTMLContainerFrame(aContext), mLastBalanceHeight(NS_INTRINSICSIZE),
     mLastFrameStatus(NS_FRAME_COMPLETE)
 {
 }
 
+void
+nsColumnSetFrame::DestroyFrom(nsIFrame* aDestructRoot)
+{
+  DestroyAbsoluteFrames(aDestructRoot);
+  nsHTMLContainerFrame::DestroyFrom(aDestructRoot);
+}
+
 nsIAtom*
 nsColumnSetFrame::GetType() const
 {
   return nsGkAtoms::columnSetFrame;
 }
 
 static void
 PaintColumnRule(nsIFrame* aFrame, nsRenderingContext* aCtx,
@@ -1064,17 +1072,17 @@ nsColumnSetFrame::Reflow(nsPresContext* 
       aReflowState.availableHeight == NS_UNCONSTRAINEDSIZE) {
     // In this situation, we might be lying about our reflow status, because
     // our last kid (the one that got interrupted) was incomplete.  Fix that.
     aStatus = NS_FRAME_COMPLETE;
   }
   
   CheckInvalidateSizeChange(aDesiredSize);
 
-  FinishAndStoreOverflow(&aDesiredSize);
+  FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus);
   aDesiredSize.mCarriedOutBottomMargin = carriedOutBottomMargin;
 
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
 
   NS_ASSERTION(NS_FRAME_IS_FULLY_COMPLETE(aStatus) ||
                aReflowState.availableHeight != NS_UNCONSTRAINEDSIZE,
                "Column set should be complete if the available height is unconstrained");
 
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -340,16 +340,17 @@ nsContainerFrame::GetChildLists(nsTArray
   ::AppendIfNonempty(this, propTable, OverflowProperty(),
                      aLists, kOverflowList);
   if (IsFrameOfType(nsIFrame::eCanContainOverflowContainers)) {
     ::AppendIfNonempty(this, propTable, OverflowContainersProperty(),
                        aLists, kOverflowContainersList);
     ::AppendIfNonempty(this, propTable, ExcessOverflowContainersProperty(),
                        aLists, kExcessOverflowContainersList);
   }
+  nsSplittableFrame::GetChildLists(aLists);
 }
 
 /////////////////////////////////////////////////////////////////////////////
 // Painting/Events
 
 NS_IMETHODIMP
 nsContainerFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                    const nsRect&           aDirtyRect,
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -115,16 +115,17 @@
 #include "nsIObjectLoadingContent.h"
 #include "nsExpirationTracker.h"
 #include "nsSVGIntegrationUtils.h"
 #include "nsSVGEffects.h"
 #include "nsChangeHint.h"
 
 #include "gfxContext.h"
 #include "CSSCalc.h"
+#include "nsAbsoluteContainingBlock.h"
 
 #include "mozilla/Preferences.h"
 #include "mozilla/LookAndFeel.h"
 
 using namespace mozilla;
 using namespace mozilla::layers;
 
 // Struct containing cached metrics for box-wrapped frames.
@@ -246,16 +247,44 @@ nsFrame::RootFrameList(nsPresContext* aP
     nsIFrame* frame = shell->FrameManager()->GetRootFrame();
     if(frame) {
       frame->List(out, aIndent);
     }
   }
 }
 #endif
 
+static void
+DestroyAbsoluteContainingBlock(void* aPropertyValue)
+{
+  delete static_cast<nsAbsoluteContainingBlock*>(aPropertyValue);
+}
+
+NS_DECLARE_FRAME_PROPERTY(AbsoluteContainingBlockProperty, DestroyAbsoluteContainingBlock)
+
+bool
+nsIFrame::HasAbsolutelyPositionedChildren() const {
+  return IsAbsoluteContainer() && GetAbsoluteContainingBlock()->HasAbsoluteFrames();
+}
+
+nsAbsoluteContainingBlock*
+nsIFrame::GetAbsoluteContainingBlock() const {
+  NS_ASSERTION(IsAbsoluteContainer(), "The frame is not marked as an abspos container correctly");
+  nsAbsoluteContainingBlock* absCB = static_cast<nsAbsoluteContainingBlock*>
+    (Properties().Get(AbsoluteContainingBlockProperty()));
+  NS_ASSERTION(absCB, "The frame is marked as an abspos container but doesn't have the property");
+  return absCB;
+}
+
+void
+nsIFrame::MarkAsAbsoluteContainingBlock() {
+  AddStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN);
+  Properties().Set(AbsoluteContainingBlockProperty(), new nsAbsoluteContainingBlock(GetAbsoluteListID()));
+}
+
 static bool ApplyOverflowClipping(nsDisplayListBuilder* aBuilder,
                                     const nsIFrame* aFrame,
                                     const nsStyleDisplay* aDisp, 
                                     nsRect* aRect);
 
 static bool ApplyAbsPosClipping(nsDisplayListBuilder* aBuilder,
                                   const nsStyleDisplay* aDisp, 
                                   const nsIFrame* aFrame,
@@ -992,16 +1021,36 @@ nsFrame::GetBaseline() const
 {
   NS_ASSERTION(!NS_SUBTREE_DIRTY(this),
                "frame must not be dirty");
   // Default to the bottom margin edge, per CSS2.1's definition of the
   // 'baseline' value of 'vertical-align'.
   return mRect.height + GetUsedMargin().bottom;
 }
 
+nsFrameList
+nsFrame::GetChildList(ChildListID aListID) const
+{
+  if (IsAbsoluteContainer() &&
+      aListID == GetAbsoluteListID()) {
+    return GetAbsoluteContainingBlock()->GetChildList();
+  } else {
+    return nsFrameList::EmptyList();
+  }
+}
+
+void
+nsFrame::GetChildLists(nsTArray<ChildList>* aLists) const
+{
+  if (IsAbsoluteContainer()) {
+    nsFrameList absoluteList = GetAbsoluteContainingBlock()->GetChildList();
+    absoluteList.AppendIfNonempty(aLists, GetAbsoluteListID());
+  }
+}
+
 static nsIFrame*
 GetActiveSelectionFrame(nsPresContext* aPresContext, nsIFrame* aFrame)
 {
   nsIContent* capturingContent = nsIPresShell::GetCapturingContent();
   if (capturingContent) {
     nsIFrame* activeFrame = aPresContext->GetPrimaryFrameFor(capturingContent);
     return activeFrame ? activeFrame : aFrame;
   }
@@ -1562,16 +1611,19 @@ nsIFrame::BuildDisplayListForStackingCon
   }
 
   bool usingSVGEffects = nsSVGIntegrationUtils::UsingEffectsForFrame(this);
   if (usingSVGEffects) {
     dirtyRect =
       nsSVGIntegrationUtils::GetRequiredSourceForInvalidArea(this, dirtyRect);
   }
 
+  // Mark the display list items for absolutely positioned children
+  MarkAbsoluteFramesForDisplayList(aBuilder, aDirtyRect);
+
   nsDisplayListCollection set;
   nsresult rv;
   {    
     nsDisplayListBuilder::AutoIsRootSetter rootSetter(aBuilder, PR_TRUE);
     nsDisplayListBuilder::AutoInTransformSetter
       inTransformSetter(aBuilder, inTransform);
     rv = BuildDisplayList(aBuilder, dirtyRect, set);
   }
@@ -1722,25 +1774,24 @@ nsIFrame::BuildDisplayListForChild(nsDis
                                    PRUint32                aFlags) {
   // If painting is restricted to just the background of the top level frame,
   // then we have nothing to do here.
   if (aBuilder->IsBackgroundOnly())
     return NS_OK;
 
   if (aChild->GetStateBits() & NS_FRAME_TOO_DEEP_IN_FRAME_TREE)
     return NS_OK;
-  
+
   const nsStyleDisplay* disp = aChild->GetStyleDisplay();
   // PR_TRUE if this is a real or pseudo stacking context
   bool pseudoStackingContext =
     (aFlags & DISPLAY_CHILD_FORCE_PSEUDO_STACKING_CONTEXT) != 0;
   // XXX we REALLY need a "are you an inline-block sort of thing?" here!!!
   if ((aFlags & DISPLAY_CHILD_INLINE) &&
       (disp->mDisplay != NS_STYLE_DISPLAY_INLINE ||
-       aChild->IsContainingBlock() ||
        (aChild->IsFrameOfType(eReplaced)))) {
     // child is a non-inline frame in an inline context, i.e.,
     // it acts like inline-block or inline-table. Therefore it is a
     // pseudo-stacking-context.
     pseudoStackingContext = PR_TRUE;
   }
 
   // dirty rect in child-relative coordinates
@@ -1768,19 +1819,25 @@ nsIFrame::BuildDisplayListForChild(nsDis
       dirty = *savedDirty;
     } else {
       // The out-of-flow frame did not intersect the dirty area. We may still
       // need to traverse into it, since it may contain placeholders we need
       // to enter to reach other out-of-flow frames that are visible.
       dirty.SetEmpty();
     }
     pseudoStackingContext = PR_TRUE;
-  } else if (aBuilder->GetSelectedFramesOnly() &&
-             aChild->IsLeaf() &&
-             !(aChild->GetStateBits() & NS_FRAME_SELECTED_CONTENT)) {
+  }
+
+  // Mark the display list items for absolutely positioned children
+  aChild->MarkAbsoluteFramesForDisplayList(aBuilder, dirty);
+
+  if (childType != nsGkAtoms::placeholderFrame &&
+      aBuilder->GetSelectedFramesOnly() &&
+      aChild->IsLeaf() &&
+      !(aChild->GetStateBits() & NS_FRAME_SELECTED_CONTENT)) {
     return NS_OK;
   }
 
   if (aBuilder->GetIncludeAllOutOfFlows() &&
       (aChild->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
     dirty = aChild->GetVisualOverflowRect();
   } else if (!(aChild->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO)) {
     // No need to descend into aChild to catch placeholders for visible
@@ -1935,16 +1992,25 @@ nsIFrame::BuildDisplayListForChild(nsDis
   // This doesn't affect correctness because the positioned descendants list
   // is sorted by z-order and content in BuildDisplayListForStackingContext,
   // but it means that sort routine needs to do less work.
   aLists.PositionedDescendants()->AppendToTop(&extraPositionedDescendants);
   return NS_OK;
 }
 
 void
+nsIFrame::MarkAbsoluteFramesForDisplayList(nsDisplayListBuilder* aBuilder,
+                                           const nsRect& aDirtyRect)
+{
+  if (IsAbsoluteContainer()) {
+    aBuilder->MarkFramesForDisplayList(this, GetAbsoluteContainingBlock()->GetChildList(), aDirtyRect);
+  }
+}
+
+void
 nsIFrame::WrapReplacedContentForBorderRadius(nsDisplayListBuilder* aBuilder,
                                              nsDisplayList* aFromList,
                                              const nsDisplayListSet& aToLists)
 {
   nscoord radii[8];
   if (GetContentBoxBorderRadii(radii)) {
     // If we have a border-radius, we have to clip our content to that
     // radius.
@@ -3681,16 +3747,17 @@ nsFrame::WillReflow(nsPresContext* aPres
 
 NS_IMETHODIMP
 nsFrame::DidReflow(nsPresContext*           aPresContext,
                    const nsHTMLReflowState*  aReflowState,
                    nsDidReflowStatus         aStatus)
 {
   NS_FRAME_TRACE_MSG(NS_FRAME_TRACE_CALLS,
                      ("nsFrame::DidReflow: aStatus=%d", aStatus));
+
   if (NS_FRAME_REFLOW_FINISHED == aStatus) {
     mState &= ~(NS_FRAME_IN_REFLOW | NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY |
                 NS_FRAME_HAS_DIRTY_CHILDREN);
   }
 
   // Notify the percent height observer if there is a percent height.
   // The observer may be able to initiate another reflow with a computed
   // height. This happens in the case where a table cell has no computed
@@ -3701,16 +3768,65 @@ nsFrame::DidReflow(nsPresContext*       
     if (height.HasPercent()) {
       aReflowState->mPercentHeightObserver->NotifyPercentHeight(*aReflowState);
     }
   }
 
   return NS_OK;
 }
 
+void
+nsFrame::FinishReflowWithAbsoluteFrames(nsPresContext*           aPresContext,
+                                        nsHTMLReflowMetrics&     aDesiredSize,
+                                        const nsHTMLReflowState& aReflowState,
+                                        nsReflowStatus&          aStatus)
+{
+  ReflowAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus);
+
+  FinishAndStoreOverflow(&aDesiredSize);
+}
+
+void
+nsFrame::DestroyAbsoluteFrames(nsIFrame* aDestructRoot)
+{
+  if (IsAbsoluteContainer()) {
+    GetAbsoluteContainingBlock()->DestroyFrames(this, aDestructRoot);
+  }
+}
+
+void
+nsFrame::ReflowAbsoluteFrames(nsPresContext*           aPresContext,
+                              nsHTMLReflowMetrics&     aDesiredSize,
+                              const nsHTMLReflowState& aReflowState,
+                              nsReflowStatus&          aStatus)
+{
+  if (HasAbsolutelyPositionedChildren()) {
+    nsAbsoluteContainingBlock* absoluteContainer = GetAbsoluteContainingBlock();
+
+    // Let the absolutely positioned container reflow any absolutely positioned
+    // child frames that need to be reflowed
+
+    // The containing block for the abs pos kids is formed by our padding edge.
+    nsMargin computedBorder =
+      aReflowState.mComputedBorderPadding - aReflowState.mComputedPadding;
+    nscoord containingBlockWidth =
+      aDesiredSize.width - computedBorder.LeftRight();
+    nscoord containingBlockHeight =
+      aDesiredSize.height - computedBorder.TopBottom();
+
+    nsContainerFrame* container = do_QueryFrame(this);
+    NS_ASSERTION(container, "Abs-pos children only supported on container frames for now");
+
+    absoluteContainer->Reflow(container, aPresContext, aReflowState, aStatus,
+                              containingBlockWidth, containingBlockHeight,
+                              true, true, true, // XXX could be optimized
+                              &aDesiredSize.mOverflowAreas);
+  }
+}
+
 /* virtual */ bool
 nsFrame::CanContinueTextRun() const
 {
   // By default, a frame will *not* allow a text run to be continued
   // through it.
   return PR_FALSE;
 }
 
@@ -4783,26 +4899,53 @@ nsFrame::IsFrameTreeTooDeep(const nsHTML
     }
 
     return PR_TRUE;
   }
   mState &= ~NS_FRAME_TOO_DEEP_IN_FRAME_TREE;
   return PR_FALSE;
 }
 
-/* virtual */ bool nsFrame::IsContainingBlock() const
-{
-  const nsStyleDisplay* display = GetStyleDisplay();
-
-  // Absolute positioning causes |display->mDisplay| to be set to block,
-  // if needed.
-  return display->mDisplay == NS_STYLE_DISPLAY_BLOCK || 
-         display->mDisplay == NS_STYLE_DISPLAY_INLINE_BLOCK || 
-         display->mDisplay == NS_STYLE_DISPLAY_LIST_ITEM ||
-         display->mDisplay == NS_STYLE_DISPLAY_TABLE_CELL;
+bool
+nsIFrame::IsBlockWrapper() const
+{
+  nsIAtom *pseudoType = GetStyleContext()->GetPseudo();
+  return (pseudoType == nsCSSAnonBoxes::mozAnonymousBlock ||
+          pseudoType == nsCSSAnonBoxes::mozAnonymousPositionedBlock ||
+          pseudoType == nsCSSAnonBoxes::cellContent);
+}
+
+static nsIFrame*
+GetNearestBlockContainer(nsIFrame* frame)
+{
+  // The block wrappers we use to wrap blocks inside inlines aren't
+  // described in the CSS spec.  We need to make them not be containing
+  // blocks.
+  // Since the parent of such a block is either a normal block or
+  // another such pseudo, this shouldn't cause anything bad to happen.
+  // Also the anonymous blocks inside table cells are not containing blocks.
+  while (frame->IsFrameOfType(nsIFrame::eLineParticipant) ||
+         frame->IsBlockWrapper()) {
+    frame = frame->GetParent();
+    NS_ASSERTION(frame, "How come we got to the root frame without seeing a containing block?");
+  }
+  return frame;
+}
+
+nsIFrame*
+nsIFrame::GetContainingBlock() const
+{
+  // MathML frames might have absolute positioning style, but they would
+  // still be in-flow.  So we have to check to make sure that the frame
+  // is really out-of-flow too.
+  if (GetStyleDisplay()->IsAbsolutelyPositioned() &&
+      (GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
+    return GetParent(); // the parent is always the containing block
+  }
+  return GetNearestBlockContainer(GetParent());
 }
 
 #ifdef NS_DEBUG
 
 PRInt32 nsFrame::ContentIndexInContainer(const nsIFrame* aFrame)
 {
   PRInt32 result = -1;
 
@@ -6315,18 +6458,17 @@ nsIFrame::SetOverflowAreas(const nsOverf
     *overflow = aOverflowAreas;
   }
 }
 
 inline bool
 IsInlineFrame(nsIFrame *aFrame)
 {
   nsIAtom *type = aFrame->GetType();
-  return type == nsGkAtoms::inlineFrame ||
-         type == nsGkAtoms::positionedInlineFrame;
+  return type == nsGkAtoms::inlineFrame;
 }
 
 void 
 nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas,
                                  nsSize aNewSize)
 {
   nsRect bounds(nsPoint(0, 0), aNewSize);
 
@@ -8040,17 +8182,16 @@ void DR_State::InitFrameTypeTable()
   AddFrameTypeInfo(nsGkAtoms::imageFrame,            "img",       "image");
   AddFrameTypeInfo(nsGkAtoms::inlineFrame,           "inline",    "inline");
   AddFrameTypeInfo(nsGkAtoms::letterFrame,           "letter",    "letter");
   AddFrameTypeInfo(nsGkAtoms::lineFrame,             "line",      "line");
   AddFrameTypeInfo(nsGkAtoms::listControlFrame,      "select",    "select");
   AddFrameTypeInfo(nsGkAtoms::objectFrame,           "obj",       "object");
   AddFrameTypeInfo(nsGkAtoms::pageFrame,             "page",      "page");
   AddFrameTypeInfo(nsGkAtoms::placeholderFrame,      "place",     "placeholder");
-  AddFrameTypeInfo(nsGkAtoms::positionedInlineFrame, "posInline", "positionedInline");
   AddFrameTypeInfo(nsGkAtoms::canvasFrame,           "canvas",    "canvas");
   AddFrameTypeInfo(nsGkAtoms::rootFrame,             "root",      "root");
   AddFrameTypeInfo(nsGkAtoms::scrollFrame,           "scroll",    "scroll");
   AddFrameTypeInfo(nsGkAtoms::tableCaptionFrame,     "caption",   "tableCaption");
   AddFrameTypeInfo(nsGkAtoms::tableCellFrame,        "cell",      "tableCell");
   AddFrameTypeInfo(nsGkAtoms::bcTableCellFrame,      "bcCell",    "bcTableCell");
   AddFrameTypeInfo(nsGkAtoms::tableColFrame,         "col",       "tableCol");
   AddFrameTypeInfo(nsGkAtoms::tableColGroupFrame,    "colG",      "tableColGroup");
--- a/layout/generic/nsFrame.h
+++ b/layout/generic/nsFrame.h
@@ -185,20 +185,18 @@ public:
   NS_IMETHOD  RemoveFrame(ChildListID     aListID,
                           nsIFrame*       aOldFrame);
   virtual void DestroyFrom(nsIFrame* aDestructRoot);
   virtual nsStyleContext* GetAdditionalStyleContext(PRInt32 aIndex) const;
   virtual void SetAdditionalStyleContext(PRInt32 aIndex,
                                          nsStyleContext* aStyleContext);
   virtual void SetParent(nsIFrame* aParent);
   virtual nscoord GetBaseline() const;
-  virtual nsFrameList GetChildList(ChildListID aListID) const {
-    return nsFrameList::EmptyList();
-  }
-  virtual void GetChildLists(nsTArray<ChildList>* aLists) const {}
+  virtual nsFrameList GetChildList(ChildListID aListID) const;
+  virtual void GetChildLists(nsTArray<ChildList>* aLists) const;
 
   NS_IMETHOD  HandleEvent(nsPresContext* aPresContext, 
                           nsGUIEvent*     aEvent,
                           nsEventStatus*  aEventStatus);
   NS_IMETHOD  GetContentForEvent(nsEvent* aEvent,
                                  nsIContent** aContent);
   NS_IMETHOD  GetCursor(const nsPoint&    aPoint,
                         nsIFrame::Cursor& aCursor);
@@ -228,17 +226,16 @@ public:
   virtual nsIFrame* GetNextContinuation() const;
   NS_IMETHOD  SetNextContinuation(nsIFrame*);
   virtual nsIFrame* GetPrevInFlowVirtual() const;
   NS_IMETHOD  SetPrevInFlow(nsIFrame*);
   virtual nsIFrame* GetNextInFlowVirtual() const;
   NS_IMETHOD  SetNextInFlow(nsIFrame*);
   NS_IMETHOD  GetOffsetFromView(nsPoint& aOffset, nsIView** aView) const;
   virtual nsIAtom* GetType() const;
-  virtual bool IsContainingBlock() const;
 
   NS_IMETHOD  GetSelected(bool *aSelected) const;
   NS_IMETHOD  IsSelectable(bool* aIsSelectable, PRUint8* aSelectStyle) const;
 
   NS_IMETHOD  GetSelectionController(nsPresContext *aPresContext, nsISelectionController **aSelCon);
 
   virtual bool PeekOffsetNoAmount(bool aForward, PRInt32* aOffset);
   virtual bool PeekOffsetCharacter(bool aForward, PRInt32* aOffset,
@@ -334,16 +331,25 @@ public:
   NS_IMETHOD  WillReflow(nsPresContext* aPresContext);
   NS_IMETHOD  Reflow(nsPresContext*          aPresContext,
                      nsHTMLReflowMetrics&     aDesiredSize,
                      const nsHTMLReflowState& aReflowState,
                      nsReflowStatus&          aStatus);
   NS_IMETHOD  DidReflow(nsPresContext*           aPresContext,
                         const nsHTMLReflowState*  aReflowState,
                         nsDidReflowStatus         aStatus);
+  void ReflowAbsoluteFrames(nsPresContext*           aPresContext,
+                            nsHTMLReflowMetrics&     aDesiredSize,
+                            const nsHTMLReflowState& aReflowState,
+                            nsReflowStatus&          aStatus);
+  void FinishReflowWithAbsoluteFrames(nsPresContext*           aPresContext,
+                                      nsHTMLReflowMetrics&     aDesiredSize,
+                                      const nsHTMLReflowState& aReflowState,
+                                      nsReflowStatus&          aStatus);
+  void DestroyAbsoluteFrames(nsIFrame* aDestructRoot);
   virtual bool CanContinueTextRun() const;
 
   // Selection Methods
   // XXX Doc me... (in nsIFrame.h puhleeze)
   // XXX If these are selection specific, then the name should imply selection
   // rather than generic event processing, e.g., SelectionHandlePress...
   NS_IMETHOD HandlePress(nsPresContext* aPresContext,
                          nsGUIEvent *    aEvent,
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -116,16 +116,17 @@ nsHTMLScrollFrame::AppendAnonymousConten
 {
   mInner.AppendAnonymousContentTo(aElements, aFilter);
 }
 
 void
 nsHTMLScrollFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
   mInner.Destroy();
+  DestroyAbsoluteFrames(aDestructRoot);
   nsHTMLContainerFrame::DestroyFrom(aDestructRoot);
 }
 
 NS_IMETHODIMP
 nsHTMLScrollFrame::SetInitialChildList(ChildListID  aListID,
                                        nsFrameList& aChildList)
 {
   nsresult rv = nsHTMLContainerFrame::SetInitialChildList(aListID, aChildList);
@@ -922,17 +923,17 @@ nsHTMLScrollFrame::Reflow(nsPresContext*
     state.mComputedBorder.LeftRight();
   aDesiredSize.height = state.mInsideBorderSize.height +
     state.mComputedBorder.TopBottom();
 
   aDesiredSize.SetOverflowAreasToDesiredBounds();
 
   CheckInvalidateSizeChange(aDesiredSize);
 
-  FinishAndStoreOverflow(&aDesiredSize);
+  FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus);
 
   if (!InInitialReflow() && !mInner.mHadNonInitialReflow) {
     mInner.mHadNonInitialReflow = PR_TRUE;
   }
 
   if (mInner.mIsRoot && !oldScrolledAreaBounds.IsEqualEdges(newScrolledAreaBounds)) {
     mInner.PostScrolledAreaEvent();
   }
--- a/layout/generic/nsHTMLParts.h
+++ b/layout/generic/nsHTMLParts.h
@@ -134,18 +134,16 @@ nsIFrame*
 NS_NewViewportFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewCanvasFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewImageFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewInlineFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
-NS_NewPositionedInlineFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
-nsIFrame*
 NS_NewObjectFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewTextFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewContinuingTextFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewEmptyFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 inline nsIFrame*
--- a/layout/generic/nsHTMLReflowState.cpp
+++ b/layout/generic/nsHTMLReflowState.cpp
@@ -225,18 +225,19 @@ nsHTMLReflowState::SetComputedWidth(nsco
   //    state is not used to reflow the parent, but just as a parent for the
   //    frame's own reflow state.  So given a nsBoxFrame inside some non-XUL
   //    (like a text control, for example), we'll end up creating a reflow
   //    state for the parent while the parent is reflowing.
 
   NS_PRECONDITION(aComputedWidth >= 0, "Invalid computed width");
   if (mComputedWidth != aComputedWidth) {
     mComputedWidth = aComputedWidth;
-    if (frame->GetType() != nsGkAtoms::viewportFrame) { // Or check GetParent()?
-      InitResizeFlags(frame->PresContext());
+    nsIAtom* frameType = frame->GetType();
+    if (frameType != nsGkAtoms::viewportFrame) { // Or check GetParent()?
+      InitResizeFlags(frame->PresContext(), frameType);
     }
   }
 }
 
 void
 nsHTMLReflowState::SetComputedHeight(nscoord aComputedHeight)
 {
   NS_ASSERTION(frame, "Must have a frame!");
@@ -247,17 +248,17 @@ nsHTMLReflowState::SetComputedHeight(nsc
   //    state is not used to reflow the parent, but just as a parent for the
   //    frame's own reflow state.  So given a nsBoxFrame inside some non-XUL
   //    (like a text control, for example), we'll end up creating a reflow
   //    state for the parent while the parent is reflowing.
 
   NS_PRECONDITION(aComputedHeight >= 0, "Invalid computed height");
   if (mComputedHeight != aComputedHeight) {
     mComputedHeight = aComputedHeight;
-    InitResizeFlags(frame->PresContext());
+    InitResizeFlags(frame->PresContext(), frame->GetType());
   }
 }
 
 void
 nsHTMLReflowState::Init(nsPresContext* aPresContext,
                         nscoord         aContainingBlockWidth,
                         nscoord         aContainingBlockHeight,
                         const nsMargin* aBorder,
@@ -271,114 +272,102 @@ nsHTMLReflowState::Init(nsPresContext* a
   mStylePosition = frame->GetStylePosition();
   mStyleDisplay = frame->GetStyleDisplay();
   mStyleVisibility = frame->GetStyleVisibility();
   mStyleBorder = frame->GetStyleBorder();
   mStyleMargin = frame->GetStyleMargin();
   mStylePadding = frame->GetStylePadding();
   mStyleText = frame->GetStyleText();
 
-  InitFrameType();
+  nsIAtom* type = frame->GetType();
+
+  InitFrameType(type);
   InitCBReflowState();
 
-  InitConstraints(aPresContext, aContainingBlockWidth, aContainingBlockHeight, aBorder, aPadding);
+  InitConstraints(aPresContext, aContainingBlockWidth, aContainingBlockHeight,
+                  aBorder, aPadding, type);
 
-  InitResizeFlags(aPresContext);
+  InitResizeFlags(aPresContext, type);
 
   NS_WARN_IF_FALSE((mFrameType == NS_CSS_FRAME_TYPE_INLINE &&
                     !frame->IsFrameOfType(nsIFrame::eReplaced)) ||
-                   frame->GetType() == nsGkAtoms::textFrame ||
+                   type == nsGkAtoms::textFrame ||
                    mComputedWidth != NS_UNCONSTRAINEDSIZE,
                    "have unconstrained width; this should only result from "
                    "very large sizes, not attempts at intrinsic width "
                    "calculation");
 }
 
 void nsHTMLReflowState::InitCBReflowState()
 {
   if (!parentReflowState) {
     mCBReflowState = nsnull;
     return;
   }
 
-  // If outer tables ever become containing blocks, we need to make sure to use
-  // their mCBReflowState in the non-absolutely-positioned case for inner
-  // tables.
-  NS_ASSERTION(frame->GetType() != nsGkAtoms::tableFrame ||
-               !frame->GetParent()->IsContainingBlock(),
-               "Outer table should not be containing block");
-
-  if (parentReflowState->frame->IsContainingBlock() ||
-      // Absolutely positioned frames should always be kids of the frames that
-      // determine their containing block....
-      (NS_FRAME_GET_TYPE(mFrameType) == NS_CSS_FRAME_TYPE_ABSOLUTE)) {
-    // an absolutely positioned inner table needs to use the parent of
-    // the outer table.  So the above comment about absolutely
-    // positioned frames is sort of a lie.
-    if (parentReflowState->parentReflowState &&
-        frame->GetType() == nsGkAtoms::tableFrame) {
-      mCBReflowState = parentReflowState->parentReflowState;
+  if (parentReflowState->frame == frame->GetContainingBlock()) {
+    // Inner table frames need to use the containing block of the outer
+    // table frame.
+    if (frame->GetType() == nsGkAtoms::tableFrame) {
+      mCBReflowState = parentReflowState->mCBReflowState;
     } else {
       mCBReflowState = parentReflowState;
     }
-      
-    return;
+  } else {
+    mCBReflowState = parentReflowState->mCBReflowState;
   }
-  
-  mCBReflowState = parentReflowState->mCBReflowState;
 }
 
 /* Check whether CalcQuirkContainingBlockHeight would stop on the
  * given reflow state, using its block as a height.  (essentially 
  * returns false for any case in which CalcQuirkContainingBlockHeight 
  * has a "continue" in its main loop.)
  *
  * XXX Maybe refactor CalcQuirkContainingBlockHeight so it uses 
  * this function as well
  */
 static bool
-IsQuirkContainingBlockHeight(const nsHTMLReflowState* rs) 
+IsQuirkContainingBlockHeight(const nsHTMLReflowState* rs, nsIAtom* aFrameType)
 {
-  nsIAtom* frameType = rs->frame->GetType();
-  if (nsGkAtoms::blockFrame == frameType ||
+  if (nsGkAtoms::blockFrame == aFrameType ||
 #ifdef MOZ_XUL
-      nsGkAtoms::XULLabelFrame == frameType ||
+      nsGkAtoms::XULLabelFrame == aFrameType ||
 #endif
-      nsGkAtoms::scrollFrame == frameType) {
+      nsGkAtoms::scrollFrame == aFrameType) {
     // Note: This next condition could change due to a style change,
     // but that would cause a style reflow anyway, which means we're ok.
     if (NS_AUTOHEIGHT == rs->ComputedHeight()) {
       if (!rs->frame->GetStyleDisplay()->IsAbsolutelyPositioned()) {
         return PR_FALSE;
       }
     }
   }
   return PR_TRUE;
 }
 
 
 void
-nsHTMLReflowState::InitResizeFlags(nsPresContext* aPresContext)
+nsHTMLReflowState::InitResizeFlags(nsPresContext* aPresContext, nsIAtom* aFrameType)
 {
   mFlags.mHResize = !(frame->GetStateBits() & NS_FRAME_IS_DIRTY) &&
                     frame->GetSize().width !=
                       mComputedWidth + mComputedBorderPadding.LeftRight();
 
   // XXX Should we really need to null check mCBReflowState?  (We do for
   // at least nsBoxFrame).
-  if (IS_TABLE_CELL(frame->GetType()) &&
+  if (IS_TABLE_CELL(aFrameType) &&
       (mFlags.mSpecialHeightReflow ||
        (frame->GetFirstInFlow()->GetStateBits() &
          NS_TABLE_CELL_HAD_SPECIAL_REFLOW)) &&
       (frame->GetStateBits() & NS_FRAME_CONTAINS_RELATIVE_HEIGHT)) {
     // Need to set the bit on the cell so that
     // mCBReflowState->mFlags.mVResize is set correctly below when
     // reflowing descendant.
     mFlags.mVResize = PR_TRUE;
-  } else if (mCBReflowState && !frame->IsContainingBlock()) {
+  } else if (mCBReflowState && !nsLayoutUtils::IsNonWrapperBlock(frame)) {
     // XXX Is this problematic for relatively positioned inlines acting
     // as containing block for absolutely positioned elements?
     // Possibly; in that case we should at least be checking
     // NS_SUBTREE_DIRTY, I'd think.
     mFlags.mVResize = mCBReflowState->mFlags.mVResize;
   } else if (mComputedHeight == NS_AUTOHEIGHT) {
     if (eCompatibility_NavQuirks == aPresContext->CompatibilityMode() &&
         mCBReflowState) {
@@ -410,17 +399,17 @@ nsHTMLReflowState::InitResizeFlags(nsPre
   if (mStyleText->mLineHeight.GetUnit() == eStyleUnit_Enumerated) {
     NS_ASSERTION(mStyleText->mLineHeight.GetIntValue() ==
                  NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT,
                  "bad line-height value");
 
     // line-height depends on block height
     frame->AddStateBits(NS_FRAME_CONTAINS_RELATIVE_HEIGHT);
     // but only on containing blocks if this frame is not a suitable block
-    dependsOnCBHeight |= !frame->IsContainingBlock();
+    dependsOnCBHeight |= !nsLayoutUtils::IsNonWrapperBlock(frame);
   }
 
   // If we're the descendant of a table cell that performs special height
   // reflows and we could be the child that requires them, always set
   // the vertical resize in case this is the first pass before the
   // special height reflow.  However, don't do this if it actually is
   // the special height reflow, since in that case it will already be
   // set correctly above if we need it set.
@@ -458,17 +447,17 @@ nsHTMLReflowState::InitResizeFlags(nsPre
       // Keep track of whether we've hit the containing block, because
       // we need to go at least that far.
       if (rs == mCBReflowState) {
         hitCBReflowState = PR_TRUE;
       }
 
     } while (!hitCBReflowState ||
              (eCompatibility_NavQuirks == aPresContext->CompatibilityMode() &&
-              !IsQuirkContainingBlockHeight(rs)));
+              !IsQuirkContainingBlockHeight(rs, rs->frame->GetType())));
     // Note: We actually don't need to set the
     // NS_FRAME_CONTAINS_RELATIVE_HEIGHT bit for the cases
     // where we hit the early break statements in
     // CalcQuirkContainingBlockHeight. But it doesn't hurt
     // us to set the bit in these cases.
     
   }
   if (frame->GetStateBits() & NS_FRAME_IS_DIRTY) {
@@ -483,62 +472,48 @@ nscoord
 nsHTMLReflowState::GetContainingBlockContentWidth(const nsHTMLReflowState* aReflowState)
 {
   const nsHTMLReflowState* rs = aReflowState->mCBReflowState;
   if (!rs)
     return 0;
   return rs->mComputedWidth;
 }
 
-/* static */
-nsIFrame*
-nsHTMLReflowState::GetContainingBlockFor(const nsIFrame* aFrame)
-{
-  NS_PRECONDITION(aFrame, "Must have frame to work with");
-  nsIFrame* container = aFrame->GetParent();
-  if (aFrame->GetStyleDisplay()->IsAbsolutelyPositioned()) {
-    // Absolutely positioned frames are just kids of their containing
-    // blocks (which may happen to be inlines).
-    return container;
-  }
-  while (container && !container->IsContainingBlock()) {
-    container = container->GetParent();
-  }
-  return container;
-}
-
 void
-nsHTMLReflowState::InitFrameType()
+nsHTMLReflowState::InitFrameType(nsIAtom* aFrameType)
 {
   const nsStyleDisplay *disp = mStyleDisplay;
   nsCSSFrameType frameType;
 
   // Section 9.7 of the CSS2 spec indicates that absolute position
   // takes precedence over float which takes precedence over display.
   // XXXldb nsRuleNode::ComputeDisplayData should take care of this, right?
   // Make sure the frame was actually moved out of the flow, and don't
 
   // just assume what the style says, because we might not have had a
   // useful float/absolute containing block
-  nsIFrame* frameToTest =
-    frame->GetType() == nsGkAtoms::tableFrame ? frame->GetParent() : frame;
+
+  DISPLAY_INIT_TYPE(frame, this);
 
-  DISPLAY_INIT_TYPE(frameToTest, this);
+  if (aFrameType == nsGkAtoms::tableFrame) {
+    mFrameType = NS_CSS_FRAME_TYPE_BLOCK;
+    return;
+  }
 
-  NS_ASSERTION(frameToTest->GetStyleDisplay()->IsAbsolutelyPositioned() ==
+  NS_ASSERTION(frame->GetStyleDisplay()->IsAbsolutelyPositioned() ==
                  disp->IsAbsolutelyPositioned(),
                "Unexpected position style");
-  NS_ASSERTION(frameToTest->GetStyleDisplay()->IsFloating() ==
+  NS_ASSERTION(frame->GetStyleDisplay()->IsFloating() ==
                  disp->IsFloating(), "Unexpected float style");
-  if (frameToTest->GetStateBits() & NS_FRAME_OUT_OF_FLOW) {
+  if (frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) {
     if (disp->IsAbsolutelyPositioned()) {
       frameType = NS_CSS_FRAME_TYPE_ABSOLUTE;
       //XXXfr hack for making frames behave properly when in overflow container lists
       //      see bug 154892; need to revisit later
-      if (frameToTest->GetPrevInFlow())
+      if (frame->GetPrevInFlow())
         frameType = NS_CSS_FRAME_TYPE_BLOCK;
     }
     else if (disp->IsFloating()) {
       frameType = NS_CSS_FRAME_TYPE_FLOATING;
     } else {
       NS_ASSERTION(disp->mDisplay == NS_STYLE_DISPLAY_POPUP,
                    "unknown out of flow frame type");
       frameType = NS_CSS_FRAME_TYPE_UNKNOWN;
@@ -693,32 +668,22 @@ nsHTMLReflowState::ComputeRelativeOffset
   if (offsets) {
     offsets->MoveTo(mComputedOffsets.left, mComputedOffsets.top);
   } else {
     props.Set(nsIFrame::ComputedOffsetProperty(),
               new nsPoint(mComputedOffsets.left, mComputedOffsets.top));
   }
 }
 
-static nsIFrame*
-GetNearestContainingBlock(nsIFrame *aFrame)
-{
-  nsIFrame *cb = aFrame;
-  do {
-    cb = cb->GetParent();
-  } while (!cb->IsContainingBlock());
-  return cb;
-}
-
 nsIFrame*
 nsHTMLReflowState::GetHypotheticalBoxContainer(nsIFrame* aFrame,
                                                nscoord& aCBLeftEdge,
                                                nscoord& aCBWidth)
 {
-  aFrame = GetNearestContainingBlock(aFrame);
+  aFrame = aFrame->GetContainingBlock();
   NS_ASSERTION(aFrame != frame, "How did that happen?");
 
   /* Now aFrame is the containing block we want */
 
   /* Check whether the containing block is currently being reflowed.
      If so, use the info from the reflow state. */
   const nsHTMLReflowState* state;
   if (aFrame->GetStateBits() & NS_FRAME_IN_REFLOW) {
@@ -765,26 +730,26 @@ struct nsHypotheticalBox {
   nsHypotheticalBox() {
 #ifdef DEBUG
     mLeftIsExact = mRightIsExact = PR_FALSE;
 #endif
   }
 };
       
 static bool
-GetIntrinsicSizeFor(nsIFrame* aFrame, nsSize& aIntrinsicSize)
+GetIntrinsicSizeFor(nsIFrame* aFrame, nsSize& aIntrinsicSize, nsIAtom* aFrameType)
 {
   // See if it is an image frame
   bool success = false;
 
   // Currently the only type of replaced frame that we can get the intrinsic
   // size for is an image frame
   // XXX We should add back the GetReflowMetrics() function and one of the
   // things should be the intrinsic size...
-  if (aFrame->GetType() == nsGkAtoms::imageFrame) {
+  if (aFrameType == nsGkAtoms::imageFrame) {
     nsImageFrame* imageFrame = (nsImageFrame*)aFrame;
 
     if (NS_SUCCEEDED(imageFrame->GetIntrinsicImageSize(aIntrinsicSize))) {
       success = (aIntrinsicSize != nsSize(0, 0));
     }
   }
   return success;
 }
@@ -882,30 +847,31 @@ static bool AreAllEarlierInFlowFramesEmp
 // cbrs->frame is the actual containing block
 void
 nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext*    aPresContext,
                                             nsIFrame*         aPlaceholderFrame,
                                             nsIFrame*         aContainingBlock,
                                             nscoord           aBlockLeftContentEdge,
                                             nscoord           aBlockContentWidth,
                                             const nsHTMLReflowState* cbrs,
-                                            nsHypotheticalBox& aHypotheticalBox)
+                                            nsHypotheticalBox& aHypotheticalBox,
+                                            nsIAtom*          aFrameType)
 {
   NS_ASSERTION(mStyleDisplay->mOriginalDisplay != NS_STYLE_DISPLAY_NONE,
                "mOriginalDisplay has not been properly initialized");
   
   // If it's a replaced element and it has a 'auto' value for 'width', see if we
   // can get the intrinsic size. This will allow us to exactly determine both the
   // left and right edges
   bool isAutoWidth = mStylePosition->mWidth.GetUnit() == eStyleUnit_Auto;
   nsSize      intrinsicSize;
   bool        knowIntrinsicSize = false;
   if (NS_FRAME_IS_REPLACED(mFrameType) && isAutoWidth) {
     // See if we can get the intrinsic size of the element
-    knowIntrinsicSize = GetIntrinsicSizeFor(frame, intrinsicSize);
+    knowIntrinsicSize = GetIntrinsicSizeFor(frame, intrinsicSize, aFrameType);
   }
 
   // See if we can calculate what the box width would have been if the
   // element had been in the flow
   nscoord boxWidth;
   bool    knowBoxWidth = false;
   if ((NS_STYLE_DISPLAY_INLINE == mStyleDisplay->mOriginalDisplay) &&
       !NS_FRAME_IS_REPLACED(mFrameType)) {
@@ -1122,30 +1088,31 @@ nsHTMLReflowState::CalculateHypothetical
   aHypotheticalBox.mRight -= border.left;
   aHypotheticalBox.mTop -= border.top;
 }
 
 void
 nsHTMLReflowState::InitAbsoluteConstraints(nsPresContext* aPresContext,
                                            const nsHTMLReflowState* cbrs,
                                            nscoord containingBlockWidth,
-                                           nscoord containingBlockHeight)
+                                           nscoord containingBlockHeight,
+                                           nsIAtom* aFrameType)
 {
   NS_PRECONDITION(containingBlockHeight != NS_AUTOHEIGHT,
                   "containing block height must be constrained");
 
-  nsIFrame* outOfFlow = 
-    frame->GetType() == nsGkAtoms::tableFrame ? frame->GetParent() : frame;
-  NS_ASSERTION(outOfFlow->GetStateBits() & NS_FRAME_OUT_OF_FLOW,
+  NS_ASSERTION(aFrameType != nsGkAtoms::tableFrame,
+               "InitAbsoluteConstraints should not be called on table frames");
+  NS_ASSERTION(frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW,
                "Why are we here?");
 
   // Get the placeholder frame
   nsIFrame*     placeholderFrame;
 
-  placeholderFrame = aPresContext->PresShell()->GetPlaceholderFrameFor(outOfFlow);
+  placeholderFrame = aPresContext->PresShell()->GetPlaceholderFrameFor(frame);
   NS_ASSERTION(nsnull != placeholderFrame, "no placeholder frame");
 
   // If both 'left' and 'right' are 'auto' or both 'top' and 'bottom' are
   // 'auto', then compute the hypothetical box of where the element would
   // have been if it had been in the flow
   nsHypotheticalBox hypotheticalBox;
   if (((eStyleUnit_Auto == mStylePosition->mOffset.GetLeftUnit()) &&
        (eStyleUnit_Auto == mStylePosition->mOffset.GetRightUnit())) ||
@@ -1154,17 +1121,17 @@ nsHTMLReflowState::InitAbsoluteConstrain
     // Find the nearest containing block frame to the placeholder frame,
     // and return its left edge and width.
     nscoord cbLeftEdge, cbWidth;
     nsIFrame* cbFrame = GetHypotheticalBoxContainer(placeholderFrame,
                                                     cbLeftEdge,
                                                     cbWidth);
 
     CalculateHypotheticalBox(aPresContext, placeholderFrame, cbFrame,
-                             cbLeftEdge, cbWidth, cbrs, hypotheticalBox);
+                             cbLeftEdge, cbWidth, cbrs, hypotheticalBox, aFrameType);
   }
 
   // Initialize the 'left' and 'right' computed offsets
   // XXX Handle new 'static-position' value...
   bool          leftIsAuto = false, rightIsAuto = false;
   if (eStyleUnit_Auto == mStylePosition->mOffset.GetLeftUnit()) {
     mComputedOffsets.left = 0;
     leftIsAuto = PR_TRUE;
@@ -1182,17 +1149,17 @@ nsHTMLReflowState::InitAbsoluteConstrain
                                  mStylePosition->mOffset.GetRight());
   }
 
   // Use the horizontal component of the hypothetical box in the cases
   // where it's needed.
   if (leftIsAuto && rightIsAuto) {
     // Use the direction of the original ("static-position") containing block
     // to dictate whether 'left' or 'right' is treated like 'static-position'.
-    if (NS_STYLE_DIRECTION_LTR == GetNearestContainingBlock(placeholderFrame)
+    if (NS_STYLE_DIRECTION_LTR == placeholderFrame->GetContainingBlock()
                                     ->GetStyleVisibility()->mDirection) {
       NS_ASSERTION(hypotheticalBox.mLeftIsExact, "should always have "
                    "exact value on containing block's start side");
       mComputedOffsets.left = hypotheticalBox.mLeft;
       leftIsAuto = PR_FALSE;
     } else {
       NS_ASSERTION(hypotheticalBox.mRightIsExact, "should always have "
                    "exact value on containing block's start side");
@@ -1562,23 +1529,28 @@ nsHTMLReflowState::ComputeContainingBloc
                                                    const nsHTMLReflowState* aContainingBlockRS,
                                                    nscoord&                 aContainingBlockWidth,
                                                    nscoord&                 aContainingBlockHeight)
 {
   // Unless the element is absolutely positioned, the containing block is
   // formed by the content edge of the nearest block-level ancestor
   aContainingBlockWidth = aContainingBlockRS->mComputedWidth;
   aContainingBlockHeight = aContainingBlockRS->mComputedHeight;
-  
-  if (NS_FRAME_GET_TYPE(mFrameType) == NS_CSS_FRAME_TYPE_ABSOLUTE) {
+
+  // mFrameType for abs-pos tables is NS_CSS_FRAME_TYPE_BLOCK, so we need to
+  // special case them here.
+  if (NS_FRAME_GET_TYPE(mFrameType) == NS_CSS_FRAME_TYPE_ABSOLUTE ||
+      (frame->GetType() == nsGkAtoms::tableFrame &&
+       frame->GetStyleDisplay()->IsAbsolutelyPositioned() &&
+       (frame->GetParent()->GetStateBits() & NS_FRAME_OUT_OF_FLOW))) {
     // See if the ancestor is block-level or inline-level
     if (NS_FRAME_GET_TYPE(aContainingBlockRS->mFrameType) == NS_CSS_FRAME_TYPE_INLINE) {
       // Base our size on the actual size of the frame.  In cases when this is
       // completely bogus (eg initial reflow), this code shouldn't even be
-      // called, since the code in nsPositionedInlineFrame::Reflow will pass in
+      // called, since the code in nsInlineFrame::Reflow will pass in
       // the containing block dimensions to our constructor.
       // XXXbz we should be taking the in-flows into account too, but
       // that's very hard.
       nsMargin computedBorder = aContainingBlockRS->mComputedBorderPadding -
         aContainingBlockRS->mComputedPadding;
       aContainingBlockWidth = aContainingBlockRS->frame->GetRect().width -
         computedBorder.LeftRight();;
       NS_ASSERTION(aContainingBlockWidth >= 0,
@@ -1656,27 +1628,28 @@ IsSideCaption(nsIFrame* aFrame, const ns
 // XXX refactor this code to have methods for each set of properties
 // we are computing: width,height,line-height; margin; offsets
 
 void
 nsHTMLReflowState::InitConstraints(nsPresContext* aPresContext,
                                    nscoord         aContainingBlockWidth,
                                    nscoord         aContainingBlockHeight,
                                    const nsMargin* aBorder,
-                                   const nsMargin* aPadding)
+                                   const nsMargin* aPadding,
+                                   nsIAtom* aFrameType)
 {
   DISPLAY_INIT_CONSTRAINTS(frame, this,
                            aContainingBlockWidth, aContainingBlockHeight,
                            aBorder, aPadding);
 
   // If this is the root frame, then set the computed width and
   // height equal to the available space
   if (nsnull == parentReflowState) {
     // XXXldb This doesn't mean what it used to!
-    InitOffsets(aContainingBlockWidth, aBorder, aPadding);
+    InitOffsets(aContainingBlockWidth, aFrameType, aBorder, aPadding);
     // Override mComputedMargin since reflow roots start from the
     // frame's boundary, which is inside the margin.
     mComputedMargin.SizeTo(0, 0, 0, 0);
     mComputedOffsets.SizeTo(0, 0, 0, 0);
 
     mComputedWidth = availableWidth - mComputedBorderPadding.LeftRight();
     if (mComputedWidth < 0)
       mComputedWidth = 0;
@@ -1713,17 +1686,17 @@ nsHTMLReflowState::InitConstraints(nsPre
         fType = cbrs->frame->GetType();
         if (IS_TABLE_CELL(fType)) {
           // use the cell's computed height 
           aContainingBlockHeight = cbrs->mComputedHeight;
         }
       }
     }
 
-    InitOffsets(aContainingBlockWidth, aBorder, aPadding);
+    InitOffsets(aContainingBlockWidth, aFrameType, aBorder, aPadding);
 
     const nsStyleCoord &height = mStylePosition->mHeight;
     nsStyleUnit heightUnit = height.GetUnit();
 
     // Check for a percentage based height and a containing block height
     // that depends on the content height
     // XXX twiddling heightUnit doesn't help anymore
     // FIXME Shouldn't we fix that?
@@ -1835,23 +1808,23 @@ nsHTMLReflowState::InitConstraints(nsPre
 
       // Doesn't apply to table elements
       mComputedMinWidth = mComputedMinHeight = 0;
       mComputedMaxWidth = mComputedMaxHeight = NS_UNCONSTRAINEDSIZE;
 
     } else if (NS_FRAME_GET_TYPE(mFrameType) == NS_CSS_FRAME_TYPE_ABSOLUTE) {
       // XXX not sure if this belongs here or somewhere else - cwk
       InitAbsoluteConstraints(aPresContext, cbrs, aContainingBlockWidth,
-                              aContainingBlockHeight);
+                              aContainingBlockHeight, aFrameType);
     } else {
       bool isBlock =
         NS_CSS_FRAME_TYPE_BLOCK == NS_FRAME_GET_TYPE(mFrameType);
       // make sure legend frames with display:block and width:auto still
       // shrink-wrap
-      bool shrinkWrap = !isBlock || frame->GetType() == nsGkAtoms::legendFrame;
+      bool shrinkWrap = !isBlock || aFrameType == nsGkAtoms::legendFrame;
       nsSize size =
         frame->ComputeSize(rendContext,
                            nsSize(aContainingBlockWidth,
                                   aContainingBlockHeight),
                            availableWidth,
                            nsSize(mComputedMargin.LeftRight(),
                                   mComputedMargin.TopBottom()),
                            nsSize(mComputedBorderPadding.LeftRight() -
@@ -1863,18 +1836,20 @@ nsHTMLReflowState::InitConstraints(nsPre
                            shrinkWrap);
 
       mComputedWidth = size.width;
       mComputedHeight = size.height;
       NS_ASSERTION(mComputedWidth >= 0, "Bogus width");
       NS_ASSERTION(mComputedHeight == NS_UNCONSTRAINEDSIZE ||
                    mComputedHeight >= 0, "Bogus height");
 
-      if (isBlock && !IsSideCaption(frame, mStyleDisplay))
-        CalculateBlockSideMargins(availableWidth, mComputedWidth);
+      // Exclude inline tables from the block margin calculations
+      if (isBlock && !IsSideCaption(frame, mStyleDisplay) &&
+          frame->GetStyleDisplay()->mDisplay != NS_STYLE_DISPLAY_INLINE_TABLE)
+        CalculateBlockSideMargins(availableWidth, mComputedWidth, aFrameType);
     }
   }
   // Check for blinking text and permission to display it
   mFlags.mBlinks = (parentReflowState && parentReflowState->mFlags.mBlinks);
   if (!mFlags.mBlinks && BlinkIsAllowed()) {
     const nsStyleTextReset* st = frame->GetStyleTextReset();
     mFlags.mBlinks = (st->mTextBlink != NS_STYLE_TEXT_BLINK_NONE);
   }
@@ -1895,16 +1870,17 @@ UpdateProp(FrameProperties& aProps,
     }
   } else {
     aProps.Delete(aProperty);
   }
 }
 
 void
 nsCSSOffsetState::InitOffsets(nscoord aContainingBlockWidth,
+                              nsIAtom* aFrameType,
                               const nsMargin *aBorder,
                               const nsMargin *aPadding)
 {
   DISPLAY_INIT_OFFSETS(frame, this, aContainingBlockWidth, aBorder, aPadding);
 
   // Since we are in reflow, we don't need to store these properties anymore
   // unless they are dependent on width, in which case we store the new value.
   nsPresContext *presContext = frame->PresContext();
@@ -1938,17 +1914,17 @@ nsCSSOffsetState::InitOffsets(nscoord aC
     mComputedPadding.left = presContext->DevPixelsToAppUnits(widget.left);
     needPaddingProp = PR_FALSE;
   }
   else if (aPadding) { // padding is an input arg
     mComputedPadding = *aPadding;
     needPaddingProp = frame->GetStylePadding()->IsWidthDependent();
   }
   else {
-    needPaddingProp = ComputePadding(aContainingBlockWidth);
+    needPaddingProp = ComputePadding(aContainingBlockWidth, aFrameType);
   }
 
   if (isThemed) {
     nsIntMargin widget;
     presContext->GetTheme()->GetWidgetBorder(presContext->DeviceContext(),
                                              frame, disp->mAppearance,
                                              &widget);
     mComputedBorderPadding.top =
@@ -1963,29 +1939,32 @@ nsCSSOffsetState::InitOffsets(nscoord aC
   else if (aBorder) {  // border is an input arg
     mComputedBorderPadding = *aBorder;
   }
   else {
     mComputedBorderPadding = frame->GetStyleBorder()->GetActualBorder();
   }
   mComputedBorderPadding += mComputedPadding;
 
-  nsIAtom* frameType = frame->GetType();
-  if (frameType == nsGkAtoms::tableFrame) {
+  if (aFrameType == nsGkAtoms::tableFrame) {
     nsTableFrame *tableFrame = static_cast<nsTableFrame*>(frame);
 
     if (tableFrame->IsBorderCollapse()) {
       // border-collapsed tables don't use any of their padding, and
       // only part of their border.  We need to do this here before we
       // try to do anything like handling 'auto' widths,
       // '-moz-box-sizing', or 'auto' margins.
       mComputedPadding.SizeTo(0,0,0,0);
       mComputedBorderPadding = tableFrame->GetIncludedOuterBCBorder();
     }
-  } else if (frameType == nsGkAtoms::scrollbarFrame) {
+
+    // The margin is inherited to the outer table frame via
+    // the ::-moz-table-outer rule in ua.css.
+    mComputedMargin.SizeTo(0, 0, 0, 0);
+  } else if (aFrameType == nsGkAtoms::scrollbarFrame) {
     // scrollbars may have had their width or height smashed to zero
     // by the associated scrollframe, in which case we must not report
     // any padding or border.
     nsSize size(frame->GetSize());
     if (size.width == 0 || size.height == 0) {
       mComputedPadding.SizeTo(0,0,0,0);
       mComputedBorderPadding.SizeTo(0,0,0,0);
     }
@@ -1998,17 +1977,18 @@ nsCSSOffsetState::InitOffsets(nscoord aC
 //
 // 'margin-left' + 'border-left-width' + 'padding-left' + 'width' +
 //   'padding-right' + 'border-right-width' + 'margin-right'
 //   = width of containing block 
 //
 // Note: the width unit is not auto when this is called
 void
 nsHTMLReflowState::CalculateBlockSideMargins(nscoord aAvailWidth,
-                                             nscoord aComputedWidth)
+                                             nscoord aComputedWidth,
+                                             nsIAtom* aFrameType)
 {
   NS_WARN_IF_FALSE(NS_UNCONSTRAINEDSIZE != aComputedWidth &&
                    NS_UNCONSTRAINEDSIZE != aAvailWidth,
                    "have unconstrained width; this should only result from "
                    "very large sizes, not attempts at intrinsic width "
                    "calculation");
 
   nscoord sum = mComputedMargin.left + mComputedBorderPadding.left +
@@ -2042,17 +2022,17 @@ nsHTMLReflowState::CalculateBlockSideMar
   bool isAutoRightMargin =
     eStyleUnit_Auto == mStyleMargin->mMargin.GetRightUnit();
   if (!isAutoLeftMargin && !isAutoRightMargin) {
     // Neither margin is 'auto' so we're over constrained. Use the
     // 'direction' property of the parent to tell which margin to
     // ignore
     // First check if there is an HTML alignment that we should honor
     const nsHTMLReflowState* prs = parentReflowState;
-    if (frame->GetType() == nsGkAtoms::tableFrame) {
+    if (aFrameType == nsGkAtoms::tableFrame) {
       NS_ASSERTION(prs->frame->GetType() == nsGkAtoms::tableOuterFrame,
                    "table not inside outer table");
       // Center the table within the outer table based on the alignment
       // of the outer table's parent.
       prs = prs->parentReflowState;
     }
     if (prs &&
         (prs->mStyleText->mTextAlign == NS_STYLE_TEXT_ALIGN_MOZ_LEFT ||
@@ -2160,17 +2140,17 @@ ComputeLineHeight(nsStyleContext* aStyle
                                                getter_AddRefs(fm));
   return GetNormalLineHeight(fm);
 }
 
 nscoord
 nsHTMLReflowState::CalcLineHeight() const
 {
   nscoord blockHeight =
-    frame->IsContainingBlock() ? mComputedHeight :
+    nsLayoutUtils::IsNonWrapperBlock(frame) ? mComputedHeight :
     (mCBReflowState ? mCBReflowState->mComputedHeight : NS_AUTOHEIGHT);
 
   return CalcLineHeight(frame->GetStyleContext(), blockHeight);
 }
 
 /* static */ nscoord
 nsHTMLReflowState::CalcLineHeight(nsStyleContext* aStyleContext,
                                   nscoord aBlockHeight)
@@ -2209,28 +2189,27 @@ nsCSSOffsetState::ComputeMargin(nscoord 
     mComputedMargin.bottom = nsLayoutUtils::
       ComputeWidthDependentValue(aContainingBlockWidth,
                                  styleMargin->mMargin.GetBottom());
   }
   return isWidthDependent;
 }
 
 bool
-nsCSSOffsetState::ComputePadding(nscoord aContainingBlockWidth)
+nsCSSOffsetState::ComputePadding(nscoord aContainingBlockWidth, nsIAtom* aFrameType)
 {
   // If style can provide us the padding directly, then use it.
   const nsStylePadding *stylePadding = frame->GetStylePadding();
   bool isWidthDependent = !stylePadding->GetPadding(mComputedPadding);
   // a table row/col group, row/col doesn't have padding
   // XXXldb Neither do border-collapse tables.
-  nsIAtom* frameType = frame->GetType();
-  if (nsGkAtoms::tableRowGroupFrame == frameType ||
-      nsGkAtoms::tableColGroupFrame == frameType ||
-      nsGkAtoms::tableRowFrame      == frameType ||
-      nsGkAtoms::tableColFrame      == frameType) {
+  if (nsGkAtoms::tableRowGroupFrame == aFrameType ||
+      nsGkAtoms::tableColGroupFrame == aFrameType ||
+      nsGkAtoms::tableRowFrame      == aFrameType ||
+      nsGkAtoms::tableColFrame      == aFrameType) {
     mComputedPadding.SizeTo(0,0,0,0);
   }
   else if (isWidthDependent) {
     // We have to compute the value
     // clamp negative calc() results to 0
     mComputedPadding.left = NS_MAX(0, nsLayoutUtils::
       ComputeWidthDependentValue(aContainingBlockWidth,
                                  stylePadding->mPadding.GetLeft()));
--- a/layout/generic/nsHTMLReflowState.h
+++ b/layout/generic/nsHTMLReflowState.h
@@ -165,17 +165,17 @@ public:
   {
   }
 
   nsCSSOffsetState(nsIFrame *aFrame, nsRenderingContext *aRenderingContext,
                    nscoord aContainingBlockWidth)
     : frame(aFrame)
     , rendContext(aRenderingContext)
   {
-    InitOffsets(aContainingBlockWidth);
+    InitOffsets(aContainingBlockWidth, frame->GetType());
   }
 
 #ifdef DEBUG
   // Reflow trace methods.  Defined in nsFrame.cpp so they have access
   // to the display-reflow infrastructure.
   static void* DisplayInitOffsetsEnter(nsIFrame* aFrame,
                                        nsCSSOffsetState* aState,
                                        nscoord aCBWidth,
@@ -194,21 +194,22 @@ private:
    */
   bool ComputeMargin(nscoord aContainingBlockWidth);
   
   /**
    * Computes padding values from the specified padding style information, and
    * fills in the mComputedPadding member.
    * @return PR_TRUE if the padding is dependent on the containing block width
    */
-   bool ComputePadding(nscoord aContainingBlockWidth);
+   bool ComputePadding(nscoord aContainingBlockWidth, nsIAtom* aFrameType);
 
 protected:
 
   void InitOffsets(nscoord aContainingBlockWidth,
+                   nsIAtom* aFrameType,
                    const nsMargin *aBorder = nsnull,
                    const nsMargin *aPadding = nsnull);
 
   /*
    * Convert nsStyleCoord to nscoord when percentages depend on the
    * containing block width, and enumerated values are for width,
    * min-width, or max-width.  Does not handle auto widths.
    */
@@ -401,23 +402,16 @@ public:
             const nsMargin* aPadding = nsnull);
   /**
    * Find the content width of the containing block of aReflowState
    */
   static nscoord
     GetContainingBlockContentWidth(const nsHTMLReflowState* aReflowState);
 
   /**
-   * Find the containing block of aFrame.  This may return null if
-   * there isn't one (but that should really only happen for root
-   * frames).
-   */
-  static nsIFrame* GetContainingBlockFor(const nsIFrame* aFrame);
-
-  /**
    * Calculate the used line-height property. The return value will be >= 0.
    */
   nscoord CalcLineHeight() const;
 
   /**
    * Same as CalcLineHeight() above, but doesn't need a reflow state.
    *
    * @param aBlockHeight The computed height of the content rect of the block
@@ -492,46 +486,49 @@ public:
   static void* DisplayInitFrameTypeEnter(nsIFrame* aFrame,
                                          nsHTMLReflowState* aState);
   static void DisplayInitFrameTypeExit(nsIFrame* aFrame,
                                        nsHTMLReflowState* aState,
                                        void* aValue);
 #endif
 
 protected:
-  void InitFrameType();
+  void InitFrameType(nsIAtom* aFrameType);
   void InitCBReflowState();
-  void InitResizeFlags(nsPresContext* aPresContext);
+  void InitResizeFlags(nsPresContext* aPresContext, nsIAtom* aFrameType);
 
   void InitConstraints(nsPresContext* aPresContext,
                        nscoord         aContainingBlockWidth,
                        nscoord         aContainingBlockHeight,
                        const nsMargin* aBorder,
-                       const nsMargin* aPadding);
+                       const nsMargin* aPadding,
+                       nsIAtom*        aFrameType);
 
   // Returns the nearest containing block or block frame (whether or not
   // it is a containing block) for the specified frame.  Also returns
   // the left edge and width of the containing block's content area.
   // These are returned in the coordinate space of the containing block.
   nsIFrame* GetHypotheticalBoxContainer(nsIFrame* aFrame,
                                         nscoord& aCBLeftEdge,
                                         nscoord& aCBWidth);
 
   void CalculateHypotheticalBox(nsPresContext*    aPresContext,
                                 nsIFrame*         aPlaceholderFrame,
                                 nsIFrame*         aContainingBlock,
                                 nscoord           aBlockLeftContentEdge,
                                 nscoord           aBlockContentWidth,
                                 const nsHTMLReflowState* cbrs,
-                                nsHypotheticalBox& aHypotheticalBox);
+                                nsHypotheticalBox& aHypotheticalBox,
+                                nsIAtom*          aFrameType);
 
   void InitAbsoluteConstraints(nsPresContext* aPresContext,
                                const nsHTMLReflowState* cbrs,
                                nscoord aContainingBlockWidth,
-                               nscoord aContainingBlockHeight);
+                               nscoord aContainingBlockHeight,
+                               nsIAtom* aFrameType);
 
   void ComputeRelativeOffsets(const nsHTMLReflowState* cbrs,
                               nscoord aContainingBlockWidth,
                               nscoord aContainingBlockHeight,
                               nsPresContext* aPresContext);
 
   // Calculates the computed values for the 'min-Width', 'max-Width',
   // 'min-Height', and 'max-Height' properties, and stores them in the assorted
@@ -540,13 +537,14 @@ protected:
                            nscoord                  aContainingBlockHeight,
                            const nsHTMLReflowState* aContainingBlockRS);
 
   void CalculateHorizBorderPaddingMargin(nscoord aContainingBlockWidth,
                                          nscoord* aInsideBoxSizing,
                                          nscoord* aOutsideBoxSizing);
 
   void CalculateBlockSideMargins(nscoord aAvailWidth,
-                                 nscoord aComputedWidth);
+                                 nscoord aComputedWidth,
+                                 nsIAtom* aFrameType);
 };
 
 #endif /* nsHTMLReflowState_h___ */
 
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -99,16 +99,17 @@ class nsAccessible;
 #endif
 class nsDisplayListBuilder;
 class nsDisplayListSet;
 class nsDisplayList;
 class gfxSkipChars;
 class gfxSkipCharsIterator;
 class gfxContext;
 class nsLineList_iterator;
+class nsAbsoluteContainingBlock;
 
 struct nsPeekOffsetStruct;
 struct nsPoint;
 struct nsRect;
 struct nsSize;
 struct nsMargin;
 struct CharacterDataChangeInfo;
 
@@ -281,16 +282,19 @@ typedef PRUint64 nsFrameState;
 #define NS_FRAME_HAS_CLIP                           NS_FRAME_STATE_BIT(35)
 
 // Frame is a display root and the retained layer tree needs to be updated
 // at the next paint via display list construction.
 // Only meaningful for display roots, so we don't really need a global state
 // bit; we could free up this bit with a little extra complexity.
 #define NS_FRAME_UPDATE_LAYER_TREE                  NS_FRAME_STATE_BIT(36)
 
+// Frame can accept absolutely positioned children.
+#define NS_FRAME_HAS_ABSPOS_CHILDREN                NS_FRAME_STATE_BIT(37)
+
 // The lower 20 bits and upper 32 bits of the frame state are reserved
 // by this API.
 #define NS_FRAME_RESERVED                           ~NS_FRAME_IMPL_RESERVED
 
 // Box layout bits
 #define NS_STATE_IS_HORIZONTAL                      NS_FRAME_STATE_BIT(22)
 #define NS_STATE_IS_DIRECTION_NORMAL                NS_FRAME_STATE_BIT(31)
 
@@ -584,16 +588,18 @@ public:
    * has been initialized.
    *
    * This is only called once for a given child list, and won't be called
    * at all for child lists with no initial list of frames.
    *
    * @param   aListID the child list identifier.
    * @param   aChildList list of child frames. Each of the frames has its
    *            NS_FRAME_IS_DIRTY bit set.  Must not be empty.
+   *            This method cannot handle the child list returned by
+   *            GetAbsoluteListID().
    * @return  NS_ERROR_INVALID_ARG if there is no child list with the specified
    *            name,
    *          NS_ERROR_UNEXPECTED if the frame is an atomic frame or if the
    *            initial list of frames has already been set for that child list,
    *          NS_OK otherwise.  In this case, SetInitialChildList empties out
    *            aChildList in the process of moving the frames over to its own
    *            child list.
    * @see     #Init()
@@ -1971,19 +1977,27 @@ public:
 #ifdef DEBUG
     return !(aFlags & ~(nsIFrame::eDEBUGAllFrames));
 #else
     return !aFlags;
 #endif
   }
 
   /**
-   * Is this frame a containing block for non-positioned elements?
+   * Returns true if the frame is a block wrapper.
    */
-  virtual bool IsContainingBlock() const = 0;
+  bool IsBlockWrapper() const;
+
+  /**
+   * Get this frame's CSS containing block.
+   *
+   * The algorithm is defined in
+   * http://www.w3.org/TR/CSS2/visudet.html#containing-block-details.
+   */
+  nsIFrame* GetContainingBlock() const;
 
   /**
    * Is this frame a containing block for floating elements?
    * Note that very few frames are, so default to false.
    */
   virtual bool IsFloatContainingBlock() const { return false; }
 
   /**
@@ -2718,27 +2732,39 @@ NS_PTR_TO_INT32(frame->Properties().Get(
     for (int i = 0, l = list->Length(); i < l; i++) {
       nsCOMPtr<nsIPresShell> shell = do_QueryReferent(list->ElementAt(i));
       
       if (shell) {
         shell->IncrementPaintCount();
       }
     }
   }  
-  
+
+  /**
+   * Accessors for the absolute containing block.
+   */
+  bool IsAbsoluteContainer() const { return !!(mState & NS_FRAME_HAS_ABSPOS_CHILDREN); }
+  bool HasAbsolutelyPositionedChildren() const;
+  nsAbsoluteContainingBlock* GetAbsoluteContainingBlock() const;
+  virtual void MarkAsAbsoluteContainingBlock();
+  // Child frame types override this function to select their own child list name
+  virtual mozilla::layout::FrameChildListID GetAbsoluteListID() const { return kAbsoluteList; }
+
 protected:
   // Members
   nsRect           mRect;
   nsIContent*      mContent;
   nsStyleContext*  mStyleContext;
   nsIFrame*        mParent;
 private:
   nsIFrame*        mNextSibling;  // doubly-linked list of frames
   nsIFrame*        mPrevSibling;  // Do not touch outside SetNextSibling!
 
+  void MarkAbsoluteFramesForDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect);
+
   static void DestroyPaintedPresShellList(void* propertyValue) {
     nsTArray<nsWeakPtr>* list = static_cast<nsTArray<nsWeakPtr>*>(propertyValue);
     list->Clear();
     delete list;
   }
 
   // Stores weak references to all the PresShells that were painted during
   // the last paint event so that we can increment their paint count during
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -42,17 +42,16 @@
 #include "nsBlockFrame.h"
 #include "nsPlaceholderFrame.h"
 #include "nsGkAtoms.h"
 #include "nsHTMLParts.h"
 #include "nsStyleContext.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsRenderingContext.h"
-#include "nsAbsoluteContainingBlock.h"
 #include "nsCSSAnonBoxes.h"
 #include "nsAutoPtr.h"
 #include "nsFrameManager.h"
 #ifdef ACCESSIBILITY
 #include "nsIServiceManager.h"
 #include "nsAccessibilityService.h"
 #endif
 #include "nsDisplayList.h"
@@ -409,17 +408,19 @@ nsInlineFrame::Reflow(nsPresContext*    
   if (mFrames.IsEmpty()) {
     // Try to pull over one frame before starting so that we know
     // whether we have an anonymous block or not.
     bool complete;
     (void) PullOneFrame(aPresContext, irs, &complete);
   }
 
   rv = ReflowFrames(aPresContext, aReflowState, irs, aMetrics, aStatus);
-  
+
+  ReflowAbsoluteFrames(aPresContext, aMetrics, aReflowState, aStatus);
+
   // Note: the line layout code will properly compute our
   // overflow-rect state for us.
 
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics);
   return rv;
 }
 
 /* virtual */ bool
@@ -913,16 +914,23 @@ nsInlineFrame::GetSkipSides() const
 }
 
 nscoord
 nsInlineFrame::GetBaseline() const
 {
   return mBaseline;
 }
 
+void
+nsInlineFrame::DestroyFrom(nsIFrame* aDestructRoot)
+{
+  DestroyAbsoluteFrames(aDestructRoot);
+  nsInlineFrameSuper::DestroyFrom(aDestructRoot);
+}
+
 #ifdef ACCESSIBILITY
 already_AddRefed<nsAccessible>
 nsInlineFrame::CreateAccessible()
 {
   // Broken image accessibles are created here, because layout
   // replaces the image or image control frame with an inline frame
   nsIAtom *tagAtom = mContent->Tag();
   if ((tagAtom == nsGkAtoms::img || tagAtom == nsGkAtoms::input || 
@@ -1092,16 +1100,18 @@ nsFirstLineFrame::Reflow(nsPresContext* 
   }
 
   NS_ASSERTION(!aReflowState.mLineLayout->GetInFirstLine(),
                "Nested first-line frames? BOGUS");
   aReflowState.mLineLayout->SetInFirstLine(PR_TRUE);
   rv = ReflowFrames(aPresContext, aReflowState, irs, aMetrics, aStatus);
   aReflowState.mLineLayout->SetInFirstLine(PR_FALSE);
 
+  ReflowAbsoluteFrames(aPresContext, aMetrics, aReflowState, aStatus);
+
   // Note: the line layout code will properly compute our overflow state for us
 
   return rv;
 }
 
 /* virtual */ void
 nsFirstLineFrame::PullOverflowsFromPrevInFlow()
 {
@@ -1112,165 +1122,8 @@ nsFirstLineFrame::PullOverflowsFromPrevI
       // Assume that our prev-in-flow has the same line container that we do.
       const nsFrameList::Slice& newFrames =
         mFrames.InsertFrames(this, nsnull, *prevOverflowFrames);
       ReparentChildListStyle(PresContext(), newFrames, this);
     }
   }
 }
 
-//////////////////////////////////////////////////////////////////////
-
-nsIFrame*
-NS_NewPositionedInlineFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
-{
-  return new (aPresShell) nsPositionedInlineFrame(aContext);
-}
-
-NS_IMPL_FRAMEARENA_HELPERS(nsPositionedInlineFrame)
-
-void
-nsPositionedInlineFrame::DestroyFrom(nsIFrame* aDestructRoot)
-{
-  mAbsoluteContainer.DestroyFrames(this, aDestructRoot);
-  nsInlineFrame::DestroyFrom(aDestructRoot);
-}
-
-NS_IMETHODIMP
-nsPositionedInlineFrame::SetInitialChildList(ChildListID     aListID,
-                                             nsFrameList&    aChildList)
-{
-  nsresult  rv;
-
-  if (kAbsoluteList == aListID) {
-    rv = mAbsoluteContainer.SetInitialChildList(this, aListID, aChildList);
-  } else {
-    rv = nsInlineFrame::SetInitialChildList(aListID, aChildList);
-  }
-
-  return rv;
-}
-
-NS_IMETHODIMP
-nsPositionedInlineFrame::AppendFrames(ChildListID     aListID,
-                                      nsFrameList&    aFrameList)
-{
-  nsresult  rv;
-  
-  if (kAbsoluteList == aListID) {
-    rv = mAbsoluteContainer.AppendFrames(this, aListID, aFrameList);
-  } else {
-    rv = nsInlineFrame::AppendFrames(aListID, aFrameList);
-  }
-
-  return rv;
-}
-  
-NS_IMETHODIMP
-nsPositionedInlineFrame::InsertFrames(ChildListID     aListID,
-                                      nsIFrame*       aPrevFrame,
-                                      nsFrameList&    aFrameList)
-{
-  nsresult  rv;
-
-  if (kAbsoluteList == aListID) {
-    rv = mAbsoluteContainer.InsertFrames(this, aListID, aPrevFrame,
-                                         aFrameList);
-  } else {
-    rv = nsInlineFrame::InsertFrames(aListID, aPrevFrame, aFrameList);
-  }
-
-  return rv;
-}
-  
-NS_IMETHODIMP
-nsPositionedInlineFrame::RemoveFrame(ChildListID     aListID,
-                                     nsIFrame*       aOldFrame)
-{
-  nsresult  rv;
-
-  if (kAbsoluteList == aListID) {
-    mAbsoluteContainer.RemoveFrame(this, aListID, aOldFrame);
-    rv = NS_OK;
-  } else {
-    rv = nsInlineFrame::RemoveFrame(aListID, aOldFrame);
-  }
-
-  return rv;
-}
-
-NS_IMETHODIMP
-nsPositionedInlineFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
-                                          const nsRect&           aDirtyRect,
-                                          const nsDisplayListSet& aLists)
-{
-  aBuilder->MarkFramesForDisplayList(this, mAbsoluteContainer.GetChildList(),
-				     aDirtyRect);
-  return nsHTMLContainerFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists);
-}
-
-nsFrameList
-nsPositionedInlineFrame::GetChildList(ChildListID aListID) const
-{
-  if (kAbsoluteList == aListID)
-    return mAbsoluteContainer.GetChildList();
-
-  return nsInlineFrame::GetChildList(aListID);
-}
-
-void
-nsPositionedInlineFrame::GetChildLists(nsTArray<ChildList>* aLists) const
-{
-  nsInlineFrame::GetChildLists(aLists);
-  mAbsoluteContainer.AppendChildList(aLists, kAbsoluteList);
-}
-
-nsIAtom*
-nsPositionedInlineFrame::GetType() const
-{
-  return nsGkAtoms::positionedInlineFrame;
-}
-
-NS_IMETHODIMP
-nsPositionedInlineFrame::Reflow(nsPresContext*          aPresContext,
-                                nsHTMLReflowMetrics&     aDesiredSize,
-                                const nsHTMLReflowState& aReflowState,
-                                nsReflowStatus&          aStatus)
-{
-  nsresult  rv = NS_OK;
-
-  // Don't bother optimizing for fast incremental reflow of absolute
-  // children of an inline
-
-  // Let the inline frame do its reflow first
-  rv = nsInlineFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
-
-  // Let the absolutely positioned container reflow any absolutely positioned
-  // child frames that need to be reflowed
-  // We want to do this under either of two conditions:
-  //  1. If we didn't do the incremental reflow above.
-  //  2. If our size changed.
-  // Even though it's the padding edge that's the containing block, we
-  // can use our rect (the border edge) since if the border style
-  // changed, the reflow would have been targeted at us so we'd satisfy
-  // condition 1.
-  if (NS_SUCCEEDED(rv) &&
-      mAbsoluteContainer.HasAbsoluteFrames()) {
-    // The containing block for the abs pos kids is formed by our padding edge.
-    nsMargin computedBorder =
-      aReflowState.mComputedBorderPadding - aReflowState.mComputedPadding;
-    nscoord containingBlockWidth =
-      aDesiredSize.width - computedBorder.LeftRight();
-    nscoord containingBlockHeight =
-      aDesiredSize.height - computedBorder.TopBottom();
-
-    // Factor the absolutely positioned child bounds into the overflow area
-    // Don't include this frame's bounds, nor its inline descendants' bounds,
-    // and don't store the overflow property.
-    // That will all be done by nsLineLayout::RelativePositionFrames.
-    rv = mAbsoluteContainer.Reflow(this, aPresContext, aReflowState, aStatus,
-                                   containingBlockWidth, containingBlockHeight,
-                                   PR_TRUE, PR_TRUE, PR_TRUE, // XXX could be optimized
-                                   &aDesiredSize.mOverflowAreas);
-  }
-
-  return rv;
-}
--- a/layout/generic/nsInlineFrame.h
+++ b/layout/generic/nsInlineFrame.h
@@ -36,17 +36,16 @@
  * ***** END LICENSE BLOCK ***** */
 
 /* rendering object for CSS display:inline objects */
 
 #ifndef nsInlineFrame_h___
 #define nsInlineFrame_h___
 
 #include "nsHTMLContainerFrame.h"
-#include "nsAbsoluteContainingBlock.h"
 #include "nsLineLayout.h"
 
 class nsAnonymousBlockFrame;
 
 #define nsInlineFrameSuper nsHTMLContainerFrame
 
 /**  In Bidi left (or right) margin/padding/border should be applied to left
  *  (or right) most frame (or a continuation frame).
@@ -92,16 +91,18 @@ public:
   {
     return nsInlineFrameSuper::IsFrameOfType(aFlags &
       ~(nsIFrame::eBidiInlineContainer | nsIFrame::eLineParticipant));
   }
 
   virtual bool IsEmpty();
   virtual bool IsSelfEmpty();
 
+  virtual void DestroyFrom(nsIFrame* aDestructRoot);
+
   virtual bool PeekOffsetCharacter(bool aForward, PRInt32* aOffset,
                                      bool aRespectClusters = true);
   
   // nsIHTMLReflow overrides
   virtual void AddInlineMinWidth(nsRenderingContext *aRenderingContext,
                                  InlineMinWidthData *aData);
   virtual void AddInlinePrefWidth(nsRenderingContext *aRenderingContext,
                                   InlinePrefWidthData *aData);
@@ -224,57 +225,9 @@ public:
 protected:
   nsFirstLineFrame(nsStyleContext* aContext) : nsInlineFrame(aContext) {}
 
   virtual nsIFrame* PullOneFrame(nsPresContext* aPresContext,
                                  InlineReflowState& rs,
                                  bool* aIsComplete);
 };
 
-//----------------------------------------------------------------------
-
-// Derived class created for relatively positioned inline-level elements
-// that acts as a containing block for child absolutely positioned
-// elements
-
-class nsPositionedInlineFrame : public nsInlineFrame
-{
-public:
-  NS_DECL_FRAMEARENA_HELPERS
-
-  nsPositionedInlineFrame(nsStyleContext* aContext)
-    : nsInlineFrame(aContext)
-    , mAbsoluteContainer(kAbsoluteList)
-  {}
-
-  virtual ~nsPositionedInlineFrame() { } // useful for debugging
-
-  virtual void DestroyFrom(nsIFrame* aDestructRoot);
-
-  NS_IMETHOD SetInitialChildList(ChildListID  aListID,
-                                 nsFrameList& aChildList);
-  NS_IMETHOD AppendFrames(ChildListID  aListID,
-                          nsFrameList& aFrameList);
-  NS_IMETHOD InsertFrames(ChildListID  aListID,
-                          nsIFrame*    aPrevFrame,
-                          nsFrameList& aFrameList);
-  NS_IMETHOD RemoveFrame(ChildListID aListID,
-                         nsIFrame*   aOldFrame);
-
-  NS_IMETHOD BuildDisplayList(nsDisplayListBuilder*   aBuilder,
-                              const nsRect&           aDirtyRect,
-                              const nsDisplayListSet& aLists);
-
-  virtual nsFrameList GetChildList(ChildListID aListID) const;
-  virtual void GetChildLists(nsTArray<ChildList>* aLists) const;
-
-  NS_IMETHOD Reflow(nsPresContext*          aPresContext,
-                    nsHTMLReflowMetrics&     aDesiredSize,
-                    const nsHTMLReflowState& aReflowState,
-                    nsReflowStatus&          aStatus);
-  
-  virtual nsIAtom* GetType() const;
-
-protected:
-  nsAbsoluteContainingBlock mAbsoluteContainer;
-};
-
 #endif /* nsInlineFrame_h___ */
--- a/layout/generic/nsLineLayout.cpp
+++ b/layout/generic/nsLineLayout.cpp
@@ -659,18 +659,17 @@ IsPercentageAware(const nsIFrame* aFrame
 
   nsIAtom *fType = aFrame->GetType();
   if (fType == nsGkAtoms::textFrame) {
     // None of these things can ever be true for text frames.
     return PR_FALSE;
   }
 
   // Some of these things don't apply to non-replaced inline frames
-  // (that is, fType == nsGkAtoms::inlineFrame || fType ==
-  // nsGkAtoms::positionedInlineFrame), but we won't bother making
+  // (that is, fType == nsGkAtoms::inlineFrame), but we won't bother making
   // things unnecessarily complicated, since they'll probably be set
   // quite rarely.
 
   const nsStyleMargin* margin = aFrame->GetStyleMargin();
   if (HasPercentageUnitSide(margin->mMargin)) {
     return PR_TRUE;
   }
 
--- a/layout/generic/nsPageContentFrame.cpp
+++ b/layout/generic/nsPageContentFrame.cpp
@@ -132,23 +132,20 @@ nsPageContentFrame::Reflow(nsPresContext
     }
 
     // Place and size the child
     FinishReflowChild(frame, aPresContext, &kidReflowState, aDesiredSize, 0, 0, 0);
 
     NS_ASSERTION(aPresContext->IsDynamic() || !NS_FRAME_IS_FULLY_COMPLETE(aStatus) ||
                   !frame->GetNextInFlow(), "bad child flow list");
   }
-  // Reflow our fixed frames 
+
+  // Reflow our fixed frames
   nsReflowStatus fixedStatus = NS_FRAME_COMPLETE;
-  mFixedContainer.Reflow(this, aPresContext, aReflowState, fixedStatus,
-                         aReflowState.availableWidth,
-                         aReflowState.availableHeight,
-                         PR_FALSE, PR_TRUE, PR_TRUE, // XXX could be optimized
-                         nsnull /* ignore overflow */);
+  ReflowAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, fixedStatus);
   NS_ASSERTION(NS_FRAME_IS_COMPLETE(fixedStatus), "fixed frames can be truncated, but not incomplete");
 
   // Return our desired size
   aDesiredSize.width = aReflowState.availableWidth;
   if (aReflowState.availableHeight != NS_UNCONSTRAINEDSIZE) {
     aDesiredSize.height = aReflowState.availableHeight;
   }
 
@@ -166,14 +163,8 @@ nsPageContentFrame::GetType() const
 
 #ifdef DEBUG
 NS_IMETHODIMP
 nsPageContentFrame::GetFrameName(nsAString& aResult) const
 {
   return MakeFrameName(NS_LITERAL_STRING("PageContent"), aResult);
 }
 #endif
-
-/* virtual */ bool
-nsPageContentFrame::IsContainingBlock() const
-{
-  return PR_TRUE;
-}
--- a/layout/generic/nsPageContentFrame.h
+++ b/layout/generic/nsPageContentFrame.h
@@ -51,17 +51,16 @@ public:
   friend class nsPageFrame;
 
   // nsIFrame
   NS_IMETHOD  Reflow(nsPresContext*      aPresContext,
                      nsHTMLReflowMetrics& aDesiredSize,
                      const nsHTMLReflowState& aMaxSize,
                      nsReflowStatus&      aStatus);
 
-  virtual bool IsContainingBlock() const;
   virtual bool IsFrameOfType(PRUint32 aFlags) const
   {
     return ViewportFrame::IsFrameOfType(aFlags &
              ~(nsIFrame::eCanContainOverflowContainers));
   }
 
   virtual void SetSharedPageData(nsSharedPageData* aPD) { mPD = aPD; }
 
--- a/layout/generic/nsPageFrame.cpp
+++ b/layout/generic/nsPageFrame.cpp
@@ -170,22 +170,16 @@ nsPageFrame::GetType() const
 #ifdef DEBUG
 NS_IMETHODIMP
 nsPageFrame::GetFrameName(nsAString& aResult) const
 {
   return MakeFrameName(NS_LITERAL_STRING("Page"), aResult);
 }
 #endif
 
-/* virtual */ bool
-nsPageFrame::IsContainingBlock() const
-{
-  return PR_TRUE;
-}
-
 void 
 nsPageFrame::ProcessSpecialCodes(const nsString& aStr, nsString& aNewStr)
 {
 
   aNewStr = aStr;
 
   // Search to see if the &D code is in the string 
   // then subst in the current date/time
--- a/layout/generic/nsPageFrame.h
+++ b/layout/generic/nsPageFrame.h
@@ -54,18 +54,16 @@ public:
                      nsHTMLReflowMetrics& aDesiredSize,
                      const nsHTMLReflowState& aMaxSize,
                      nsReflowStatus&      aStatus);
 
   NS_IMETHOD BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                               const nsRect&           aDirtyRect,
                               const nsDisplayListSet& aLists);
 
-  virtual bool IsContainingBlock() const;
-
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::pageFrame
    */
   virtual nsIAtom* GetType() const;
   
 #ifdef NS_DEBUG
--- a/layout/generic/nsQueryFrame.h
+++ b/layout/generic/nsQueryFrame.h
@@ -177,17 +177,16 @@ public:
     nsMenuFrame_id,
     nsMenuPopupFrame_id,
     nsObjectFrame_id,
     nsPageBreakFrame_id,
     nsPageContentFrame_id,
     nsPageFrame_id,
     nsPlaceholderFrame_id,
     nsPopupSetFrame_id,
-    nsPositionedInlineFrame_id,
     nsProgressFrame_id,
     nsProgressMeterFrame_id,
     nsResizerFrame_id,
     nsRootBoxFrame_id,
     nsScrollbarButtonFrame_id,
     nsScrollbarFrame_id,
     nsSelectsAreaFrame_id,
     nsSimplePageSequenceFrame_id,
--- a/layout/generic/nsViewportFrame.cpp
+++ b/layout/generic/nsViewportFrame.cpp
@@ -42,16 +42,17 @@
 
 #include "nsCOMPtr.h"
 #include "nsViewportFrame.h"
 #include "nsHTMLParts.h"
 #include "nsGkAtoms.h"
 #include "nsIScrollableFrame.h"
 #include "nsDisplayList.h"
 #include "FrameLayerBuilder.h"
+#include "nsAbsoluteContainingBlock.h"
 
 using namespace mozilla;
 
 nsIFrame*
 NS_NewViewportFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) ViewportFrame(aContext);
 }
@@ -64,159 +65,100 @@ ViewportFrame::Init(nsIContent*      aCo
                     nsIFrame*        aPrevInFlow)
 {
   return Super::Init(aContent, aParent, aPrevInFlow);
 }
 
 void
 ViewportFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
-  mFixedContainer.DestroyFrames(this, aDestructRoot);
+  DestroyAbsoluteFrames(aDestructRoot);
   nsContainerFrame::DestroyFrom(aDestructRoot);
 }
 
 NS_IMETHODIMP
 ViewportFrame::SetInitialChildList(ChildListID     aListID,
                                    nsFrameList&    aChildList)
 {
-  nsresult rv = NS_OK;
-
   // See which child list to add the frames to
 #ifdef NS_DEBUG
   nsFrame::VerifyDirtyBitSet(aChildList);
 #endif
-  if (kFixedList == aListID) {
-    rv = mFixedContainer.SetInitialChildList(this, aListID, aChildList);
-  } 
-  else {
-    rv = nsContainerFrame::SetInitialChildList(aListID, aChildList);
-  }
-
-  return rv;
+  return nsContainerFrame::SetInitialChildList(aListID, aChildList);
 }
 
 NS_IMETHODIMP
 ViewportFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists)
 {
-  // We don't need any special painting or event handling. We just need to
-  // mark our visible out-of-flow frames (i.e., the fixed position frames) so
-  // that display list construction is guaranteed to recurse into their
-  // ancestors.
-  aBuilder->MarkFramesForDisplayList(this, mFixedContainer.GetChildList(),
-                                     aDirtyRect);
-
   nsIFrame* kid = mFrames.FirstChild();
   if (!kid)
     return NS_OK;
 
   // make the kid's BorderBackground our own. This ensures that the canvas
   // frame's background becomes our own background and therefore appears
   // below negative z-index elements.
   return BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists);
 }
 
 NS_IMETHODIMP
 ViewportFrame::AppendFrames(ChildListID     aListID,
                             nsFrameList&    aFrameList)
 {
-  nsresult rv = NS_OK;
-
-  if (kFixedList == aListID) {
-    rv = mFixedContainer.AppendFrames(this, aListID, aFrameList);
-  }
-  else {
-    NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
-    NS_ASSERTION(GetChildList(aListID).IsEmpty(), "Shouldn't have any kids!");
-    rv = nsContainerFrame::AppendFrames(aListID, aFrameList);
-  }
-
-  return rv;
+  NS_ASSERTION(aListID == kPrincipalList ||
+               aListID == GetAbsoluteListID(), "unexpected child list");
+  NS_ASSERTION(aListID != GetAbsoluteListID() ||
+               GetChildList(aListID).IsEmpty(), "Shouldn't have any kids!");
+  return nsContainerFrame::AppendFrames(aListID, aFrameList);
 }
 
 NS_IMETHODIMP
 ViewportFrame::InsertFrames(ChildListID     aListID,
                             nsIFrame*       aPrevFrame,
                             nsFrameList&    aFrameList)
 {
-  nsresult rv = NS_OK;
-
-  if (kFixedList == aListID) {
-    rv = mFixedContainer.InsertFrames(this, aListID, aPrevFrame, aFrameList);
-  }
-  else {
-    NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
-    NS_ASSERTION(GetChildList(aListID).IsEmpty(), "Shouldn't have any kids!");
-    rv = nsContainerFrame::InsertFrames(aListID, aPrevFrame, aFrameList);
-  }
-
-  return rv;
+  NS_ASSERTION(aListID == kPrincipalList ||
+               aListID == GetAbsoluteListID(), "unexpected child list");
+  NS_ASSERTION(aListID != GetAbsoluteListID() ||
+               GetChildList(aListID).IsEmpty(), "Shouldn't have any kids!");
+  return nsContainerFrame::InsertFrames(aListID, aPrevFrame, aFrameList);
 }
 
 NS_IMETHODIMP
 ViewportFrame::RemoveFrame(ChildListID     aListID,
                            nsIFrame*       aOldFrame)
 {
-  nsresult rv = NS_OK;
-
-  if (kFixedList == aListID) {
-    mFixedContainer.RemoveFrame(this, aListID, aOldFrame);
-    rv = NS_OK;
-  }
-  else {
-    NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
-    rv = nsContainerFrame::RemoveFrame(aListID, aOldFrame);
-  }
-
-  return rv;
-}
-
-nsFrameList
-ViewportFrame::GetChildList(ChildListID aListID) const
-{
-  if (kFixedList == aListID)
-    return mFixedContainer.GetChildList();
-
-  return nsContainerFrame::GetChildList(aListID);
-}
-
-void
-ViewportFrame::GetChildLists(nsTArray<ChildList>* aLists) const
-{
-  nsContainerFrame::GetChildLists(aLists);
-  mFixedContainer.AppendChildList(aLists, kFixedList);
+  NS_ASSERTION(aListID == kPrincipalList ||
+               aListID == GetAbsoluteListID(), "unexpected child list");
+  return nsContainerFrame::RemoveFrame(aListID, aOldFrame);
 }
 
 /* virtual */ nscoord
 ViewportFrame::GetMinWidth(nsRenderingContext *aRenderingContext)
 {
   nscoord result;
   DISPLAY_MIN_WIDTH(this, result);
   if (mFrames.IsEmpty())
     result = 0;
   else
     result = mFrames.FirstChild()->GetMinWidth(aRenderingContext);
-    
-  // XXXldb Deal with mFixedContainer (matters for SizeToContent)!
 
   return result;
 }
 
 /* virtual */ nscoord
 ViewportFrame::GetPrefWidth(nsRenderingContext *aRenderingContext)
 {
   nscoord result;
   DISPLAY_PREF_WIDTH(this, result);
   if (mFrames.IsEmpty())
     result = 0;
   else
     result = mFrames.FirstChild()->GetPrefWidth(aRenderingContext);
-    
-  // XXXldb Deal with mFixedContainer (matters for SizeToContent)!
 
   return result;
 }
 
 nsPoint
 ViewportFrame::AdjustReflowStateForScrollbars(nsHTMLReflowState* aReflowState) const
 {
   // Calculate how much room is available for fixed frames. That means
@@ -304,30 +246,34 @@ ViewportFrame::Reflow(nsPresContext*    
   aDesiredSize.height = aReflowState.ComputedHeight() != NS_UNCONSTRAINEDSIZE
                           ? aReflowState.ComputedHeight()
                           : kidHeight;
 
   // Make a copy of the reflow state and change the computed width and height
   // to reflect the available space for the fixed items
   nsHTMLReflowState reflowState(aReflowState);
   nsPoint offset = AdjustReflowStateForScrollbars(&reflowState);
-  
+
 #ifdef DEBUG
-  NS_ASSERTION(mFixedContainer.GetChildList().IsEmpty() ||
-               (offset.x == 0 && offset.y == 0),
-               "We don't handle correct positioning of fixed frames with "
-               "scrollbars in odd positions");
+  if (IsAbsoluteContainer()) {
+    NS_ASSERTION(GetAbsoluteContainingBlock()->GetChildList().IsEmpty() ||
+                 (offset.x == 0 && offset.y == 0),
+                 "We don't handle correct positioning of fixed frames with "
+                 "scrollbars in odd positions");
+  }
 #endif
 
-  // Just reflow all the fixed-pos frames.
-  rv = mFixedContainer.Reflow(this, aPresContext, reflowState, aStatus,
-                              reflowState.ComputedWidth(),
-                              reflowState.ComputedHeight(),
-                              PR_FALSE, PR_TRUE, PR_TRUE, // XXX could be optimized
-                              nsnull /* ignore overflow */);
+  if (IsAbsoluteContainer()) {
+    // Just reflow all the fixed-pos frames.
+    rv = GetAbsoluteContainingBlock()->Reflow(this, aPresContext, reflowState, aStatus,
+                                              reflowState.ComputedWidth(),
+                                              reflowState.ComputedHeight(),
+                                              false, true, true, // XXX could be optimized
+                                              nsnull /* ignore overflow */);
+  }
 
   // If we were dirty then do a repaint
   if (GetStateBits() & NS_FRAME_IS_DIRTY) {
     nsRect damageRect(0, 0, aDesiredSize.width, aDesiredSize.height);
     Invalidate(damageRect);
   }
 
   // XXX Should we do something to clip our children to this?
@@ -339,22 +285,16 @@ ViewportFrame::Reflow(nsPresContext*    
 }
 
 nsIAtom*
 ViewportFrame::GetType() const
 {
   return nsGkAtoms::viewportFrame;
 }
 
-/* virtual */ bool
-ViewportFrame::IsContainingBlock() const
-{
-  return PR_TRUE;
-}
-
 void
 ViewportFrame::InvalidateInternal(const nsRect& aDamageRect,
                                   nscoord aX, nscoord aY, nsIFrame* aForChild,
                                   PRUint32 aFlags)
 {
   nsRect r = aDamageRect + nsPoint(aX, aY);
   nsPresContext* presContext = PresContext();
   presContext->NotifyInvalidation(r, aFlags);
--- a/layout/generic/nsViewportFrame.h
+++ b/layout/generic/nsViewportFrame.h
@@ -40,35 +40,32 @@
  * the document's scrollbars and contains fixed-positioned elements
  */
 
 #ifndef nsViewportFrame_h___
 #define nsViewportFrame_h___
 
 #include "nsContainerFrame.h"
 #include "nsGkAtoms.h"
-#include "nsAbsoluteContainingBlock.h"
 
 class nsPresContext;
 
 /**
   * ViewportFrame is the parent of a single child - the doc root frame or a scroll frame 
   * containing the doc root frame. ViewportFrame stores this child in its primary child 
-  * list. It stores fixed positioned items in a secondary child list and its mFixedContainer 
-  * delegate handles them. 
+  * list.
   */
 class ViewportFrame : public nsContainerFrame {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   typedef nsContainerFrame Super;
 
   ViewportFrame(nsStyleContext* aContext)
     : nsContainerFrame(aContext)
-    , mFixedContainer(kFixedList)
   {}
   virtual ~ViewportFrame() { } // useful for debugging
 
   virtual void DestroyFrom(nsIFrame* aDestructRoot);
 
   NS_IMETHOD Init(nsIContent*      aContent,
                   nsIFrame*        aParent,
                   nsIFrame*        asPrevInFlow);
@@ -81,19 +78,16 @@ public:
 
   NS_IMETHOD InsertFrames(ChildListID     aListID,
                           nsIFrame*       aPrevFrame,
                           nsFrameList&    aFrameList);
 
   NS_IMETHOD RemoveFrame(ChildListID     aListID,
                          nsIFrame*       aOldFrame);
 
-  virtual nsFrameList GetChildList(ChildListID aListID) const;
-  virtual void GetChildLists(nsTArray<ChildList>* aLists) const;
-
   NS_IMETHOD BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                               const nsRect&           aDirtyRect,
                               const nsDisplayListSet& aLists);
 
   virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext);
   virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext);
   NS_IMETHOD Reflow(nsPresContext*          aPresContext,
                     nsHTMLReflowMetrics&     aDesiredSize,
@@ -101,29 +95,26 @@ public:
                     nsReflowStatus&          aStatus);
 
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::viewportFrame
    */
   virtual nsIAtom* GetType() const;
-  
-  virtual bool IsContainingBlock() const;
 
   virtual void InvalidateInternal(const nsRect& aDamageRect,
                                   nscoord aX, nscoord aY, nsIFrame* aForChild,
                                   PRUint32 aFlags);
 
 #ifdef DEBUG
   NS_IMETHOD GetFrameName(nsAString& aResult) const;
 #endif
 
+private:
+  virtual mozilla::layout::FrameChildListID GetAbsoluteListID() const { return kFixedList; }
+
 protected:
   nsPoint AdjustReflowStateForScrollbars(nsHTMLReflowState* aReflowState) const;
-
-  // position: fixed content is really content which is absolutely positioned with
-  // respect to the viewport.
-  nsAbsoluteContainingBlock mFixedContainer;
 };
 
 
 #endif // nsViewportFrame_h___
new file mode 100644
--- /dev/null
+++ b/layout/reftests/abs-pos/continuation-positioned-inline-1.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <span style="position: relative; top: 100px">foo<br>
+      <span id="ins-point"><span style="position: absolute; top: 0">abs</span>bar</span></span>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/abs-pos/continuation-positioned-inline-2.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+  <body onload="loaded()">
+    <span style="position: relative; top: 100px">foo<br>
+      <span id="ins-point">bar</span></span>
+    <script>
+      function loaded() {
+        var insPoint = document.getElementById("ins-point");
+        var span = document.createElement("span");
+        span.style.position = "absolute";
+        span.style.top = 0;
+        span.appendChild(document.createTextNode("abs"));
+        insPoint.insertBefore(span, insPoint.firstChild);
+      }
+    </script>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/abs-pos/continuation-positioned-inline-ref.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <span style="position: relative; top: 100px"><span style="position: absolute; top: 0; left: 0">abs</span>foo<br>
+      <span id="ins-point">bar</span></span>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/abs-pos/fieldset-1-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <style>
+      * { border: 0; margin: 0; padding: 0; }
+    </style>
+  </head>
+  <body>
+    <span style="position: absolute; top: 50px; left: 50px">test</span>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/abs-pos/fieldset-1.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <style>
+      * { border: 0; margin: 0; padding: 0; }
+    </style>
+  </head>
+  <body>
+    <fieldset style="position: relative; top: 25px; left: 20px; width: 100px;">
+      <legend>
+        <span style="position: absolute; top: 25px; left: 30px">test</span>
+      </legend>
+    </fieldset>
+  </body>
+</html>
--- a/layout/reftests/abs-pos/reftest.list
+++ b/layout/reftests/abs-pos/reftest.list
@@ -1,3 +1,15 @@
 == font-size-wrap.html font-size-wrap-ref.html
 == abs-pos-auto-margin-1.html abs-pos-auto-margin-1-ref.html
 == auto-offset-inline-block-1.html auto-offset-inline-block-1-ref.html
+== fieldset-1.html fieldset-1-ref.html
+== table-1.html table-1-ref.html
+== table-2.html table-2-ref.html
+== table-3.html table-3-ref.html
+== continuation-positioned-inline-1.html continuation-positioned-inline-ref.html
+== continuation-positioned-inline-2.html continuation-positioned-inline-ref.html
+== scrollframe-1.html scrollframe-1-ref.html
+== scrollframe-2.html scrollframe-2-ref.html
+== select-1.html select-1-ref.html
+== select-1-dynamic.html select-1-ref.html
+== select-2.html select-2-ref.html
+== select-3.html select-3-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/abs-pos/scrollframe-1-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <body onload="loaded()">
+    <div style="position: relative; top: 100px; overflow: scroll; width: 100px; height: 100px;">
+      <div style="height: 200px"></div></div>
+    <script>
+      function loaded() {
+        var insPoint = document.querySelector("div");
+        insPoint.scrollTop = 50;
+      }
+    </script>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/abs-pos/scrollframe-1.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+  <body onload="loaded()">
+    <div style="position: relative; top: 100px; overflow: scroll; width: 100px; height: 100px;">
+      <div style="height: 200px">foo</div></div>
+    <script>
+      function loaded() {
+        var insPoint = document.querySelector("div");
+        insPoint.scrollTop = 50;
+        var div = document.createElement("div");
+        div.style.position = "absolute";
+        div.style.top = 0;
+        div.appendChild(document.createTextNode("abs"));
+        insPoint.insertBefore(div, insPoint.firstChild);
+      }
+    </script>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/abs-pos/scrollframe-2-ref.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+  <body onload="loaded()">
+    <div style="position: relative; top: 100px; overflow: scroll; width: 100px; height: 100px;">
+      <div style="height: 200px"></div></div>
+    <div style="position: absolute; top: 100px;" id="abs">abs</div>
+    <script>
+      function loaded() {
+        var insPoint = document.querySelector("div");
+        insPoint.scrollTop = 50;
+        var abs = document.getElementById("abs");
+        abs.style.top = insPoint.offsetTop + "px";
+      }
+    </script>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/abs-pos/scrollframe-2.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+  <body onload="loaded()">
+    <div style="position: relative; top: 100px; overflow: scroll; width: 100px; height: 100px;">
+      <div style="height: 200px">foo</div></div>
+    <script>
+      function loaded() {
+        var insPoint = document.querySelector("div");
+        insPoint.scrollTop = 50;
+        var div = document.createElement("div");
+        div.style.position = "absolute";
+        div.style.top = '50px';
+        div.appendChild(document.createTextNode("abs"));
+        insPoint.insertBefore(div, insPoint.firstChild);
+      }
+    </script>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/abs-pos/select-1-dynamic.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+  <select style="position: relative" size=4>
+    <option>bar</option>
+  </select>
+  <select style="position: relative">
+    <option>bar</option>
+  </select>
+  <script>
+    function injectAbsPosKid(s) {
+      var option = document.createElement("option");
+      option.appendChild(document.createTextNode("foo"));
+      option.style.position = "absolute";
+      option.style.top = "100px";
+      s.insertBefore(option, s.firstChild);
+
+      var div = document.createElement("div");
+      div.appendChild(document.createTextNode("bar"));
+      div.style.position = "absolute";
+      div.style.top = "200px";
+      s.appendChild(div);
+    }
+    onload = function() {
+      var s1 = document.querySelectorAll("select")[0];
+      var s2 = document.querySelectorAll("select")[1];
+      injectAbsPosKid(s1);
+      injectAbsPosKid(s2);
+      s2.selectedIndex = 0;
+    };
+  </script>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/abs-pos/select-1-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <select size=4>
+    <option>foo</option>
+    <option>bar</option>
+  </select>
+  <select>
+    <option>foo</option>
+    <option>bar</option>
+  </select>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/abs-pos/select-1.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <select style="position: relative" size=4>
+    <option style="position: absolute; top:100px;">foo</option>
+    <option>bar</option>
+    <div style="position: absolute; top: 200px;">baz</div>
+  </select>
+  <select style="position: relative">
+    <option style="position: absolute; top:100px;">foo</option>
+    <option>bar</option>
+    <div style="position: absolute; top: 200px;">baz</div>
+  </select>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/abs-pos/select-2-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <body style="margin: 0; padding: 0;">
+    <div style="position: absolute; top: 100px; left: 100px;">
+      <select size=4>
+        <option>foo</option>
+        <option>bar</option>
+      </select>
+    </div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/abs-pos/select-2.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <body style="margin: 0; padding: 0;">
+    <div style="position: relative">
+      <select size=4 style="position: absolute; top: 100px; left: 100px;">
+        <option>foo</option>
+        <option>bar</option>
+      </select>
+    </div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/abs-pos/select-3-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+  <body style="margin: 0; padding: 0;">
+    <select style="position: fixed; top: 100px; left: 100px;">
+      <option>foo</option>
+      <option>bar</option>
+    </select>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/abs-pos/select-3.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <body style="margin: 0; padding: 0;">
+    <div style="position: relative;">
+      <select style="position: absolute; top: 100px; left: 100px;">
+        <option>foo</option>
+        <option>bar</option>
+      </select>
+    </div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/abs-pos/table-1-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+  <body style="margin: 0">
+    <table style="position: relative; top: 100px; left: 50px; border: 1px solid red; width: 90px; height: 100px; border-spacing: 0">
+      <tr>
+        <td style="padding: 0">
+        </td>
+      </tr>
+    </table>
+    <div style="position: absolute; top: 110px; left: 70px; border: 1px solid green; width: 50px; height: 60px;"></div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/abs-pos/table-1.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+  <body style="margin: 0">
+    <table style="position: relative; top: 100px; left: 50px; border: 1px solid red; width: 90px; height: 100px; border-spacing: 0">
+      <tr>
+        <td style="padding: 0">
+          <div style="position: absolute; top: 10px; left: 20px; border: 1px solid green; width: 50px; height: 60px;"></div>
+        </td>
+      </tr>
+    </table>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/abs-pos/table-2-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <body style="margin: 0">
+    <table style="position: relative; top: 100px; left: 50px; border: 1px solid red; width: 90px; height: 100px; border-spacing: 0">
+      <caption>foo</caption>
+      <tr>
+        <td style="padding: 0">
+        </td>
+      </tr>
+    </table>
+    <div style="position: absolute; top: 110px; left: 70px; border: 1px solid green; width: 50px; height: 60px;"></div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/abs-pos/table-2.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <body style="margin: 0">
+    <table style="position: relative; top: 100px; left: 50px; border: 1px solid red; width: 90px; height: 100px; border-spacing: 0">
+      <caption>foo</caption>
+      <tr>
+        <td style="padding: 0">
+          <div style="position: absolute; top: 10px; left: 20px; border: 1px solid green; width: 50px; height: 60px;"></div>
+        </td>
+      </tr>
+    </table>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/abs-pos/table-3-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style type="text/css">
+.box {position: relative; left:50px; top: 50px; outline: red dotted 1px;width: 200px; height:200px;}
+.lc {position: absolute; left:0px; top:0px;border: green dotted 1px;width: 20px; height:20px;}
+.rc {position: absolute; right:0px; top:0px;border: blue dotted 1px;width: 20px; height:20px;}
+.brc {position: absolute; right:0px; bottom:0px;border: blue dotted 1px;width: 20px; height:20px;}
+</style>
+</head>
+<body>
+<div class="box">
+  <div class="border">
+    <div class="lc"></div>
+    <div class="brc"></div>
+  </div>
+</div>
+</div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/abs-pos/table-3.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style type="text/css">
+.table {display: table; position: relative; left:50px; top: 50px; outline: red dotted 1px;width: 200px; height:200px;}
+.lc {position: absolute; left:0px; top:0px;border: green dotted 1px;width: 20px; height:20px;}
+.rc {position: absolute; right:0px; top:0px;border: blue dotted 1px;width: 20px; height:20px;}
+.brc {position: absolute; right:0px; bottom:0px;border: blue dotted 1px;width: 20px; height:20px;}
+</style>
+</head>
+<body>
+<div class="table">
+  <div class="lc"></div>
+  <div class="brc"></div>
+</div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/10209-1.html
@@ -0,0 +1,16 @@
+<!DOCTYPE HTML>
+<style>
+@font-face {
+  font-family: Ahem;
+  src: url(../fonts/Ahem.ttf);
+}
+* {
+  font-family: Ahem;
+}
+</style>
+<body style="font-size: 100px; padding-top: 5px">
+  <div style="position: relative; display: inline;">
+    <table style="height: 50%; position: absolute; width: 50px; background: green">
+    </table>
+  </div>
+</body>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/10209-2.html
@@ -0,0 +1,16 @@
+<!DOCTYPE HTML>
+<style>
+@font-face {
+  font-family: Ahem;
+  src: url(../fonts/Ahem.ttf);
+}
+* {
+  font-family: Ahem;
+}
+</style>
+<body style="font-size: 100px">
+  <div style="position: relative; height:100px;">
+    <table style="height: 50%; position: absolute; width: 50px; background: green">
+    </table>
+  </div>
+</body>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/10209-3-ref.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<style>
+@font-face {
+  font-family: Ahem;
+  src: url(../fonts/Ahem.ttf);
+}
+* {
+  font-family: Ahem;
+}
+</style>
+<body style="margin: 0">
+  <div style="width: 100px; height: 100px; background: green">
+  </div>
+</body>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/10209-3.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<style>
+@font-face {
+  font-family: Ahem;
+  src: url(../fonts/Ahem.ttf);
+}
+* {
+  font-family: Ahem;
+}
+</style>
+<body style="position: relative; display: inline; border-right: 1px solid black; font-size: 100px; line-height: 100px; margin: 0">
+  <table style="position: absolute; width: 100px; height: 100%; top: 0; left: 0; background: green"></table>
+</body>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/10209-ref.html
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML>
+<style>
+@font-face {
+  font-family: Ahem;
+  src: url(../fonts/Ahem.ttf);
+}
+* {
+  font-family: Ahem;
+}
+</style>
+<body>
+  <div style="width: 50px; height: 50px; background: green">
+  </div>
+</body>
--- a/layout/reftests/bugs/427129-table-caption-ref.html
+++ b/layout/reftests/bugs/427129-table-caption-ref.html
@@ -33,276 +33,276 @@
 
   To test the behavior under resizing, every test in this page is
   repeated three times, once in a container one pixel above the
   transition width, once at the transition width (just fitting), and
   once in a container a pixel below the transition width.
 
 -->
 
-<div style="width: 335px">
+<div style="width: 405px">
 	<div class="contain">
 		<div class="t" style="margin-left: 56px"></div>
 		<div class="caption" style="margin-left: 116px"></div>
 	</div>
 </div>
 
-<div style="width: 334px">
+<div style="width: 404px">
 	<div class="contain">
 		<div class="t" style="margin-left: 56px"></div>
 		<div class="caption" style="margin-left: 116px"></div>
 	</div>
 </div>
 
-<div style="width: 333px">
+<div style="width: 403px">
 	<div class="contain">
 		<div class="pushed"></div>
 		<div class="t" style="margin-left: 55px"></div>
 		<div class="caption" style="margin-left: 115px"></div>
 	</div>
 </div>
 
-<div style="width: 334px">
+<div style="width: 405px">
 	<div class="contain">
 		<div class="caption" style="margin-left: 116px"></div>
 		<div class="t" style="margin-left: 56px"></div>
 	</div>
 </div>
 
-<div style="width: 333px">
+<div style="width: 404px">
 	<div class="contain">
 		<div class="caption" style="margin-left: 116px"></div>
 		<div class="t" style="margin-left: 56px"></div>
 	</div>
 </div>
 
-<div style="width: 332px">
+<div style="width: 403px">
 	<div class="contain">
 		<div class="pushed"></div>
 		<div class="caption" style="margin-left: 116px"></div>
 		<div class="t" style="margin-left: 56px"></div>
 	</div>
 </div>
 
-<div style="width: 334px">
+<div style="width: 406px">
 	<div class="contain">
 		<div class="t" style="margin-left: 57px"></div>
 		<div class="caption" style="margin-left: 117px"></div>
 	</div>
 </div>
 
-<div style="width: 333px">
+<div style="width: 405px">
 	<div class="contain">
 		<div class="t" style="margin-left: 57px"></div>
 		<div class="caption" style="margin-left: 117px"></div>
 	</div>
 </div>
 
-<div style="width: 332px">
+<div style="width: 404px">
 	<div class="contain">
 		<div class="pushed"></div>
 		<div class="t" style="margin-left: 57px"></div>
 		<div class="caption" style="margin-left: 117px"></div>
 	</div>
 </div>
 
-<div style="width: 330px">
+<div style="width: 401px">
+	<div class="contain">
+		<div class="caption" style="margin-left: 112px"></div>
+		<div class="t" style="margin-left: 56px"></div>
+	</div>
+</div>
+
+<div style="width: 400px">
 	<div class="contain">
-		<div class="caption" style="margin-left: 56px"></div>
+		<div class="caption" style="margin-left: 112px"></div>
+		<div class="t" style="margin-left: 56px"></div>
+	</div>
+</div>
+
+<div style="width: 399px">
+	<div class="contain">
+		<div class="pushed"></div>
+		<div class="caption" style="margin-left: 112px"></div>
 		<div class="t" style="margin-left: 56px"></div>
 	</div>
 </div>
 
-<div style="width: 329px">
+<div style="width: 401px">
+	<div class="contain">
+		<div class="t" style="margin-left: 56px"></div>
+		<div class="caption" style="margin-left: 112px"></div>
+	</div>
+</div>
+
+<div style="width: 400px">
 	<div class="contain">
-		<div class="caption" style="margin-left: 56px"></div>
 		<div class="t" style="margin-left: 56px"></div>
+		<div class="caption" style="margin-left: 112px"></div>
+	</div>
+</div>
+
+<div style="width: 399px">
+	<div class="contain">
+		<div class="pushed"></div>
+		<div class="t" style="margin-left: 55px"></div>
+		<div class="caption" style="margin-left: 111px"></div>
 	</div>
 </div>
 
-<div style="width: 328px">
+<div style="width: 400px">
+	<div class="contain">
+		<div class="t" style="margin-left: 56px"></div>
+		<div class="caption" style="margin-left: 111px"></div>
+	</div>
+</div>
+
+<div style="width: 399px">
+	<div class="contain">
+		<div class="t" style="margin-left: 56px"></div>
+		<div class="caption" style="margin-left: 111px"></div>
+	</div>
+</div>
+
+<div style="width: 398px">
 	<div class="contain">
 		<div class="pushed"></div>
-		<div class="caption" style="margin-left: 56px"></div>
+		<div class="t" style="margin-left: 56px"></div>
+		<div class="caption" style="margin-left: 111px"></div>
+	</div>
+</div>
+
+<div style="width: 400px">
+	<div class="contain">
+		<div class="caption" style="margin-left: 111px"></div>
 		<div class="t" style="margin-left: 56px"></div>
 	</div>
 </div>
 
-<div style="width: 331px">
-	<div class="contain">
-		<div class="t" style="margin-left: 56px"></div>
-		<div class="caption" style="margin-left: 57px"></div>
-	</div>
-</div>
-
-<div style="width: 330px">
-	<div class="contain">
-		<div class="t" style="margin-left: 56px"></div>
-		<div class="caption" style="margin-left: 57px"></div>
-	</div>
-</div>
-
-<div style="width: 329px">
-	<div class="contain">
-		<div class="pushed"></div>
-		<div class="t" style="margin-left: 55px"></div>
-		<div class="caption" style="margin-left: 56px"></div>
-	</div>
-</div>
-
-<div style="width: 331px">
+<div style="width: 399px">
 	<div class="contain">
-		<div class="t" style="margin-left: 57px"></div>
-		<div class="caption" style="margin-left: 56px"></div>
-	</div>
-</div>
-
-<div style="width: 330px">
-	<div class="contain">
-		<div class="t" style="margin-left: 57px"></div>
-		<div class="caption" style="margin-left: 56px"></div>
-	</div>
-</div>
-
-<div style="width: 329px">
-	<div class="contain">
-		<div class="pushed"></div>
-		<div class="t" style="margin-left: 56px"></div>
-		<div class="caption" style="margin-left: 55px"></div>
-	</div>
-</div>
-
-<div style="width: 330px">
-	<div class="contain">
-		<div class="caption" style="margin-left: 56px"></div>
+		<div class="caption" style="margin-left: 111px"></div>
 		<div class="t" style="margin-left: 56px"></div>
 	</div>
 </div>
 
-<div style="width: 329px">
-	<div class="contain">
-		<div class="caption" style="margin-left: 56px"></div>
-		<div class="t" style="margin-left: 56px"></div>
-	</div>
-</div>
-
-<div style="width: 328px">
+<div style="width: 398px">
 	<div class="contain">
 		<div class="pushed"></div>
-		<div class="caption" style="margin-left: 55px"></div>
+		<div class="caption" style="margin-left: 110px"></div>
 		<div class="t" style="margin-left: 55px"></div>
 	</div>
 </div>
 
-<div style="width: 331px">
+<div style="width: 402px">
 	<div class="contain">
 		<div class="t" style="margin-left: 57px"></div>
-		<div class="caption" style="margin-left: 56px"></div>
+		<div class="caption" style="margin-left: 113px"></div>
 	</div>
 </div>
 
-<div style="width: 330px">
+<div style="width: 401px">
 	<div class="contain">
 		<div class="t" style="margin-left: 57px"></div>
-		<div class="caption" style="margin-left: 56px"></div>
+		<div class="caption" style="margin-left: 113px"></div>
 	</div>
 </div>
 
-<div style="width: 329px">
+<div style="width: 400px">
 	<div class="contain">
 		<div class="pushed"></div>
 		<div class="t" style="margin-left: 57px"></div>
-		<div class="caption" style="margin-left: 56px"></div>
+		<div class="caption" style="margin-left: 113px"></div>
 	</div>
 </div>
 
-<div style="width: 331px">
+<div style="width: 402px">
 	<div class="contain">
-		<div class="caption" style="margin-left: 57px"></div>
+		<div class="caption" style="margin-left: 113px"></div>
 		<div class="t" style="margin-left: 56px"></div>
 	</div>
 </div>
 
-<div style="width: 330px">
+<div style="width: 401px">
 	<div class="contain">
-		<div class="caption" style="margin-left: 57px"></div>
+		<div class="caption" style="margin-left: 113px"></div>
+		<div class="t" style="margin-left: 56px"></div>
+	</div>
+</div>
+
+<div style="width: 400px">
+	<div class="contain">
+		<div class="pushed"></div>
+		<div class="caption" style="margin-left: 113px"></div>
 		<div class="t" style="margin-left: 56px"></div>
 	</div>
 </div>
 
-<div style="width: 329px">
+<div style="width: 656px">
+	<div class="contain">
+		<div class="side caption" style="margin-left: 155px"></div
+		><div class="side t" style="margin-left: 100px"></div>
+	</div>
+</div>
+
+<div style="width: 655px">
+	<div class="contain">
+		<div class="side caption" style="margin-left: 155px"></div
+		><div class="side t" style="margin-left: 100px"></div>
+	</div>
+</div>
+
+<div style="width: 654px">
 	<div class="contain">
 		<div class="pushed"></div>
-		<div class="caption" style="margin-left: 57px"></div>
-		<div class="t" style="margin-left: 56px"></div>
+		<div class="side caption" style="margin-left: 155px"></div
+		><div class="side t" style="margin-left: 100px"></div>
 	</div>
 </div>
 
 <div style="width: 657px">
 	<div class="contain">
-		<div class="side caption" style="margin-left: 56px"></div
+		<div class="side caption" style="margin-left: 156px"></div
 		><div class="side t" style="margin-left: 100px"></div>
 	</div>
 </div>
 
 <div style="width: 656px">
 	<div class="contain">
-		<div class="side caption" style="margin-left: 56px"></div
+		<div class="side caption" style="margin-left: 156px"></div
 		><div class="side t" style="margin-left: 100px"></div>
 	</div>
 </div>
 
 <div style="width: 655px">
 	<div class="contain">
 		<div class="pushed"></div>
-		<div class="side caption" style="margin-left: 55px"></div
+		<div class="side caption" style="margin-left: 156px"></div
+		><div class="side t" style="margin-left: 100px"></div>
+	</div>
+</div>
+
+<div style="width: 658px">
+	<div class="contain">
+		<div class="side caption" style="margin-left: 157px"></div
 		><div class="side t" style="margin-left: 100px"></div>
 	</div>
 </div>
 
 <div style="width: 657px">
 	<div class="contain">
-		<div class="side caption" style="margin-left: 56px"></div
-		><div class="side t" style="margin-left: 100px"></div>
-	</div>
-</div>
-
-<div style="width: 656px">
-	<div class="contain">
-		<div class="side caption" style="margin-left: 56px"></div
-		><div class="side t" style="margin-left: 100px"></div>
-	</div>
-</div>
-
-<div style="width: 655px">
-	<div class="contain">
-		<div class="pushed"></div>
-		<div class="side caption" style="margin-left: 56px"></div
-		><div class="side t" style="margin-left: 100px"></div>
-	</div>
-</div>
-
-<div style="width: 658px">
-	<div class="contain">
-		<div class="side caption" style="margin-left: 57px"></div
-		><div class="side t" style="margin-left: 100px"></div>
-	</div>
-</div>
-
-<div style="width: 657px">
-	<div class="contain">
-		<div class="side caption" style="margin-left: 57px"></div
+		<div class="side caption" style="margin-left: 157px"></div
 		><div class="side t" style="margin-left: 100px"></div>
 	</div>
 </div>
 
 <div style="width: 656px">
 	<div class="contain">
 		<div class="pushed"></div>
-		<div class="side caption" style="margin-left: 57px"></div
+		<div class="side caption" style="margin-left: 157px"></div
 		><div class="side t" style="margin-left: 100px"></div>
 	</div>
 </div>
 
 <div style="width: 657px">
 	<div class="contain">
 		<div class="side t" style="margin-left: 56px"></div
 		><div class="side caption" style="margin-left: 100px"></div>
@@ -363,307 +363,307 @@
 <div style="width: 656px">
 	<div class="contain">
 		<div class="pushed"></div>
 		<div class="side t" style="margin-left: 57px"></div
 		><div class="side caption" style="margin-left: 100px"></div>
 	</div>
 </div>
 
-<div style="width: 338px">
+<div style="width: 425px">
 	<div class="contain rtl">
-		<div class="t" style="margin-left: 65px"></div>
-		<div class="caption" style="margin-left: -15px"></div>
+		<div class="t" style="margin-left: 152px"></div>
+		<div class="caption" style="margin-left: 72px"></div>
 	</div>
 </div>
 
-<div style="width: 337px">
+<div style="width: 424px">
 	<div class="contain rtl">
-		<div class="t" style="margin-left: 64px"></div>
-		<div class="caption" style="margin-left: -16px"></div>
+		<div class="t" style="margin-left: 151px"></div>
+		<div class="caption" style="margin-left: 71px"></div>
 	</div>
 </div>
 
-<div style="width: 336px">
+<div style="width: 423px">
 	<div class="contain rtl">
 		<div class="pushed"></div>
-		<div class="t" style="margin-left: 64px"></div>
-		<div class="caption" style="margin-left: -16px"></div>
+		<div class="t" style="margin-left: 151px"></div>
+		<div class="caption" style="margin-left: 71px"></div>
 	</div>
 </div>
 
-<div style="width: 337px">
+<div style="width: 425px">
 	<div class="contain rtl">
-		<div class="caption" style="margin-left: -16px"></div>
-		<div class="t" style="margin-left: 64px"></div>
+		<div class="caption" style="margin-left: 72px"></div>
+		<div class="t" style="margin-left: 152px"></div>
 	</div>
 </div>
 
-<div style="width: 336px">
+<div style="width: 424px">
 	<div class="contain rtl">
-		<div class="caption" style="margin-left: -17px"></div>
-		<div class="t" style="margin-left: 63px"></div>
+		<div class="caption" style="margin-left: 71px"></div>
+		<div class="t" style="margin-left: 151px"></div>
 	</div>
 </div>
 
-<div style="width: 335px">
+<div style="width: 423px">
 	<div class="contain rtl">
 		<div class="pushed"></div>
-		<div class="caption" style="margin-left: -18px"></div>
-		<div class="t" style="margin-left: 62px"></div>
+		<div class="caption" style="margin-left: 70px"></div>
+		<div class="t" style="margin-left: 150px"></div>
 	</div>
 </div>
 
-<div style="width: 337px">
+<div style="width: 426px">
 	<div class="contain rtl">
-		<div class="t" style="margin-left: 63px"></div>
-		<div class="caption" style="margin-left: -17px"></div>
+		<div class="t" style="margin-left: 152px"></div>
+		<div class="caption" style="margin-left: 72px"></div>
 	</div>
 </div>
 
-<div style="width: 336px">
+<div style="width: 425px">
 	<div class="contain rtl">
-		<div class="t" style="margin-left: 62px"></div>
-		<div class="caption" style="margin-left: -18px"></div>
+		<div class="t" style="margin-left: 151px"></div>
+		<div class="caption" style="margin-left: 71px"></div>
 	</div>
 </div>
 
-<div style="width: 335px">
+<div style="width: 424px">
 	<div class="contain rtl">
 		<div class="pushed"></div>
-		<div class="t" style="margin-left: 61px"></div>
-		<div class="caption" style="margin-left: -19px"></div>
+		<div class="t" style="margin-left: 150px"></div>
+		<div class="caption" style="margin-left: 70px"></div>
 	</div>
 </div>
 
-<div style="width: 330px">
+<div style="width: 418px">
 	<div class="contain rtl">
-		<div class="caption" style="margin-left: 57px"></div>
-		<div class="t" style="margin-left: 57px"></div>
+		<div class="caption" style="margin-left: 72px"></div>
+		<div class="t" style="margin-left: 145px"></div>
 	</div>
 </div>
 
-<div style="width: 329px">
+<div style="width: 417px">
 	<div class="contain rtl">
-		<div class="caption" style="margin-left: 56px"></div>
-		<div class="t" style="margin-left: 56px"></div>
+		<div class="caption" style="margin-left: 71px"></div>
+		<div class="t" style="margin-left: 144px"></div>
 	</div>
 </div>
 
-<div style="width: 328px">
+<div style="width: 416px">
 	<div class="contain rtl">
 		<div class="pushed"></div>
-		<div class="caption" style="margin-left: 55px"></div>
-		<div class="t" style="margin-left: 55px"></div>
+		<div class="caption" style="margin-left: 70px"></div>
+		<div class="t" style="margin-left: 143px"></div>
 	</div>
 </div>
 
-<div style="width: 331px">
+<div style="width: 418px">
 	<div class="contain rtl">
-		<div class="t" style="margin-left: 58px"></div>
-		<div class="caption" style="margin-left: 57px"></div>
+		<div class="t" style="margin-left: 145px"></div>
+		<div class="caption" style="margin-left: 72px"></div>
 	</div>
 </div>
 
-<div style="width: 330px">
+<div style="width: 417px">
 	<div class="contain rtl">
-		<div class="t" style="margin-left: 57px"></div>
-		<div class="caption" style="margin-left: 56px"></div>
+		<div class="t" style="margin-left: 144px"></div>
+		<div class="caption" style="margin-left: 71px"></div>
 	</div>
 </div>
 
-<div style="width: 329px">
+<div style="width: 416px">
 	<div class="contain rtl">
 		<div class="pushed"></div>
-		<div class="t" style="margin-left: 57px"></div>
-		<div class="caption" style="margin-left: 56px"></div>
+		<div class="t" style="margin-left: 144px"></div>
+		<div class="caption" style="margin-left: 71px"></div>
 	</div>
 </div>
 
-<div style="width: 331px">
+<div style="width: 417px">
 	<div class="contain rtl">
-		<div class="t" style="margin-left: 57px"></div>
-		<div class="caption" style="margin-left: 58px"></div>
+		<div class="t" style="margin-left: 144px"></div>
+		<div class="caption" style="margin-left: 72px"></div>
 	</div>
 </div>
 
-<div style="width: 330px">
+<div style="width: 416px">
 	<div class="contain rtl">
-		<div class="t" style="margin-left: 56px"></div>
-		<div class="caption" style="margin-left: 57px"></div>
+		<div class="t" style="margin-left: 143px"></div>
+		<div class="caption" style="margin-left: 71px"></div>
 	</div>
 </div>
 
-<div style="width: 329px">
+<div style="width: 415px">
 	<div class="contain rtl">
 		<div class="pushed"></div>
-		<div class="t" style="margin-left: 56px"></div>
-		<div class="caption" style="margin-left: 57px"></div>
+		<div class="t" style="margin-left: 142px"></div>
+		<div class="caption" style="margin-left: 70px"></div>
 	</div>
 </div>
 
-<div style="width: 330px">
+<div style="width: 417px">
 	<div class="contain rtl">
-		<div class="caption" style="margin-left: 57px"></div>
-		<div class="t" style="margin-left: 57px"></div>
+		<div class="caption" style="margin-left: 72px"></div>
+		<div class="t" style="margin-left: 144px"></div>
 	</div>
 </div>
 
-<div style="width: 329px">
+<div style="width: 416px">
 	<div class="contain rtl">
-		<div class="caption" style="margin-left: 56px"></div>
-		<div class="t" style="margin-left: 56px"></div>
+		<div class="caption" style="margin-left: 71px"></div>
+		<div class="t" style="margin-left: 143px"></div>
 	</div>
 </div>
 
-<div style="width: 328px">
+<div style="width: 415px">
 	<div class="contain rtl">
 		<div class="pushed"></div>
-		<div class="caption" style="margin-left: 56px"></div>
-		<div class="t" style="margin-left: 56px"></div>
+		<div class="caption" style="margin-left: 71px"></div>
+		<div class="t" style="margin-left: 143px"></div>
 	</div>
 </div>
 
-<div style="width: 331px">
+<div style="width: 419px">
 	<div class="contain rtl">
-		<div class="t" style="margin-left: 57px"></div>
-		<div class="caption" style="margin-left: 58px"></div>
+		<div class="t" style="margin-left: 145px"></div>
+		<div class="caption" style="margin-left: 72px"></div>
 	</div>
 </div>
 
-<div style="width: 330px">
+<div style="width: 418px">
 	<div class="contain rtl">
-		<div class="t" style="margin-left: 56px"></div>
-		<div class="caption" style="margin-left: 57px"></div>
+		<div class="t" style="margin-left: 144px"></div>
+		<div class="caption" style="margin-left: 71px"></div>
 	</div>
 </div>
 
-<div style="width: 329px">
+<div style="width: 417px">
 	<div class="contain rtl">
 		<div class="pushed"></div>
-		<div class="t" style="margin-left: 55px"></div>
-		<div class="caption" style="margin-left: 56px"></div>
+		<div class="t" style="margin-left: 143px"></div>
+		<div class="caption" style="margin-left: 70px"></div>
 	</div>
 </div>
 
-<div style="width: 331px">
+<div style="width: 419px">
 	<div class="contain rtl">
-		<div class="caption" style="margin-left: 57px"></div>
-		<div class="t" style="margin-left: 58px"></div>
+		<div class="caption" style="margin-left: 72px"></div>
+		<div class="t" style="margin-left: 146px"></div>
 	</div>
 </div>
 
-<div style="width: 330px">
+<div style="width: 418px">
 	<div class="contain rtl">
-		<div class="caption" style="margin-left: 56px"></div>
-		<div class="t" style="margin-left: 57px"></div>
+		<div class="caption" style="margin-left: 71px"></div>
+		<div class="t" style="margin-left: 145px"></div>
 	</div>
 </div>
 
-<div style="width: 329px">
+<div style="width: 417px">
 	<div class="contain rtl">
 		<div class="pushed"></div>
-		<div class="caption" style="margin-left: 55px"></div>
-		<div class="t" style="margin-left: 56px"></div>
+		<div class="caption" style="margin-left: 70px"></div>
+		<div class="t" style="margin-left: 144px"></div>
 	</div>
 </div>
 
 <div style="width: 673px">
 	<div class="contain rtl">
 		<!-- margins showing up in the wrong places? -->
-		<div class="side caption" style="margin-left: 100px"></div
+		<div class="side caption" style="margin-left: 201px"></div
 		><div class="side t" style="margin-left: 72px"></div>
 	</div>
 </div>
 
 <div style="width: 672px">
 	<div class="contain rtl">
 		<!-- margins showing up in the wrong places? -->
-		<div class="side caption" style="margin-left: 100px"></div
+		<div class="side caption" style="margin-left: 200px"></div
 		><div class="side t" style="margin-left: 72px"></div>
 	</div>
 </div>
 
 <div style="width: 671px">
 	<div class="contain rtl">
 		<div class="pushed"></div>
 		<!-- margins showing up in the wrong places? -->
-		<div class="side caption" style="margin-left: 100px"></div
+		<div class="side caption" style="margin-left: 199px"></div
 		><div class="side t" style="margin-left: 72px"></div>
 	</div>
 </div>
 
 <div style="width: 674px">
 	<div class="contain rtl">
 		<!-- margins showing up in the wrong places? -->
-		<div class="side caption" style="margin-left: 100px"></div
+		<div class="side caption" style="margin-left: 201px"></div
 		><div class="side t" style="margin-left: 73px"></div>
 	</div>
 </div>
 
 <div style="width: 673px">
 	<div class="contain rtl">
 		<!-- margins showing up in the wrong places? -->
-		<div class="side caption" style="margin-left: 100px"></div
+		<div class="side caption" style="margin-left: 200px"></div
 		><div class="side t" style="margin-left: 73px"></div>
 	</div>
 </div>
 
 <div style="width: 672px">
 	<div class="contain rtl">
 		<div class="pushed"></div>
 		<!-- margins showing up in the wrong places? -->
-		<div class="side caption" style="margin-left: 100px"></div
+		<div class="side caption" style="margin-left: 199px"></div
 		><div class="side t" style="margin-left: 73px"></div>
 	</div>
 </div>
 
 <div style="width: 675px">
 	<div class="contain rtl">
 		<!-- margins showing up in the wrong places? -->
-		<div class="side caption" style="margin-left: 100px"></div
+		<div class="side caption" style="margin-left: 201px"></div
 		><div class="side t" style="margin-left: 74px"></div>
 	</div>
 </div>
 
 <div style="width: 674px">
 	<div class="contain rtl">
 		<!-- margins showing up in the wrong places? -->
-		<div class="side caption" style="margin-left: 100px"></div
+		<div class="side caption" style="margin-left: 200px"></div
 		><div class="side t" style="margin-left: 74px"></div>
 	</div>
 </div>
 
 <div style="width: 673px">
 	<div class="contain rtl">
 		<div class="pushed"></div>
 		<!-- margins showing up in the wrong places? -->
-		<div class="side caption" style="margin-left: 100px"></div
+		<div class="side caption" style="margin-left: 199px"></div
 		><div class="side t" style="margin-left: 74px"></div>
 	</div>
 </div>
 
-<div style="width: 673px">
+<div style="width: 674px">
 	<div class="contain rtl">
 		<div class="side t" style="margin-left: 101px"></div
 		><div class="side caption" style="margin-left: 100px"></div>
 	</div>
 </div>
 
-<div style="width: 672px">
+<div style="width: 673px">
 	<div class="contain rtl">
 		<div class="side t" style="margin-left: 100px"></div
 		><div class="side caption" style="margin-left: 100px"></div>
 	</div>
 </div>
 
-<div style="width: 671px">
+<div style="width: 672px">
 	<div class="contain rtl">
 		<div class="pushed"></div>
-		<div class="side t" style="margin-left: 99px"></div
+		<div class="side t" style="margin-left: 100px"></div
 		><div class="side caption" style="margin-left: 100px"></div>
 	</div>
 </div>
 
 <div style="width: 674px">
 	<div class="contain rtl">
 		<div class="side t" style="margin-left: 101px"></div
 		><div class="side caption" style="margin-left: 100px"></div>
--- a/layout/reftests/bugs/427129-table-caption.html
+++ b/layout/reftests/bugs/427129-table-caption.html
@@ -41,324 +41,313 @@
 
   To test the behavior under resizing, every test in this page is
   repeated three times, once in a container one pixel above the
   transition width, once at the transition width (just fitting), and
   once in a container a pixel below the transition width.
 
 -->
 
-<div style="width: 335px">
+<div style="width: 405px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 15px 0 55px; caption-side: bottom">
 			<caption style="margin: 0 15px 0 60px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 334px">
+<div style="width: 404px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 15px 0 55px; caption-side: bottom">
 			<caption style="margin: 0 15px 0 60px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 333px">
+<div style="width: 403px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 15px 0 55px; caption-side: bottom">
 			<caption style="margin: 0 15px 0 60px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 334px">
+<div style="width: 405px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 15px 0 56px; caption-side: top">
 			<caption style="margin: 0 15px 0 60px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 333px">
+<div style="width: 404px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 15px 0 56px; caption-side: top">
 			<caption style="margin: 0 15px 0 60px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 332px">
+<div style="width: 403px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 15px 0 56px; caption-side: top">
 			<caption style="margin: 0 15px 0 60px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 334px">
+<div style="width: 406px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 15px 0 57px; caption-side: bottom">
 			<caption style="margin: 0 15px 0 60px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 333px">
+<div style="width: 405px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 15px 0 57px; caption-side: bottom">
 			<caption style="margin: 0 15px 0 60px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 332px">
+<div style="width: 404px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 15px 0 57px; caption-side: bottom">
 			<caption style="margin: 0 15px 0 60px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 330px">
+<div style="width: 401px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 15px 0 56px; caption-side: top-outside">
 			<caption style="margin: 0 15px 0 56px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 329px">
+<div style="width: 400px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 15px 0 56px; caption-side: top-outside">
 			<caption style="margin: 0 15px 0 56px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 328px">
+<div style="width: 399px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 15px 0 56px; caption-side: top-outside">
 			<caption style="margin: 0 15px 0 56px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 331px">
+<div style="width: 401px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 15px 0 55px; caption-side: bottom-outside">
 			<caption style="margin: 0 15px 0 56px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 330px">
+<div style="width: 400px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 15px 0 55px; caption-side: bottom-outside">
 			<caption style="margin: 0 15px 0 56px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 329px">
+<div style="width: 399px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 15px 0 55px; caption-side: bottom-outside">
 			<caption style="margin: 0 15px 0 56px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 331px">
+<div style="width: 400px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 15px 0 56px; caption-side: bottom-outside">
 			<caption style="margin: 0 15px 0 55px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 330px">
+<div style="width: 399px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 15px 0 56px; caption-side: bottom-outside">
 			<caption style="margin: 0 15px 0 55px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 329px">
+<div style="width: 398px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 15px 0 56px; caption-side: bottom-outside">
 			<caption style="margin: 0 15px 0 55px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 330px">
-	<div class="contain">
-		<div class="fl"></div>
-		<div class="fr"></div>
-		<table class="t" style="margin: 0 15px 0 55px; caption-side: top-outside">
-			<caption style="margin: 0 15px 0 55px"></caption>
-			<tr><td></td></tr>
-		</table>
-	</div>
-</div>
-
-<div style="width: 329px">
+<div style="width: 400px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 15px 0 55px; caption-side: top-outside">
 			<caption style="margin: 0 15px 0 55px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 328px">
+<div style="width: 399px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 15px 0 55px; caption-side: top-outside">
 			<caption style="margin: 0 15px 0 55px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 331px">
+<div style="width: 398px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
-		<table class="t" style="margin: 0 15px 0 57px; caption-side: bottom-outside">
-			<caption style="margin: 0 15px 0 56px"></caption>
+		<table class="t" style="margin: 0 15px 0 55px; caption-side: top-outside">
+			<caption style="margin: 0 15px 0 55px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 330px">
+<div style="width: 402px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 15px 0 57px; caption-side: bottom-outside">
 			<caption style="margin: 0 15px 0 56px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 329px">
+<div style="width: 401px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 15px 0 57px; caption-side: bottom-outside">
 			<caption style="margin: 0 15px 0 56px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 331px">
+<div style="width: 400px">
+	<div class="contain">
+		<div class="fl"></div>
+		<div class="fr"></div>
+		<table class="t" style="margin: 0 15px 0 57px; caption-side: bottom-outside">
+			<caption style="margin: 0 15px 0 56px"></caption>
+			<tr><td></td></tr>
+		</table>
+	</div>
+</div>
+
+<div style="width: 402px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 15px 0 56px; caption-side: top-outside">
 			<caption style="margin: 0 15px 0 57px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 330px">
+<div style="width: 401px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 15px 0 56px; caption-side: top-outside">
 			<caption style="margin: 0 15px 0 57px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 329px">
+<div style="width: 400px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 15px 0 56px; caption-side: top-outside">
 			<caption style="margin: 0 15px 0 57px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 657px">
-	<div class="contain">
-		<div class="fl"></div>
-		<div class="fr"></div>
-		<table class="t" style="margin: 0 100px 0 100px; caption-side: left">
-			<caption style="margin: 0 100px 0 55px"></caption>
-			<tr><td></td></tr>
-		</table>
-	</div>
-</div>
-
 <div style="width: 656px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 100px 0 100px; caption-side: left">
 			<caption style="margin: 0 100px 0 55px"></caption>
 			<tr><td></td></tr>
 		</table>
@@ -371,16 +360,27 @@
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 100px 0 100px; caption-side: left">
 			<caption style="margin: 0 100px 0 55px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
+<div style="width: 654px">
+	<div class="contain">
+		<div class="fl"></div>
+		<div class="fr"></div>
+		<table class="t" style="margin: 0 100px 0 100px; caption-side: left">
+			<caption style="margin: 0 100px 0 55px"></caption>
+			<tr><td></td></tr>
+		</table>
+	</div>
+</div>
+
 <div style="width: 657px">
 	<div class="contain">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 100px 0 100px; caption-side: left">
 			<caption style="margin: 0 100px 0 56px"></caption>
 			<tr><td></td></tr>
 		</table>
@@ -536,303 +536,303 @@
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 100px 0 57px; caption-side: right">
 			<caption style="margin: 0 100px 0 100px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 338px">
+<div style="width: 425px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 72px 0 15px; caption-side: bottom">
 			<caption style="margin: 0 80px 0 15px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 337px">
+<div style="width: 424px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 72px 0 15px; caption-side: bottom">
 			<caption style="margin: 0 80px 0 15px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 336px">
+<div style="width: 423px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 72px 0 15px; caption-side: bottom">
 			<caption style="margin: 0 80px 0 15px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 337px">
+<div style="width: 425px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 73px 0 15px; caption-side: top">
 			<caption style="margin: 0 80px 0 15px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 336px">
+<div style="width: 424px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 73px 0 15px; caption-side: top">
 			<caption style="margin: 0 80px 0 15px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 335px">
+<div style="width: 423px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 73px 0 15px; caption-side: top">
 			<caption style="margin: 0 80px 0 15px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 337px">
+<div style="width: 426px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 74px 0 15px; caption-side: bottom">
 			<caption style="margin: 0 80px 0 15px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 336px">
+<div style="width: 425px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 74px 0 15px; caption-side: bottom">
 			<caption style="margin: 0 80px 0 15px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 335px">
+<div style="width: 424px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 74px 0 15px; caption-side: bottom">
 			<caption style="margin: 0 80px 0 15px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 330px">
+<div style="width: 418px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 73px 0 15px; caption-side: top-outside">
 			<caption style="margin: 0 73px 0 15px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 329px">
+<div style="width: 417px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 73px 0 15px; caption-side: top-outside">
 			<caption style="margin: 0 73px 0 15px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 328px">
+<div style="width: 416px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 73px 0 15px; caption-side: top-outside">
 			<caption style="margin: 0 73px 0 15px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 331px">
+<div style="width: 418px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 72px 0 15px; caption-side: bottom-outside">
 			<caption style="margin: 0 73px 0 15px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 330px">
+<div style="width: 417px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 72px 0 15px; caption-side: bottom-outside">
 			<caption style="margin: 0 73px 0 15px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 329px">
+<div style="width: 416px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 72px 0 15px; caption-side: bottom-outside">
 			<caption style="margin: 0 73px 0 15px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 331px">
+<div style="width: 417px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 73px 0 15px; caption-side: bottom-outside">
 			<caption style="margin: 0 72px 0 15px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 330px">
+<div style="width: 416px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 73px 0 15px; caption-side: bottom-outside">
 			<caption style="margin: 0 72px 0 15px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 329px">
+<div style="width: 415px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 73px 0 15px; caption-side: bottom-outside">
 			<caption style="margin: 0 72px 0 15px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 330px">
+<div style="width: 417px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 72px 0 15px; caption-side: top-outside">
 			<caption style="margin: 0 72px 0 15px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 329px">
+<div style="width: 416px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 72px 0 15px; caption-side: top-outside">
 			<caption style="margin: 0 72px 0 15px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 328px">
+<div style="width: 415px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 72px 0 15px; caption-side: top-outside">
 			<caption style="margin: 0 72px 0 15px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 331px">
+<div style="width: 419px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 74px 0 15px; caption-side: bottom-outside">
 			<caption style="margin: 0 73px 0 15px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 330px">
+<div style="width: 418px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 74px 0 15px; caption-side: bottom-outside">
 			<caption style="margin: 0 73px 0 15px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 329px">
+<div style="width: 417px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 74px 0 15px; caption-side: bottom-outside">
 			<caption style="margin: 0 73px 0 15px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 331px">
+<div style="width: 419px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 73px 0 15px; caption-side: top-outside">
 			<caption style="margin: 0 74px 0 15px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 330px">
+<div style="width: 418px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 73px 0 15px; caption-side: top-outside">
 			<caption style="margin: 0 74px 0 15px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 329px">
+<div style="width: 417px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 73px 0 15px; caption-side: top-outside">
 			<caption style="margin: 0 74px 0 15px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
@@ -932,16 +932,27 @@
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 100px 0 100px; caption-side: left">
 			<caption style="margin: 0 74px 0 100px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
+<div style="width: 674px">
+	<div class="contain rtl">
+		<div class="fl"></div>
+		<div class="fr"></div>
+		<table class="t" style="margin: 0 72px 0 100px; caption-side: right">
+			<caption style="margin: 0 100px 0 100px"></caption>
+			<tr><td></td></tr>
+		</table>
+	</div>
+</div>
+
 <div style="width: 673px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 72px 0 100px; caption-side: right">
 			<caption style="margin: 0 100px 0 100px"></caption>
 			<tr><td></td></tr>
 		</table>
@@ -954,27 +965,16 @@
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 72px 0 100px; caption-side: right">
 			<caption style="margin: 0 100px 0 100px"></caption>
 			<tr><td></td></tr>
 		</table>
 	</div>
 </div>
 
-<div style="width: 671px">
-	<div class="contain rtl">
-		<div class="fl"></div>
-		<div class="fr"></div>
-		<table class="t" style="margin: 0 72px 0 100px; caption-side: right">
-			<caption style="margin: 0 100px 0 100px"></caption>
-			<tr><td></td></tr>
-		</table>
-	</div>
-</div>
-
 <div style="width: 674px">
 	<div class="contain rtl">
 		<div class="fl"></div>
 		<div class="fr"></div>
 		<table class="t" style="margin: 0 73px 0 100px; caption-side: right">
 			<caption style="margin: 0 100px 0 100px"></caption>
 			<tr><td></td></tr>
 		</table>
--- a/layout/reftests/bugs/478614-1-ref.html
+++ b/layout/reftests/bugs/478614-1-ref.html
@@ -1,13 +1,14 @@
 <!DOCTYPE html>
 <html>
 <head>
 <title>Testcase for table + caption vertical margins (bug 478614)</title>
 <style type="text/css">
+body {margin-top: 0} /* Don't let collapsing of the body's top margin interfere with positioning */
 caption {margin-top: 150px}
 table {width:100px}
 </style>
 </head>
 <body>
 <table><caption>caption</caption>
 <tr><td>td</td></tr>
 </table>
--- a/layout/reftests/bugs/478614-1.html
+++ b/layout/reftests/bugs/478614-1.html
@@ -1,13 +1,14 @@
 <!DOCTYPE html>
 <html>
 <head>
 <title>Testcase for table + caption vertical margins (bug 478614)</title>
 <style type="text/css">
+body {margin-top: 0} /* Don't let collapsing of the body's top margin interfere with positioning */
 caption {margin-top: 50px;}
 table {margin-top: 100px; width:100px}
 </style>
 </head>
 <body>
 <table><caption>caption</caption>
 <tr><td>td</td></tr>
 </table>
--- a/layout/reftests/bugs/478614-2.html
+++ b/layout/reftests/bugs/478614-2.html
@@ -1,13 +1,14 @@
 <!DOCTYPE html>
 <html>
 <head>
 <title>Testcase for table + caption vertical margins (bug 478614)</title>
 <style type="text/css">
+body {margin-top: 0} /* Don't let collapsing of the body's top margin interfere with positioning */
 caption {margin-top: 50px; caption-side:top}
 table {margin-top: 100px; width:100px}
 </style>
 </head>
 <body>
 <table><caption>caption</caption>
 <tr><td>td</td></tr>
 </table>
--- a/layout/reftests/bugs/478614-3-ref.html
+++ b/layout/reftests/bugs/478614-3-ref.html
@@ -1,13 +1,14 @@
 <!DOCTYPE html>
 <html>
 <head>
 <title>Testcase for table + caption vertical margins (bug 478614)</title>
 <style type="text/css">
+body {margin-top: 0} /* Don't let collapsing of the body's top margin interfere with positioning */
 caption { caption-side:bottom;}
 table {100px; width:100px;}
 </style>
 </head>
 <body>
 <table><caption>caption</caption>
 <tr><td>td</td></tr>
 </table>
--- a/layout/reftests/bugs/478614-3.html
+++ b/layout/reftests/bugs/478614-3.html
@@ -1,13 +1,14 @@
 <!DOCTYPE html>
 <html>
 <head>
 <title>Testcase for table + caption vertical margins (bug 478614)</title>
 <style type="text/css">
+body {margin-top: 0} /* Don't let collapsing of the body's top margin interfere with positioning */
 caption {margin-bottom: 100px; caption-side:bottom;}
 table {margin-bottom: 100px; width:100px;}
 </style>
 </head>
 <body>
 <table><caption>caption</caption>
 <tr><td>td</td></tr>
 </table>
--- a/layout/reftests/bugs/478614-4-ref.html
+++ b/layout/reftests/bugs/478614-4-ref.html
@@ -1,13 +1,14 @@
 <!DOCTYPE html>
 <html>
 <head>
 <title>Testcase for table + caption vertical margins (bug 478614)</title>
 <style type="text/css">
+body {margin-top: 0} /* Don't let collapsing of the body's top margin interfere with positioning */
 caption {margin-top: 160px;margin-bottom:50px}
 table {width:100px}
 </style>
 </head>
 <body>
 <table><caption>caption</caption>
 <tr><td>td</td></tr>
 </table>
--- a/layout/reftests/bugs/478614-4.html
+++ b/layout/reftests/bugs/478614-4.html
@@ -1,13 +1,14 @@
 <!DOCTYPE html>
 <html>
 <head>
 <title>Testcase for table + caption vertical margins (bug 478614)</title>
 <style type="text/css">
+body {margin-top: 0} /* Don't let collapsing of the body's top margin interfere with positioning */
 caption {margin-top: 60px;margin-bottom:50px}
 table {margin-top: 100px; width:100px}
 </style>
 </head>
 <body>
 <table><caption>caption</caption>
 <tr><td>td</td></tr>
 </table>
--- a/layout/reftests/bugs/478614-5-ref.html
+++ b/layout/reftests/bugs/478614-5-ref.html
@@ -1,13 +1,14 @@
 <!DOCTYPE html>
 <html>
 <head>
 <title>Testcase for table + caption vertical margins (bug 478614)</title>
 <style type="text/css">
+body {margin-top: 0} /* Don't let collapsing of the body's top margin interfere with positioning */
 caption {margin-top:50px; caption-side:bottom}
 table {width:100px}
 </style>
 </head>
 <body>
 <table><caption>caption</caption>
 <tr><td>td</td></tr>
 </table>
--- a/layout/reftests/bugs/478614-5.html
+++ b/layout/reftests/bugs/478614-5.html
@@ -1,13 +1,14 @@
 <!DOCTYPE html>
 <html>
 <head>
 <title>Testcase for table + caption vertical margins (bug 478614)</title>
 <style type="text/css">
+body {margin-top: 0} /* Don't let collapsing of the body's top margin interfere with positioning */
 caption {margin-bottom: 100px;margin-top:50px; caption-side:bottom}
 table {margin-bottom: 100px; width:100px}
 </style>
 </head>
 <body>
 <table><caption>caption</caption>
 <tr><td>td</td></tr>
 </table>
--- a/layout/reftests/bugs/478614-6-ref.html
+++ b/layout/reftests/bugs/478614-6-ref.html
@@ -1,14 +1,15 @@
 <!DOCTYPE html>
 <html>
 <head>
 <title>Testcase for table + caption vertical margins (bug 478614)</title>
 <style type="text/css">
-caption {margin-top: 100px;margin-bottom:50px;caption-side:top-outside}
+body {margin-top: 0} /* Don't let collapsing of the body's top margin interfere with positioning */
+caption {margin-top: 150px;caption-side:top-outside}
 table { width:100px}
 </style>
 </head>
 <body>
 <table><caption>caption</caption>
 <tr><td>td</td></tr>
 </table>
 </body>
--- a/layout/reftests/bugs/478614-6.html
+++ b/layout/reftests/bugs/478614-6.html
@@ -1,13 +1,14 @@
 <!DOCTYPE html>
 <html>
 <head>
 <title>Testcase for table + caption vertical margins (bug 478614)</title>
 <style type="text/css">
+body {margin-top: 0} /* Don't let collapsing of the body's top margin interfere with positioning */
 caption {margin-top: 100px;caption-side:top-outside}
 table {margin-top: 50px; width:100px}
 </style>
 </head>
 <body>
 <table><caption>caption</caption>
 <tr><td>td</td></tr>
 </table>
--- a/layout/reftests/bugs/478614-7-ref.html
+++ b/layout/reftests/bugs/478614-7-ref.html
@@ -1,15 +1,18 @@
 <!DOCTYPE html>
 <html>
 <head>
 <title>Testcase for table + caption vertical margins (bug 478614)</title>
 <style type="text/css">
+body {margin-top: 0} /* Don't let collapsing of the body's top margin interfere with positioning */
 caption {margin-top: 50px;caption-side:bottom-outside}
-table {width:100px}
+table {width:100px;}
+div {margin-top: 150px;}
 </style>
 </head>
 <body>
 <table><caption>caption</caption>
 <tr><td>td</td></tr>
 </table>
+<div>block</div>
 </body>
 </html>
--- a/layout/reftests/bugs/478614-7.html
+++ b/layout/reftests/bugs/478614-7.html
@@ -1,15 +1,17 @@
 <!DOCTYPE html>
 <html>
 <head>
 <title>Testcase for table + caption vertical margins (bug 478614)</title>
 <style type="text/css">
-caption {margin-top: 50px;caption-side:bottom-outside}
+body {margin-top: 0} /* Don't let collapsing of the body's top margin interfere with positioning */
+caption {margin-top: 50px; margin-bottom: 100px; caption-side:bottom-outside}
 table {margin-bottom: 50px; width:100px}
 </style>
 </head>
 <body>
 <table><caption>caption</caption>
 <tr><td>td</td></tr>
 </table>
+<div>block</div>
 </body>
 </html>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -13,16 +13,19 @@
 == 9458-width-2a.html 9458-width-2-ref.html
 == 9458-width-2b.html 9458-width-2-ref.html
 == 9458-zorder-1.html 9458-zorder-ref.html
 == 9458-zorder-2.html 9458-zorder-ref.html
 == 9458-zorder-3.html 9458-zorder-ref-inline.html
 == 9458-zorder-4.html 9458-zorder-ref-inline-block.html
 == 9458-zorder-5.html 9458-zorder-ref-inline-block.html
 == 10036-1.html 10036-1-ref.html
+skip-if(!cocoaWidget) HTTP(..) == 10209-1.html 10209-ref.html # Bug 667079
+HTTP(..) == 10209-2.html 10209-ref.html
+asserts(4) skip-if(!cocoaWidget) HTTP(..) == 10209-3.html 10209-3-ref.html # Assertions: bug 666606, skip because of bug 667079
 == 18217-basic-1.html 18217-basic-1-ref.html
 == 18217-basic-2a.html 18217-basic-2-ref.html
 == 18217-basic-2b.html 18217-basic-2-ref.html
 == 18217-valign-1.html 18217-valign-1-ref.html
 == 18217-height-1.html 18217-height-1-ref.html
 == 18217-height-2.html 18217-height-2-ref.html
 == 18217-width-1a.html 18217-width-1-ref.html
 == 18217-width-1b.html 18217-width-1-ref.html
@@ -1432,17 +1435,17 @@ random-if(d2d) == 523468-1.html 523468-1
 == 526463-1.html 526463-1-ref.html
 == 527464-1.html 527464-ref.html
 == 528038-1a.html 528038-1-ref.html
 == 528038-1b.html 528038-1-ref.html
 == 528038-1c.html 528038-1-ref.html
 == 528038-1d.html 528038-1-ref.html
 == 528038-1e.html 528038-1-ref.html
 == 528038-1f.html 528038-1-ref.html
-asserts(5) == 528038-2.html 528038-2-ref.html # bug 512749
+== 528038-2.html 528038-2-ref.html
 == 528096-1.html 528096-1-ref.html
 == 530686-1.html 530686-1-ref.html
 == 531098-1.html 531098-1-ref.html
 == 531371-1.html 531371-1-ref.html
 == 534526-1a.html 534526-1-ref.html
 == 534526-1b.html 534526-1-ref.html
 == 534804-1.html 534804-1-ref.html
 == 534808-1.html 534808-1-ref.html
@@ -1630,17 +1633,17 @@ skip-if(Android) == 632781-verybig.html 
 == 633344-1.html 633344-1-ref.html
 fails-if(Android) == 634232-1.html 634232-1-ref.html
 fails-if(Android) == 635302-1.html 635302-1-ref.html
 == 635373-1.html 635373-1-ref.html
 == 635373-2.html 635373-2-ref.html
 fails-if(http.platform=="X11"&&!layersGPUAccelerated) == 635373-3.html 635373-3-ref.html
 HTTP(..) == 635639-1.html 635639-1-ref.html
 HTTP(..) == 635639-2.html 635639-2-ref.html
-== 637597-1.html 637597-1-ref.html
+random == 637597-1.html 637597-1-ref.html # bug 637597 was never really fixed!
 == 637852-1.html 637852-1-ref.html
 == 637852-2.html 637852-2-ref.html
 == 637852-3.html 637852-3-ref.html
 == 641770-1.html 641770-1-ref.html
 == 641856-1.html 641856-1-ref.html
 == 645491-1.html 645491-1-ref.html
 == 652301-1a.html 652301-1-ref.html
 == 652301-1b.html 652301-1-ref.html
--- a/layout/reftests/first-line/reftest.list
+++ b/layout/reftests/first-line/reftest.list
@@ -11,17 +11,17 @@ fails == out-of-flow-1d.html out-of-flow
 == parent-style-1.html parent-style-1-ref.html
 == parent-style-2.html parent-style-2-ref.html
 == parent-style-3.html parent-style-3-ref.html
 
 # stress-tests
 load stress-1.html # assertion test
 == stress-2.html stress-2-ref.html # assertion + rendering test
 load stress-3.html # assertion test
-asserts(2) load stress-4.html # assertion/crash test. existing assertions are bug 512749.
+load stress-4.html # assertion/crash test.
 load stress-5.html # assertion/crash test
 load stress-6.html # assertion/crash test
 load stress-7.html # assertion/crash test
 == stress-8.html stress-8-ref.html # assertion/crash test
 == stress-9.html stress-9-ref.html # assertion/crash test
 load stress-10.html # crash test
 == stress-11.xhtml stress-11-ref.xhtml
 
new file mode 100644
--- /dev/null
+++ b/layout/reftests/floats/border-box-wrap-around-float-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <style>
+      img { display: block; margin-left: 200px; height: 100px; width: 100px; }
+    </style>
+  </head>
+  <body>
+    <img src="../bugs/solidblue.png">
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/floats/border-box-wrap-around-float.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <style>
+      div { float: left; width: 200px; height: 200px; }
+      img { display: block; margin-left: 100px; height: 100px; width: 100px; }
+    </style>
+  </head>
+  <body>
+    <div></div>
+    <img src="../bugs/solidblue.png">
+  </body>
+</html>
--- a/layout/reftests/floats/reftest.list
+++ b/layout/reftests/floats/reftest.list
@@ -1,8 +1,9 @@
+== border-box-wrap-around-float.html border-box-wrap-around-float-ref.html
 == other-float-outside-rule-3-left.html other-float-outside-rule-3-left-ref.html
 == other-float-outside-rule-3-right.html other-float-outside-rule-3-right-ref.html
 fails == other-float-outside-rule-3-left-2.html other-float-outside-rule-3-left-2-ref.html # bug 616334
 fails == other-float-outside-rule-3-right-2.html other-float-outside-rule-3-right-2-ref.html # bug 616334
 fails == other-float-outside-rule-7-left.html other-float-outside-rule-7-left-ref.html # bug 616334
 fails == other-float-outside-rule-7-right.html other-float-outside-rule-7-right-ref.html # bug 616334
 == float-outside-block-push.html float-outside-block-push-ref.html
 == zero-height-float-base.html zero-height-float-ref.html
--- a/layout/reftests/margin-collapsing/reftest.list
+++ b/layout/reftests/margin-collapsing/reftest.list
@@ -133,42 +133,42 @@ fails-if(Android&&layersOpenGL) == block
 == block-overflow-5a.html block-overflow-5-ref.html
 == block-overflow-5a.html block-overflow-5-ref2.html
 == block-overflow-5b.html block-overflow-5-ref.html
 == block-overflow-5b.html block-overflow-5-ref2.html
 == block-overflow-5c.html block-overflow-5c-ref.html
 == block-overflow-5c.html block-overflow-5c-ref2.html
 == block-overflow-5d.html block-overflow-5-ref.html
 == block-overflow-5d.html block-overflow-5-ref2.html
-fails == table-sibling-1a.html table-sibling-1-ref.html # Bug 87277
-fails != table-sibling-1a.html table-sibling-1-noref.html # Bug 87277
-fails == table-sibling-1b.html table-sibling-1-ref.html # Bug 87277
-fails != table-sibling-1b.html table-sibling-1-noref.html # Bug 87277
-fails == table-sibling-1c.html table-sibling-1-ref.html # Bug 87277
-fails != table-sibling-1c.html table-sibling-1-noref2.html # Bug 87277
-fails == table-sibling-2a.html table-sibling-2-ref.html # Bug 87277
-fails != table-sibling-2a.html table-sibling-2-noref.html # Bug 87277
-fails == table-sibling-2b.html table-sibling-2-ref.html # Bug 87277
-fails != table-sibling-2b.html table-sibling-2-noref.html # Bug 87277
-fails == table-sibling-2c.html table-sibling-2-ref.html # Bug 87277
-fails != table-sibling-2c.html table-sibling-2-noref2.html # Bug 87277
-fails == table-sibling-1a-dyn.html table-sibling-1-ref.html # Bug 87277
-fails != table-sibling-1a-dyn.html table-sibling-1-noref.html # Bug 87277
-fails == table-sibling-1b-dyn.html table-sibling-1-ref.html # Bug 87277
-fails != table-sibling-1b-dyn.html table-sibling-1-noref.html # Bug 87277
-fails == table-sibling-1c-dyn.html table-sibling-1-ref.html # Bug 87277
-fails != table-sibling-1c-dyn.html table-sibling-1-noref2.html # Bug 87277
-fails == table-sibling-2a-dyn.html table-sibling-2-ref.html # Bug 87277
-fails != table-sibling-2a-dyn.html table-sibling-2-noref.html # Bug 87277
-fails == table-sibling-2b-dyn.html table-sibling-2-ref.html # Bug 87277
-fails != table-sibling-2b-dyn.html table-sibling-2-noref.html # Bug 87277
-fails == table-sibling-2c-dyn.html table-sibling-2-ref.html # Bug 87277
-fails != table-sibling-2c-dyn.html table-sibling-2-noref2.html # Bug 87277
-fails == table-sibling-3-dyn.html table-sibling-3-ref.html # Bug 87277
-fails != table-sibling-3-dyn.html table-sibling-3-noref.html # Bug 87277
+== table-sibling-1a.html table-sibling-1-ref.html
+!= table-sibling-1a.html table-sibling-1-noref.html
+== table-sibling-1b.html table-sibling-1-ref.html
+!= table-sibling-1b.html table-sibling-1-noref.html
+== table-sibling-1c.html table-sibling-1-ref.html
+!= table-sibling-1c.html table-sibling-1-noref2.html
+== table-sibling-2a.html table-sibling-2-ref.html
+!= table-sibling-2a.html table-sibling-2-noref.html
+== table-sibling-2b.html table-sibling-2-ref.html
+!= table-sibling-2b.html table-sibling-2-noref.html
+== table-sibling-2c.html table-sibling-2-ref.html
+!= table-sibling-2c.html table-sibling-2-noref2.html
+== table-sibling-1a-dyn.html table-sibling-1-ref.html
+!= table-sibling-1a-dyn.html table-sibling-1-noref.html
+== table-sibling-1b-dyn.html table-sibling-1-ref.html
+!= table-sibling-1b-dyn.html table-sibling-1-noref.html
+== table-sibling-1c-dyn.html table-sibling-1-ref.html
+!= table-sibling-1c-dyn.html table-sibling-1-noref2.html
+== table-sibling-2a-dyn.html table-sibling-2-ref.html
+!= table-sibling-2a-dyn.html table-sibling-2-noref.html
+== table-sibling-2b-dyn.html table-sibling-2-ref.html
+!= table-sibling-2b-dyn.html table-sibling-2-noref.html
+== table-sibling-2c-dyn.html table-sibling-2-ref.html
+!= table-sibling-2c-dyn.html table-sibling-2-noref2.html
+== table-sibling-3-dyn.html table-sibling-3-ref.html
+!= table-sibling-3-dyn.html table-sibling-3-noref.html
 == table-caption-1a.html table-caption-1-ref.html
 == table-caption-1b.html table-caption-1-ref.html
 == table-caption-2a.html table-caption-2-ref.html
 == table-caption-2b.html table-caption-2-ref.html
 == table-caption-2c.html table-caption-2-ref.html
 == table-caption-top-1.html table-caption-top-1-ref.html
 == table-caption-top-2.html table-caption-top-2-ref.html
 == table-caption-bottom-1.html table-caption-bottom-1-ref.html
--- a/layout/reftests/pagination/table-caption-splitaftercaption-1-ref.html
+++ b/layout/reftests/pagination/table-caption-splitaftercaption-1-ref.html
@@ -1,15 +1,15 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
 	"http://www.w3.org/TR/html4/strict.dtd">
 <html lang="en-US" class="reftest-print">
 <head>
 <style type="text/css">
-div.filler {height: 90px; width: 50px; border:thin solid blue;}
-div.spacer { height: 0px; width: 0px; padding: 20px;border:thin solid green;}
+div.filler {height: 1in; width: 0.5in; border:thin solid blue;}
+div.spacer { height: 0px; width: 0px; padding: 0.2in;border:thin solid green;}
 </style>
 </head>
 <body>
 <div class=filler></div>
 <table cellspacing="0" cellpadding="0" style="page-break-before:always">
 <caption><div class="spacer"></div></caption>
 <tbody>
 <tr><td><div class="spacer"></div></td></tr>
--- a/layout/reftests/pagination/table-caption-splitaftercaption-1.html
+++ b/layout/reftests/pagination/table-caption-splitaftercaption-1.html
@@ -1,15 +1,15 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
 	"http://www.w3.org/TR/html4/strict.dtd">
 <html lang="en-US" class="reftest-print">
 <head>
 <style type="text/css">
-div.filler {height: 90px; width: 50px; border:thin solid blue;}
-div.spacer { height: 0px; width: 0px; padding: 20px;border:thin solid green;}
+div.filler {height: 1in; width: 0.5in; border:thin solid blue;}
+div.spacer { height: 0px; width: 0px; padding: 0.2in;border:thin solid green;}
 </style>
 </head>
 <body>
 <div class=filler></div>
 <table cellspacing="0" cellpadding="0">
 <caption><div class="spacer"></div></caption>
 <tbody>
 <tr><td><div class="spacer"></div></td></tr>
--- a/layout/reftests/pagination/table-caption-splitaftercaption-2-ref.html
+++ b/layout/reftests/pagination/table-caption-splitaftercaption-2-ref.html
@@ -1,15 +1,15 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
 	"http://www.w3.org/TR/html4/strict.dtd">
 <html lang="en-US" class="reftest-print">
 <head>
 <style type="text/css">
-div.filler {height: 25px; width: 50px; border:thin solid blue;}
-div.spacer { height: 0px; width: 0px; padding: 20px;border:thin solid green;}
+div.filler {height: 0.5in; width: 0.5in; border:thin solid blue;}
+div.spacer { height: 0px; width: 0px; padding: 0.2in;border:thin solid green;}
 </style>
 </head>
 <body>
 <div class=filler></div>
 <table cellspacing="0" cellpadding="0">
 <caption><div class="spacer"></div></caption>
 <tbody>
 <tr><td><div class="spacer"></div></td></tr>
--- a/layout/reftests/pagination/table-caption-splitaftercaption-2.html
+++ b/layout/reftests/pagination/table-caption-splitaftercaption-2.html
@@ -1,15 +1,15 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
 	"http://www.w3.org/TR/html4/strict.dtd">
 <html lang="en-US" class="reftest-print">
 <head>
 <style type="text/css">
-div.filler {height:25px; width: 50px; border:thin solid blue;}
-div.spacer { height: 0px; width: 0px; padding: 20px;border:thin solid green;}
+div.filler {height: 0.5in; width: 0.5in; border:thin solid blue;}
+div.spacer { height: 0px; width: 0px; padding: 0.2in;border:thin solid green;}
 </style>
 </head>
 <body>
 <div class=filler></div>
 <table cellspacing="0" cellpadding="0">
 <caption><div class="spacer"></div></caption>
 <tbody>
 <tr><td><div class="spacer"></div></td></tr>
--- a/layout/reftests/pagination/table-caption-splitaftercaption-3-ref.html
+++ b/layout/reftests/pagination/table-caption-splitaftercaption-3-ref.html
@@ -1,16 +1,15 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
 	"http://www.w3.org/TR/html4/strict.dtd">
 <html lang="en-US" class="reftest-print">
 <head>
 <style type="text/css">
-div.filler {height: 25px; width: 50px; border:thin solid blue;}
-div.spacer { height: 0px; width: 0px; padding: 20px;border:thin solid green;}
-caption {margin-top: 10px; margin-bottom:20px}
+div.spacer { height: 0px; width: 0px; padding: 0.2in;border:thin solid green;}
+caption {margin-top: 0.1in; margin-bottom:0.2in}
 </style>
 </head>
 <body>
 
 <table cellspacing="0" cellpadding="0">
 <caption><div class="spacer"></div></caption>
 <tbody>
 <tr><td><div class="spacer"></div></td></tr>
--- a/layout/reftests/pagination/table-caption-splitaftercaption-3.html
+++ b/layout/reftests/pagination/table-caption-splitaftercaption-3.html
@@ -1,16 +1,15 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
 	"http://www.w3.org/TR/html4/strict.dtd">
 <html lang="en-US" class="reftest-print">
 <head>
 <style type="text/css">
-div.filler {height:5px; width: 50px; border:thin solid blue;}
-div.spacer { height: 0px; width: 0px; padding: 20px;border:thin solid green;}
-caption {margin-top: 10px; margin-bottom:20px}
+div.spacer { height: 0px; width: 0px; padding: 0.2in;border:thin solid green;}
+caption {margin-top: 0.1in; margin-bottom:0.2in}
 </style>
 </head>
 <body>
 
 <table cellspacing="0" cellpadding="0">
 <caption><div class="spacer"></div></caption>
 <tbody>
 <tr><td><div class="spacer"></div></td></tr>
--- a/layout/reftests/pagination/table-caption-splitaftercaption-4-ref.html
+++ b/layout/reftests/pagination/table-caption-splitaftercaption-4-ref.html
@@ -1,17 +1,16 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
 	"http://www.w3.org/TR/html4/strict.dtd">
 <html lang="en-US" class="reftest-print">
 <head>
 <style type="text/css">
-div.filler {height: 25px; width: 50px; border:thin solid blue;}
-div.spacer { height: 0px; width: 0px; padding: 20px;border:thin solid green;}
-caption {margin-top: 5px; margin-bottom:5px}
-table {margin-top: 5px; margin-bottom:5px}
+div.spacer { height: 0px; width: 0px; padding: 0.2in;border:thin solid green;}
+caption {margin-top: 0.15in; margin-bottom:0.15in}
+table {margin-top: 0.15in; margin-bottom:0.15in}
 </style>
 </head>
 <body>
 
 <table cellspacing="0" cellpadding="0">
 <caption><div class="spacer"></div></caption>
 <tbody>
 <tr><td><div class="spacer"></div></td></tr>
--- a/layout/reftests/pagination/table-caption-splitaftercaption-4.html
+++ b/layout/reftests/pagination/table-caption-splitaftercaption-4.html
@@ -1,17 +1,16 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
 	"http://www.w3.org/TR/html4/strict.dtd">
 <html lang="en-US" class="reftest-print">
 <head>
 <style type="text/css">
-div.filler {height:5px; width: 50px; border:thin solid blue;}
-div.spacer { height: 0px; width: 0px; padding: 20px;border:thin solid green;}
-caption {margin-top: 5px; margin-bottom:5px}
-table {margin-top: 5px; margin-bottom:5px}
+div.spacer { height: 0px; width: 0px; padding: 0.2in;border:thin solid green;}
+caption {margin-top: 0.15in; margin-bottom:0.15in}
+table {margin-top: 0.15in; margin-bottom:0.15in}
 </style>
 </head>
 <body>
 
 <table cellspacing="0" cellpadding="0">
 <caption><div class="spacer"></div></caption>
 <tbody>
 <tr><td><div class="spacer"></div></td></tr>
--- a/layout/reftests/pagination/table-caption-splitaftercaption-5-ref.html
+++ b/layout/reftests/pagination/table-caption-splitaftercaption-5-ref.html
@@ -1,17 +1,16 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
 	"http://www.w3.org/TR/html4/strict.dtd">
 <html lang="en-US" class="reftest-print">
 <head>
 <style type="text/css">
-div.filler {height: 25px; width: 50px; border:thin solid blue;}
-div.spacer { height: 0px; width: 0px; padding: 20px;border:thin solid green;}
-caption {margin-top: 5px; margin-bottom:5px; caption-side:bottom}
-table {margin-top: 5px; margin-bottom:5px}
+div.spacer { height: 0px; width: 0px; padding: 0.2in;border:thin solid green;}
+caption {margin-top: 0.15in; margin-bottom:0.15in; caption-side:bottom}
+table {margin-top: 0.15in; margin-bottom:0.15in}
 </style>
 </head>
 <body>
 
 <table cellspacing="0" cellpadding="0">
 <caption><div class="spacer"></div></caption>
 <tbody>
 <tr><td><div class="spacer"></div></td></tr>
--- a/layout/reftests/pagination/table-caption-splitaftercaption-5.html
+++ b/layout/reftests/pagination/table-caption-splitaftercaption-5.html
@@ -1,17 +1,16 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
 	"http://www.w3.org/TR/html4/strict.dtd">
 <html lang="en-US" class="reftest-print">
 <head>
 <style type="text/css">
-div.filler {height:5px; width: 50px; border:thin solid blue;}
-div.spacer { height: 0px; width: 0px; padding: 20px;border:thin solid green;}
-caption {margin-top: 5px; margin-bottom:5px; caption-side:bottom}
-table {margin-top: 5px; margin-bottom:5px}
+div.spacer { height: 0px; width: 0px; padding: 0.2in;border:thin solid green;}
+caption {margin-top: 0.15in; margin-bottom:0.15in; caption-side:bottom}
+table {margin-top: 0.15in; margin-bottom:0.15in}
 </style>
 </head>
 <body>
 
 <table cellspacing="0" cellpadding="0">
 <caption><div class="spacer"></div></caption>
 <tbody>
 <tr><td><div class="spacer"></div></td></tr>
--- a/layout/reftests/pagination/table-caption-splitaftercaption-6-ref.html
+++ b/layout/reftests/pagination/table-caption-splitaftercaption-6-ref.html
@@ -1,17 +1,16 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
 	"http://www.w3.org/TR/html4/strict.dtd">
 <html lang="en-US" class="reftest-print">
 <head>
 <style type="text/css">
-div.filler {height: 25px; width: 50px; border:thin solid blue;}
-div.spacer { height: 0px; width: 0px; padding: 20px;border:thin solid green;}
-caption {margin-top: 5px; margin-bottom:15px; caption-side:top-outside}
-table {margin-top: 5px; margin-bottom:5px}
+div.spacer { height: 0px; width: 0px; padding: 0.2in;border:thin solid green;}
+caption {margin-top: 0.1in; margin-bottom:0.3in; caption-side:top-outside}
+table {margin-top: 0.1in; margin-bottom:0.1in}
 </style>
 </head>
 <body>
 
 <table cellspacing="0" cellpadding="0">
 <caption><div class="spacer"></div></caption>
 <tbody>
 <tr><td><div class="spacer"></div></td></tr>
--- a/layout/reftests/pagination/table-caption-splitaftercaption-6.html
+++ b/layout/reftests/pagination/table-caption-splitaftercaption-6.html
@@ -1,17 +1,16 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
 	"http://www.w3.org/TR/html4/strict.dtd">
 <html lang="en-US" class="reftest-print">
 <head>
 <style type="text/css">
-div.filler {height:5px; width: 50px; border:thin solid blue;}
-div.spacer { height: 0px; width: 0px; padding: 20px;border:thin solid green;}
-caption {margin-top: 5px; margin-bottom:15px; caption-side:top-outside}
-table {margin-top: 5px; margin-bottom:5px}
+div.spacer { height: 0px; width: 0px; padding: 0.2in;border:thin solid green;}
+caption {margin-top: 0.1in; margin-bottom:0.3in; caption-side:top-outside}
+table {margin-top: 0.1in; margin-bottom:0.1in}
 </style>
 </head>
 <body>
 
 <table cellspacing="0" cellpadding="0">
 <caption><div class="spacer"></div></caption>
 <tbody>
 <tr><td><div class="spacer"></div></td></tr>
--- a/layout/reftests/pagination/table-caption-splitaftercaption-7-ref.html
+++ b/layout/reftests/pagination/table-caption-splitaftercaption-7-ref.html
@@ -1,17 +1,16 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
 	"http://www.w3.org/TR/html4/strict.dtd">
 <html lang="en-US" class="reftest-print">
 <head>
 <style type="text/css">
-div.filler {height: 25px; width: 50px; border:thin solid blue;}
-div.spacer { height: 0px; width: 0px; padding: 20px;border:thin solid green;}
-caption {margin-top: 5px; margin-bottom:15px; caption-side:bottom-outside}
-table {margin-top: 5px; margin-bottom:5px}
+div.spacer { height: 0px; width: 0px; padding: 0.2in;border:thin solid green;}
+caption {margin-top: 0.1in; margin-bottom:0.3in; caption-side:bottom-outside}
+table {margin-top: 0.1in; margin-bottom:0.1in}
 </style>
 </head>
 <body>
 
 <table cellspacing="0" cellpadding="0">
 <caption><div class="spacer"></div></caption>
 <tbody>
 <tr><td><div class="spacer"></div></td></tr>
--- a/layout/reftests/pagination/table-caption-splitaftercaption-7.html
+++ b/layout/reftests/pagination/table-caption-splitaftercaption-7.html
@@ -1,17 +1,16 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
 	"http://www.w3.org/TR/html4/strict.dtd">
 <html lang="en-US" class="reftest-print">
 <head>
 <style type="text/css">
-div.filler {height:5px; width: 50px; border:thin solid blue;}
-div.spacer { height: 0px; width: 0px; padding: 20px;border:thin solid green;}
-caption {margin-top: 5px; margin-bottom:15px; caption-side:bottom-outside}
-table {margin-top: 5px; margin-bottom:5px}
+div.spacer { height: 0px; width: 0px; padding: 0.2in;border:thin solid green;}
+caption {margin-top: 0.1in; margin-bottom:0.3in; caption-side:bottom-outside}
+table {margin-top: 0.1in; margin-bottom:0.1in}
 </style>
 </head>
 <body>
 
 <table cellspacing="0" cellpadding="0">
 <caption><div class="spacer"></div></caption>
 <tbody>
 <tr><td><div class="spacer"></div></td></tr>
--- a/layout/style/nsCSSPseudoClassList.h
+++ b/layout/style/nsCSSPseudoClassList.h
@@ -151,16 +151,18 @@ CSS_STATE_PSEUDO_CLASS(mozFocusRing, ":-
 CSS_STATE_PSEUDO_CLASS(mozBroken, ":-moz-broken", NS_EVENT_STATE_BROKEN)
 CSS_STATE_PSEUDO_CLASS(mozUserDisabled, ":-moz-user-disabled",
                        NS_EVENT_STATE_USERDISABLED)
 CSS_STATE_PSEUDO_CLASS(mozSuppressed, ":-moz-suppressed",
                        NS_EVENT_STATE_SUPPRESSED)
 CSS_STATE_PSEUDO_CLASS(mozLoading, ":-moz-loading", NS_EVENT_STATE_LOADING)
 CSS_STATE_PSEUDO_CLASS(mozTypeUnsupported, ":-moz-type-unsupported",
                        NS_EVENT_STATE_TYPE_UNSUPPORTED)
+CSS_STATE_PSEUDO_CLASS(mozHandlerClickToPlay, ":-moz-handler-clicktoplay",
+                       NS_EVENT_STATE_TYPE_CLICK_TO_PLAY)
 CSS_STATE_PSEUDO_CLASS(mozHandlerDisabled, ":-moz-handler-disabled",
                        NS_EVENT_STATE_HANDLER_DISABLED)
 CSS_STATE_PSEUDO_CLASS(mozHandlerBlocked, ":-moz-handler-blocked",
                        NS_EVENT_STATE_HANDLER_BLOCKED)
 CSS_STATE_PSEUDO_CLASS(mozHandlerCrashed, ":-moz-handler-crashed",
                        NS_EVENT_STATE_HANDLER_CRASHED)
 
 CSS_STATE_PSEUDO_CLASS(mozMathIncrementScriptLevel,
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -126,17 +126,17 @@ NS_NewComputedDOMStyle(nsIDOMElement *aE
   return NS_OK;
 }
 
 static nsIFrame*
 GetContainingBlockFor(nsIFrame* aFrame) {
   if (!aFrame) {
     return nsnull;
   }
-  return nsHTMLReflowState::GetContainingBlockFor(aFrame);
+  return aFrame->GetContainingBlock();
 }
 
 nsComputedDOMStyle::nsComputedDOMStyle()
   : mDocumentWeak(nsnull), mOuterFrame(nsnull),
     mInnerFrame(nsnull), mPresShell(nsnull),
     mExposeVisitedStyle(PR_FALSE)
 {
 }
@@ -3327,17 +3327,17 @@ nsComputedDOMStyle::GetLineHeightCoord(n
 {
   AssertFlushedPendingReflows();
 
   nscoord blockHeight = NS_AUTOHEIGHT;
   if (GetStyleText()->mLineHeight.GetUnit() == eStyleUnit_Enumerated) {
     if (!mInnerFrame)
       return PR_FALSE;
 
-    if (mInnerFrame->IsContainingBlock()) {
+    if (nsLayoutUtils::IsNonWrapperBlock(mInnerFrame)) {
       blockHeight = mInnerFrame->GetContentRect().height;
     } else {
       GetCBContentHeight(blockHeight);
     }
   }
 
   aCoord = nsHTMLReflowState::CalcLineHeight(mStyleContextHolder,
                                              blockHeight);
@@ -3419,17 +3419,22 @@ nsComputedDOMStyle::GetMarginWidthFor(mo
 {
   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
 
   if (!mInnerFrame) {
     SetValueToCoord(val, GetStyleMargin()->mMargin.Get(aSide), PR_FALSE);
   } else {
     AssertFlushedPendingReflows();
 
-    val->SetAppUnits(mInnerFrame->GetUsedMargin().Side(aSide));
+    // For tables, GetUsedMargin always returns an empty margin, so we
+    // should read the margin from the outer table frame instead.
+    val->SetAppUnits(mOuterFrame->GetUsedMargin().Side(aSide));
+    NS_ASSERTION(mOuterFrame == mInnerFrame ||
+                 mInnerFrame->GetUsedMargin() == nsMargin(0, 0, 0, 0),
+                 "Inner tables must have zero margins");
   }
 
   return val;
 }
 
 nsIDOMCSSValue*
 nsComputedDOMStyle::GetBorderStyleFor(mozilla::css::Side aSide)
 {
--- a/layout/style/ua.css
+++ b/layout/style/ua.css
@@ -53,17 +53,17 @@
 
 *|*::-moz-inline-table {
   display: inline-table !important;
   -moz-box-sizing: border-box; /* XXX do we really want this? */
 }
 
 *|*::-moz-table-outer {
   display: inherit !important; /* table or inline-table */
-  margin: 0 ! important;
+  margin: inherit ! important;
   padding: 0 ! important;
   border: none ! important;
   float: inherit;
   clear: inherit;
   position: inherit;
   top: inherit;
   right: inherit;
   bottom: inherit;
new file mode 100644
--- /dev/null
+++ b/layout/tables/crashtests/512749-1.html
@@ -0,0 +1,1 @@
+<html style="position:fixed"><table style="position:absolute"></table></html>
\ No newline at end of file
--- a/layout/tables/crashtests/crashtests.list
+++ b/layout/tables/crashtests/crashtests.list
@@ -75,17 +75,17 @@ load 391898-1.html
 load 391901-1.html
 load 392132-1.xhtml
 load 397448-1.html
 load 398157-1.xhtml
 load 399209-1.xhtml
 load 403249-1.html
 load 403579-1.html
 load 404301-1.xhtml
-asserts(1-2) load 408753-1.xhtml # Bug 512749
+load 408753-1.xhtml
 load 410426-1.html
 load 411582.xhtml
 load 413091.xhtml
 load 413180-1.html
 load 416845-1.xhtml
 load 416845-2.xhtml
 load 416845-3.html   
 asserts(12) load 420654-1.xhtml # Bug 575011
@@ -93,16 +93,17 @@ load 423514-1.xhtml
 load 430374.html
 load 444431-1.html
 load 448988-1.xhtml
 load 450311-1.html
 load 456041.html
 load 457115.html
 load 467141-1.html
 load 488388-1.html
+load 512749-1.html
 load 513732-1.html
 asserts(0-1) load 533380-1.xhtml # Bug 614457
 load 534716-1.html
 load 573354-1.xhtml
 load 576890-1.html
 load 576890-2.html
 load 576890-3.html
 asserts(0-3) load 595758-1.xhtml # Bug 453871
--- a/layout/tables/nsTableCellFrame.cpp
+++ b/layout/tables/nsTableCellFrame.cpp
@@ -1038,22 +1038,16 @@ nsTableCellFrame::GetBorderWidth(nsMargi
 }
 
 nsIAtom*
 nsTableCellFrame::GetType() const
 {
   return nsGkAtoms::tableCellFrame;
 }
 
-/* virtual */ bool
-nsTableCellFrame::IsContainingBlock() const
-{
-  return PR_TRUE;
-}
-
 #ifdef DEBUG
 NS_IMETHODIMP
 nsTableCellFrame::GetFrameName(nsAString& aResult) const
 {
   return MakeFrameName(NS_LITERAL_STRING("TableCell"), aResult);
 }
 #endif
 
--- a/layout/tables/nsTableCellFrame.h
+++ b/layout/tables/nsTableCellFrame.h
@@ -144,18 +144,16 @@ public:
 
   /**
    * Get the "type" of the frame
    *
    * @see nsLayoutAtoms::tableCellFrame
    */
   virtual nsIAtom* GetType() const;
 
-  virtual bool IsContainingBlock() const;
-
 #ifdef DEBUG
   NS_IMETHOD GetFrameName(nsAString& aResult) const;
 #endif
 
   void VerticallyAlignChild(nscoord aMaxAscent);
 
   /*
    * Get the value of vertical-align adjusted for CSS 2's rules for a
--- a/layout/tables/nsTableColGroupFrame.cpp
+++ b/layout/tables/nsTableColGroupFrame.cpp
@@ -424,22 +424,16 @@ NS_METHOD nsTableColGroupFrame::Reflow(n
 
   aDesiredSize.width=0;
   aDesiredSize.height=0;
   aStatus = NS_FRAME_COMPLETE;
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
   return rv;
 }
 
-/* virtual */ bool
-nsTableColGroupFrame::IsContainingBlock() const
-{
-  return PR_TRUE;
-}
-
 nsTableColFrame * nsTableColGroupFrame::GetFirstColumn()
 {
   return GetNextColumn(nsnull);
 }
 
 nsTableColFrame * nsTableColGroupFrame::GetNextColumn(nsIFrame *aChildFrame)
 {
   nsTableColFrame *result = nsnull;
--- a/layout/tables/nsTableColGroupFrame.h
+++ b/layout/tables/nsTableColGroupFrame.h
@@ -137,20 +137,16 @@ public:
     * don't play directly in the rendering game.  They do however
     * maintain important state that effects table and cell layout.
     */
   NS_IMETHOD Reflow(nsPresContext*          aPresContext,
                     nsHTMLReflowMetrics&     aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
                     nsReflowStatus&          aStatus);
 
-  /* needed only because we use Reflow in a hacky way, see
-     nsTableFrame::ReflowColGroups */
-  virtual bool IsContainingBlock() const;
-
   /**
    * 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.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -354,22 +354,16 @@ nsTableFrame::SetInitialChildList(ChildL
       nsRect damageArea(0, 0, GetColCount(), GetRowCount());
       SetBCDamageArea(damageArea);
     }
   }
 
   return NS_OK;
 }
 
-/* virtual */ bool
-nsTableFrame::IsContainingBlock() const
-{
-  return PR_TRUE;
-}
-
 void nsTableFrame::AttributeChangedFor(nsIFrame*       aFrame,
                                        nsIContent*     aContent,
                                        nsIAtom*        aAttribute)
 {
   nsTableCellFrame *cellFrame = do_QueryFrame(aFrame);
   if (cellFrame) {
     if ((nsGkAtoms::rowspan == aAttribute) ||
         (nsGkAtoms::colspan == aAttribute)) {
@@ -1503,16 +1497,19 @@ nsTableFrame::GetPrefWidth(nsRenderingCo
 }
 
 /* virtual */ nsIFrame::IntrinsicWidthOffsetData
 nsTableFrame::IntrinsicWidthOffsets(nsRenderingContext* aRenderingContext)
 {
   IntrinsicWidthOffsetData result =
     nsHTMLContainerFrame::IntrinsicWidthOffsets(aRenderingContext);
 
+  result.hMargin = 0;
+  result.hPctMargin = 0;
+
   if (IsBorderCollapse()) {
     result.hPadding = 0;
     result.hPctPadding = 0;
 
     nsMargin outerBC = GetIncludedOuterBCBorder();
     result.hBorder = outerBC.LeftRight();
   }
 
@@ -2338,16 +2335,24 @@ nsTableFrame::GetUsedBorder() const
 nsTableFrame::GetUsedPadding() const
 {
   if (!IsBorderCollapse())
     return nsHTMLContainerFrame::GetUsedPadding();
 
   return nsMargin(0,0,0,0);
 }
 
+/* virtual */ nsMargin
+nsTableFrame::GetUsedMargin() const
+{
+  // The margin is inherited to the outer table frame via
+  // the ::-moz-table-outer rule in ua.css.
+  return nsMargin(0, 0, 0, 0);
+}
+
 // Destructor function for BCPropertyData properties
 static void
 DestroyBCProperty(void* aPropertyValue)
 {
   delete static_cast<BCPropertyData*>(aPropertyValue);
 }
 
 NS_DECLARE_FRAME_PROPERTY(TableBCProperty, DestroyBCProperty)
--- a/layout/tables/nsTableFrame.h
+++ b/layout/tables/nsTableFrame.h
@@ -159,18 +159,16 @@ public:
   // See if a special height reflow will occur due to having a pct height when
   // the pct height basis may not yet be valid.
   static void CheckRequestSpecialHeightReflow(const nsHTMLReflowState& aReflowState);
 
   // Notify the frame and its ancestors (up to the containing table) that a special
   // height reflow will occur. 
   static void RequestSpecialHeightReflow(const nsHTMLReflowState& aReflowState);
 
-  virtual bool IsContainingBlock() const;
-
   static void RePositionViews(nsIFrame* aFrame);
 
   static bool PageBreakAfter(nsIFrame* aSourceFrame,
                                nsIFrame* aNextFrame);
 
   nsPoint GetFirstSectionOrigin(const nsHTMLReflowState& aReflowState) const;
   /*
    * Notification that aAttribute has changed for content inside a table (cell, row, etc)
@@ -190,16 +188,17 @@ public:
   NS_IMETHOD InsertFrames(ChildListID     aListID,
                           nsIFrame*       aPrevFrame,
                           nsFrameList&    aFrameList);
   NS_IMETHOD RemoveFrame(ChildListID     aListID,
                          nsIFrame*       aOldFrame);
 
   virtual nsMargin GetUsedBorder() const;
   virtual nsMargin GetUsedPadding() const;
+  virtual nsMargin GetUsedMargin() const;
 
   // Get the offset from the border box to the area where the row groups fit
   nsMargin GetChildAreaOffset(const nsHTMLReflowState* aReflowState) const;
 
   /** helper method to find the table parent of any table frame object */
   static nsTableFrame* GetTableFrame(nsIFrame* aSourceFrame);
                                  
   typedef nsresult (* DisplayGenericTablePartTraversal)
--- a/layout/tables/nsTableOuterFrame.cpp
+++ b/layout/tables/nsTableOuterFrame.cpp
@@ -51,17 +51,17 @@
 #endif
 #include "nsIServiceManager.h"
 #include "nsIDOMNode.h"
 #include "nsDisplayList.h"
 #include "nsLayoutUtils.h"
 
 /* ----------- nsTableCaptionFrame ---------- */
 
-#define NS_TABLE_FRAME_CAPTION_LIST_INDEX 0
+#define NS_TABLE_FRAME_CAPTION_LIST_INDEX 1
 #define NO_SIDE 100
 
 // caption frame
 nsTableCaptionFrame::nsTableCaptionFrame(nsStyleContext* aContext):
   nsBlockFrame(aContext)
 {
   // shrink wrap 
   SetFlags(NS_BLOCK_FLOAT_MGR);
@@ -194,45 +194,38 @@ nsTableOuterFrame::CreateAccessible()
     return accService->CreateHTMLTableAccessible(mContent,
                                                  PresContext()->PresShell());
   }
 
   return nsnull;
 }
 #endif
 
-/* virtual */ bool
-nsTableOuterFrame::IsContainingBlock() const
-{
-  return PR_FALSE;
-}
-
 void
 nsTableOuterFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
+  DestroyAbsoluteFrames(aDestructRoot);
   mCaptionFrames.DestroyFramesFrom(aDestructRoot);
   nsHTMLContainerFrame::DestroyFrom(aDestructRoot);
 }
 
 nsFrameList
 nsTableOuterFrame::GetChildList(ChildListID aListID) const
 {
-  switch (aListID) {
-    case kPrincipalList:
-      return mFrames;
-    case kCaptionList:
-      return mCaptionFrames;
-    default:
-      return nsFrameList::EmptyList();
+  if (aListID == kCaptionList) {
+    return mCaptionFrames;
   }
+
+  return nsHTMLContainerFrame::GetChildList(aListID);
 }
 
 void
 nsTableOuterFrame::GetChildLists(nsTArray<ChildList>* aLists) const
 {
+  nsHTMLContainerFrame::GetChildLists(aLists);
   mFrames.AppendIfNonempty(aLists, kPrincipalList);
   mCaptionFrames.AppendIfNonempty(aLists, kCaptionList);
 }
 
 NS_IMETHODIMP 
 nsTableOuterFrame::SetInitialChildList(ChildListID     aListID,
                                        nsFrameList&    aChildList)
 {
@@ -538,17 +531,16 @@ nsTableOuterFrame::GetPrefWidth(nsRender
 // aMarginResult is non-null, fill it with the part of the margin-width
 // that was contributed by the margin.
 static nscoord
 ChildShrinkWrapWidth(nsRenderingContext *aRenderingContext,
                      nsIFrame *aChildFrame,
                      nsSize aCBSize, nscoord aAvailableWidth,
                      nscoord *aMarginResult = nsnull)
 {
-  // The outer table's children do not use it as a containing block.
   nsCSSOffsetState offsets(aChildFrame, aRenderingContext, aCBSize.width);
   nsSize size = aChildFrame->ComputeSize(aRenderingContext, aCBSize,
                   aAvailableWidth,
                   nsSize(offsets.mComputedMargin.LeftRight(),
                          offsets.mComputedMargin.TopBottom()),
                   nsSize(offsets.mComputedBorderPadding.LeftRight() -
                            offsets.mComputedPadding.LeftRight(),
                          offsets.mComputedBorderPadding.TopBottom() -
@@ -563,58 +555,59 @@ ChildShrinkWrapWidth(nsRenderingContext 
 }
 
 /* virtual */ nsSize
 nsTableOuterFrame::ComputeAutoSize(nsRenderingContext *aRenderingContext,
                                    nsSize aCBSize, nscoord aAvailableWidth,
                                    nsSize aMargin, nsSize aBorder,
                                    nsSize aPadding, bool aShrinkWrap)
 {
-  if (!aShrinkWrap)
-    return nsHTMLContainerFrame::ComputeAutoSize(aRenderingContext, aCBSize,
-               aAvailableWidth, aMargin, aBorder, aPadding, aShrinkWrap);
+  nscoord kidAvailableWidth = aAvailableWidth - aMargin.width;
+  NS_ASSERTION(aBorder == nsSize(0, 0) &&
+               aPadding == nsSize(0, 0),
+               "Table outer frames cannot hae borders or paddings");
 
   // When we're shrink-wrapping, our auto size needs to wrap around the
   // actual size of the table, which (if it is specified as a percent)
   // could be something that is not reflected in our GetMinWidth and
   // GetPrefWidth.  See bug 349457 for an example.
 
   // Match the availableWidth logic in Reflow.
   PRUint8 captionSide = GetCaptionSide();
   nscoord width;
   if (captionSide == NO_SIDE) {
     width = ChildShrinkWrapWidth(aRenderingContext, InnerTableFrame(),
-                                 aCBSize, aAvailableWidth);
+                                 aCBSize, kidAvailableWidth);
   } else if (captionSide == NS_STYLE_CAPTION_SIDE_LEFT ||
              captionSide == NS_STYLE_CAPTION_SIDE_RIGHT) {
     nscoord capWidth = ChildShrinkWrapWidth(aRenderingContext,
                                             mCaptionFrames.FirstChild(),
-                                            aCBSize, aAvailableWidth);
+                                            aCBSize, kidAvailableWidth);
     width = capWidth + ChildShrinkWrapWidth(aRenderingContext,
                                             InnerTableFrame(), aCBSize,
-                                            aAvailableWidth - capWidth);
+                                            kidAvailableWidth - capWidth);
   } else if (captionSide == NS_STYLE_CAPTION_SIDE_TOP ||
              captionSide == NS_STYLE_CAPTION_SIDE_BOTTOM) {
     nscoord margin;
     width = ChildShrinkWrapWidth(aRenderingContext, InnerTableFrame(),
-                                 aCBSize, aAvailableWidth, &margin);
+                                 aCBSize, kidAvailableWidth, &margin);
     nscoord capWidth = ChildShrinkWrapWidth(aRenderingContext,
                                             mCaptionFrames.FirstChild(), aCBSize,
                                             width - margin);
     if (capWidth > width)
       width = capWidth;
   } else {
     NS_ASSERTION(captionSide == NS_STYLE_CAPTION_SIDE_TOP_OUTSIDE ||
                  captionSide == NS_STYLE_CAPTION_SIDE_BOTTOM_OUTSIDE,
                  "unexpected caption-side");
     width = ChildShrinkWrapWidth(aRenderingContext, InnerTableFrame(),
-                                 aCBSize, aAvailableWidth);
+                                 aCBSize, kidAvailableWidth);
     nscoord capWidth = ChildShrinkWrapWidth(aRenderingContext,
                                             mCaptionFrames.FirstChild(),
-                                            aCBSize, aAvailableWidth);
+                                            aCBSize, kidAvailableWidth);
     if (capWidth > width)
       width = capWidth;
   }
 
   return nsSize(width, NS_UNCONSTRAINEDSIZE);
 }
 
 PRUint8
@@ -745,32 +738,24 @@ nsTableOuterFrame::GetCaptionOrigin(PRUi
           break;
         case NS_STYLE_VERTICAL_ALIGN_BOTTOM:
           aOrigin.y = NS_MAX(0, aInnerMargin.top + aInnerSize.height - aCaptionSize.height);
           break;
         default:
           break;
       }
       break;
+    case NS_STYLE_CAPTION_SIDE_BOTTOM_OUTSIDE:
     case NS_STYLE_CAPTION_SIDE_BOTTOM: {
       aOrigin.y = aInnerMargin.top + aInnerSize.height + aCaptionMargin.top;
     } break;
-    case NS_STYLE_CAPTION_SIDE_BOTTOM_OUTSIDE: {
-      nsCollapsingMargin marg;
-      marg.Include(aCaptionMargin.top);
-      marg.Include(aInnerMargin.bottom);
-      nscoord collapseMargin = marg.get();
-      aOrigin.y = aInnerMargin.top + aInnerSize.height + collapseMargin;
-    } break;
+    case NS_STYLE_CAPTION_SIDE_TOP_OUTSIDE:
     case NS_STYLE_CAPTION_SIDE_TOP: {
       aOrigin.y = aInnerMargin.top + aCaptionMargin.top;
     } break;
-    case NS_STYLE_CAPTION_SIDE_TOP_OUTSIDE: {
-      aOrigin.y = aCaptionMargin.top;
-    } break;
     default:
       NS_NOTREACHED("Unknown caption alignment type");
       break;
   }
   return NS_OK;
 }
 
 nsresult 
@@ -840,27 +825,21 @@ nsTableOuterFrame::GetInnerOrigin(PRUint
         case NS_STYLE_VERTICAL_ALIGN_BOTTOM:
           aOrigin.y = NS_MAX(aInnerMargin.top, aCaptionSize.height - aInnerSize.height);
           break;
         default:
           break;
       }
     } break;
     case NO_SIDE:
+    case NS_STYLE_CAPTION_SIDE_TOP_OUTSIDE:
     case NS_STYLE_CAPTION_SIDE_TOP: {
       aOrigin.y = aInnerMargin.top + aCaptionMargin.top + aCaptionSize.height +
                   aCaptionMargin.bottom;
     } break;
-    case NS_STYLE_CAPTION_SIDE_TOP_OUTSIDE: {
-      nsCollapsingMargin marg;
-      marg.Include(aCaptionMargin.bottom);
-      marg.Include(aInnerMargin.top);
-      nscoord collapseMargin = marg.get();
-      aOrigin.y = aCaptionMargin.top + aCaptionSize.height + collapseMargin;
-    } break;
     default:
       NS_NOTREACHED("Unknown caption alignment type");
       break;
   }
   return NS_OK;
 }
 
 void
@@ -933,17 +912,16 @@ nsTableOuterFrame::UpdateReflowMetrics(P
   SetDesiredSize(aCaptionSide, aInnerMargin, aCaptionMargin,
                  aMet.width, aMet.height);
 
   aMet.SetOverflowAreasToDesiredBounds();
   ConsiderChildOverflow(aMet.mOverflowAreas, InnerTableFrame());
   if (mCaptionFrames.NotEmpty()) {
     ConsiderChildOverflow(aMet.mOverflowAreas, mCaptionFrames.FirstChild());
   }
-  FinishAndStoreOverflow(&aMet);
 }
 
 NS_METHOD nsTableOuterFrame::Reflow(nsPresContext*           aPresContext,
                                     nsHTMLReflowMetrics&     aDesiredSize,
                                     const nsHTMLReflowState& aOuterRS,
                                     nsReflowStatus&          aStatus)
 {
   DO_GLOBAL_REFLOW_COUNT("nsTableOuterFrame");
@@ -1051,36 +1029,22 @@ NS_METHOD nsTableOuterFrame::Reflow(nsPr
     captionMargin = captionRS->mComputedMargin;
     // Now that we know the height of the caption, reduce the available height
     // for the table frame if we are height constrained and the caption is above
     // or below the inner table.
     if (NS_UNCONSTRAINEDSIZE != aOuterRS.availableHeight) {
       nscoord captionHeight = 0;
       switch (captionSide) {
         case NS_STYLE_CAPTION_SIDE_TOP:
-        case NS_STYLE_CAPTION_SIDE_BOTTOM: {
+        case NS_STYLE_CAPTION_SIDE_BOTTOM:
+        case NS_STYLE_CAPTION_SIDE_TOP_OUTSIDE:
+        case NS_STYLE_CAPTION_SIDE_BOTTOM_OUTSIDE: {
           captionHeight = captionSize.height + captionMargin.TopBottom();
           break;
         }
-        case NS_STYLE_CAPTION_SIDE_TOP_OUTSIDE: {
-          nsCollapsingMargin belowCaptionMargin;
-          belowCaptionMargin.Include(captionMargin.bottom);
-          belowCaptionMargin.Include(innerRS->mComputedMargin.top);
-          captionHeight = captionSize.height + captionMargin.top +
-                          belowCaptionMargin.get();
-          break;
-        }
-        case NS_STYLE_CAPTION_SIDE_BOTTOM_OUTSIDE: {
-          nsCollapsingMargin aboveCaptionMargin;
-          aboveCaptionMargin.Include(captionMargin.top);
-          aboveCaptionMargin.Include(innerRS->mComputedMargin.bottom);
-          captionHeight = captionSize.height + captionMargin.bottom +
-                          aboveCaptionMargin.get();
-          break;
-        }
       }
       innerRS->availableHeight =
         NS_MAX(0, innerRS->availableHeight - captionHeight);
     }
   } else {
     captionSize.SizeTo(0,0);
     captionMargin.SizeTo(0,0,0,0);
   }
@@ -1126,17 +1090,18 @@ NS_METHOD nsTableOuterFrame::Reflow(nsPr
                                 origInnerVisualOverflow, innerFirstReflow);
   if (mCaptionFrames.NotEmpty()) {
     nsTableFrame::InvalidateFrame(mCaptionFrames.FirstChild(), origCaptionRect,
                                   origCaptionVisualOverflow,
                                   captionFirstReflow);
   }
 
   UpdateReflowMetrics(captionSide, aDesiredSize, innerMargin, captionMargin);
-  
+  FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aOuterRS, aStatus);
+
   // Return our desired rect
 
   NS_FRAME_SET_TRUNCATION(aStatus, aOuterRS, aDesiredSize);
   return rv;
 }
 
 nsIAtom*
 nsTableOuterFrame::GetType() const
--- a/layout/tables/nsTableOuterFrame.h
+++ b/layout/tables/nsTableOuterFrame.h
@@ -93,18 +93,16 @@ public:
     *
     * @return           the frame that was created
     */
   friend nsIFrame* NS_NewTableOuterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
   
   // nsIFrame overrides - see there for a description
 
   virtual void DestroyFrom(nsIFrame* aDestructRoot);
-  
-  virtual bool IsContainingBlock() const;
 
   NS_IMETHOD SetInitialChildList(ChildListID     aListID,
                                  nsFrameList&    aChildList);
  
   virtual nsFrameList GetChildList(ChildListID aListID) const;
   virtual void GetChildLists(nsTArray<ChildList>* aLists) const;
 
   NS_IMETHOD AppendFrames(ChildListID     aListID,
--- a/layout/tables/nsTableRowGroupFrame.cpp
+++ b/layout/tables/nsTableRowGroupFrame.cpp
@@ -64,22 +64,16 @@ nsTableRowGroupFrame::nsTableRowGroupFra
 nsTableRowGroupFrame::~nsTableRowGroupFrame()
 {
 }
 
 NS_QUERYFRAME_HEAD(nsTableRowGroupFrame)
   NS_QUERYFRAME_ENTRY(nsTableRowGroupFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsHTMLContainerFrame)
 
-/* virtual */ bool
-nsTableRowGroupFrame::IsContainingBlock() const
-{
-  return PR_TRUE;
-}
-
 PRInt32
 nsTableRowGroupFrame::GetRowCount()
 {
 #ifdef DEBUG
   for (nsFrameList::Enumerator e(mFrames); !e.AtEnd(); e.Next()) {
     NS_ASSERTION(e.get()->GetStyleDisplay()->mDisplay ==
                    NS_STYLE_DISPLAY_TABLE_ROW,
                  "Unexpected display");
--- a/layout/tables/nsTableRowGroupFrame.h
+++ b/layout/tables/nsTableRowGroupFrame.h
@@ -144,18 +144,16 @@ public:
 
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::tableRowGroupFrame
    */
   virtual nsIAtom* GetType() const;
 
-  virtual bool IsContainingBlock() const;
-
   nsTableRowFrame* GetFirstRow();
 
 #ifdef DEBUG
   NS_IMETHOD GetFrameName(nsAString& aResult) const;
 #endif
 
   /** return the number of child rows (not necessarily == number of child frames) */
   PRInt32 GetRowCount();
--- a/layout/xul/base/src/nsScrollbarFrame.cpp
+++ b/layout/xul/base/src/nsScrollbarFrame.cpp
@@ -97,24 +97,16 @@ nsScrollbarFrame::Reflow(nsPresContext* 
   }
   if (aReflowState.availableHeight == 0) {
     aDesiredSize.height = 0;
   }
 
   return NS_OK;
 }
 
-/* virtual */ bool
-nsScrollbarFrame::IsContainingBlock() const
-{
-  // Return true so that the nsHTMLReflowState code is happy with us
-  // being a reflow root.
-  return PR_TRUE;
-}
-
 nsIAtom*
 nsScrollbarFrame::GetType() const
 {
   return nsGkAtoms::scrollbarFrame;
 }
 
 NS_IMETHODIMP
 nsScrollbarFrame::AttributeChanged(PRInt32 aNameSpaceID,
--- a/layout/xul/base/src/nsScrollbarFrame.h
+++ b/layout/xul/base/src/nsScrollbarFrame.h
@@ -91,18 +91,16 @@ public:
                   nsIFrame*        aParent,
                   nsIFrame*        aPrevInFlow);
 
   NS_IMETHOD Reflow(nsPresContext*          aPresContext,
                     nsHTMLReflowMetrics&     aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
                     nsReflowStatus&          aStatus);
 
-  virtual bool IsContainingBlock() const;
-
   virtual nsIAtom* GetType() const;  
 
   void SetScrollbarMediatorContent(nsIContent* aMediator);
   nsIScrollbarMediator* GetScrollbarMediator();
 
   // nsBox methods
 
   /**
--- a/mobile/app/mobile.js
+++ b/mobile/app/mobile.js
@@ -432,20 +432,24 @@ pref("browser.ui.touch.left", 8);
 pref("browser.ui.touch.right", 8);
 pref("browser.ui.touch.top", 12);
 pref("browser.ui.touch.bottom", 4);
 pref("browser.ui.touch.weight.visited", 120); // percentage
 
 // plugins
 #if MOZ_PLATFORM_MAEMO == 6
 pref("plugin.disable", false);
+pref("dom.ipc.plugins.enabled", true);
+#elifdef ANDROID
+pref("plugin.disable", false);
+pref("dom.ipc.plugins.enabled", false);
 #else
 pref("plugin.disable", true);
+pref("dom.ipc.plugins.enabled", true);
 #endif
-pref("dom.ipc.plugins.enabled", true);
 
 // process priority
 // higher values give content process less CPU time
 #if MOZ_PLATFORM_MAEMO == 5
 pref("dom.ipc.content.nice", 10);
 #else
 pref("dom.ipc.content.nice", 1);
 #endif
--- a/mobile/chrome/content/browser.js
+++ b/mobile/chrome/content/browser.js
@@ -395,16 +395,17 @@ var Browser = {
     messageManager.addMessageListener("Browser:FormSubmit", this);
     messageManager.addMessageListener("Browser:KeyPress", this);
     messageManager.addMessageListener("Browser:ZoomToPoint:Return", this);
     messageManager.addMessageListener("Browser:CanUnload:Return", this);
     messageManager.addMessageListener("scroll", this);
     messageManager.addMessageListener("Browser:CertException", this);
     messageManager.addMessageListener("Browser:BlockedSite", this);
     messageManager.addMessageListener("Browser:ErrorPage", this);
+    messageManager.addMessageListener("Browser:PluginClickToPlay", this);
 
     // Broadcast a UIReady message so add-ons know we are finished with startup
     let event = document.createEvent("Events");
     event.initEvent("UIReady", true, false);
     window.dispatchEvent(event);
   },
 
   _alertShown: function _alertShown() {
@@ -493,16 +494,17 @@ var Browser = {
     messageManager.removeMessageListener("Browser:ViewportMetadata", this);
     messageManager.removeMessageListener("Browser:FormSubmit", this);
     messageManager.removeMessageListener("Browser:KeyPress", this);
     messageManager.removeMessageListener("Browser:ZoomToPoint:Return", this);
     messageManager.removeMessageListener("scroll", this);
     messageManager.removeMessageListener("Browser:CertException", this);
     messageManager.removeMessageListener("Browser:BlockedSite", this);
     messageManager.removeMessageListener("Browser:ErrorPage", this);
+    messageManager.removeMessageListener("Browser:PluginClickToPlay", this);
 
     var os = Services.obs;
     os.removeObserver(XPInstallObserver, "addon-install-blocked");
     os.removeObserver(XPInstallObserver, "addon-install-started");
     os.removeObserver(SessionHistoryObserver, "browser:purge-session-history");
     os.removeObserver(ContentCrashObserver, "ipc:content-shutdown");
     os.removeObserver(MemoryObserver, "memory-pressure");
     os.removeObserver(ActivityObserver, "application-background", false);
@@ -1265,16 +1267,41 @@ var Browser = {
         this._handleCertException(aMessage);
         break;
       case "Browser:BlockedSite":
         this._handleBlockedSite(aMessage);
         break;
       case "Browser:ErrorPage":
         this._handleErrorPage(aMessage);
         break;
+      case "Browser:PluginClickToPlay": {
+        // Save off session history
+        let parent = browser.parentNode;
+        let data = browser.__SS_data;
+        if (data.entries.length == 0)
+          return;
+
+        // Remove the browser from the DOM, effectively killing it's content
+        parent.removeChild(browser);
+
+        // Re-create the browser as non-remote, so plugins work
+        browser.setAttribute("remote", "false");
+        parent.appendChild(browser);
+
+        // Reload the content using session history
+        browser.__SS_data = data;
+        let json = {
+          uri: data.entries[data.index - 1].url,
+          flags: null,
+          entries: data.entries,
+          index: data.index
+        };
+        browser.messageManager.sendAsyncMessage("WebNavigation:LoadURI", json);
+        break;
+      }
     }
   },
 
   _grabbedSidebar: false, // true while the user is dragging the sidebar
   _sidebarOffset: 0, // tracks how far the sidebar has been dragged
   _slideMultiplier: 1, // set greater than 1 to amplify sidebar drags (makes swiping easier)
 
   /**
--- a/mobile/chrome/content/content.js
+++ b/mobile/chrome/content/content.js
@@ -278,16 +278,17 @@ let Content = {
 
     if (Util.isParentProcess())
       addEventListener("DOMActivate", this, true);
 
     addEventListener("MozApplicationManifest", this, false);
     addEventListener("DOMContentLoaded", this, false);
     addEventListener("pagehide", this, false);
     addEventListener("keypress", this, false, false);
+    addEventListener("PluginClickToPlay", this, false, true);
 
     // Attach a listener to watch for "click" events bubbling up from error
     // pages and other similar page. This lets us fix bugs like 401575 which
     // require error page UI to do privileged things, without letting error
     // pages have any privilege themselves.
     addEventListener("click", this, false);
 
     docShell.QueryInterface(Ci.nsIDocShellHistory).useGlobalHistory = true;
@@ -389,16 +390,20 @@ let Content = {
       case "DOMContentLoaded":
         this._maybeNotifyErroPage();
         break;
 
       case "pagehide":
         if (aEvent.target == content.document)
           this._resetFontSize();          
         break;
+
+      case "PluginClickToPlay":
+        sendAsyncMessage("Browser:PluginClickToPlay", { });
+        break;
     }
   },
 
   receiveMessage: function receiveMessage(aMessage) {
     let json = aMessage.json;
     let x = json.x;
     let y = json.y;
     let modifiers = json.modifiers;
--- a/toolkit/locales/en-US/chrome/mozapps/plugins/plugins.dtd
+++ b/toolkit/locales/en-US/chrome/mozapps/plugins/plugins.dtd
@@ -16,16 +16,17 @@
 <!ENTITY pluginWizard.installPluginsPage.description.label   "&brandShortName; is installing plugins…">
 
 <!ENTITY pluginWizard.finalPage.description.label            "&brandShortName; finished installing the missing plugins:">
 
 <!ENTITY pluginWizard.finalPage.moreInfo.label               "Find out more about Plugins or manually find missing plugins.">
 <!ENTITY pluginWizard.finalPage.restart.label                "&brandShortName; needs to be restarted for the plugin(s) to work.">
 
 <!ENTITY missingPlugin                                       "A plugin is needed to display this content.">
+<!ENTITY clickToPlayPlugin                                   "Tap here to activate plugin.">
 <!ENTITY disabledPlugin                                      "This plugin is disabled.">
 <!ENTITY blockedPlugin.label                                 "This plugin has been blocked for your protection.">
 
 <!ENTITY installPlugin                                       "Install plugin…">
 <!ENTITY managePlugins                                       "Manage plugins…">
 
 <!-- LOCALIZATION NOTE (reloadPlugin.pre): include a trailing space as needed -->
 <!-- LOCALIZATION NOTE (reloadPlugin.middle): avoid leading/trailing spaces, this text is a link -->
--- a/toolkit/mozapps/plugins/content/pluginProblem.xml
+++ b/toolkit/mozapps/plugins/content/pluginProblem.xml
@@ -53,16 +53,19 @@
         <stylesheet src="chrome://mozapps/content/plugins/pluginProblemContent.css"/>
     </resources>
 
     <content>
         <xul:vbox class="mainBox" flex="1" chromedir="&locale.dir;">
             <xul:spacer flex="1"/>
             <xul:box class="icon"/>
             <html:div class="msg msgUnsupported">&missingPlugin;</html:div>
+            <html:div class="msg msgClickToPlay" onclick="var evt = document.createEvent('Events'); evt.initEvent('PluginClickToPlay', true, false); this.dispatchEvent(evt);">
+               &clickToPlayPlugin;
+            </html:div>
             <html:div class="msg msgDisabled">&disabledPlugin;</html:div>
             <html:div class="msg msgBlocked">&blockedPlugin.label;</html:div>
             <html:div class="msg msgCrashed"><!-- set at runtime --></html:div>
 
             <html:div class="installStatus">
                 <html:div class="msg msgInstallPlugin"><html:a class="installPluginLink" href="">&installPlugin;</html:a></html:div>
             </html:div>
             <html:div class="msg msgManagePlugins"><html:a class="managePluginsLink" href="">&managePlugins;</html:a></html:div>
--- a/toolkit/mozapps/plugins/content/pluginProblemBinding.css
+++ b/toolkit/mozapps/plugins/content/pluginProblemBinding.css
@@ -36,18 +36,21 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 @namespace url(http://www.w3.org/1999/xhtml); /* set default namespace to HTML */
 
 embed:-moz-handler-disabled,
 embed:-moz-handler-blocked,
 embed:-moz-handler-crashed,
+embed:-moz-handler-clicktoplay,
 applet:-moz-handler-disabled,
 applet:-moz-handler-blocked,
 applet:-moz-handler-crashed,
+applet:-moz-handler-clicktoplay,
 object:-moz-has-handlerref:-moz-handler-disabled,
 object:-moz-has-handlerref:-moz-handler-blocked,
-object:-moz-handler-crashed {
+object:-moz-handler-crashed,
+object:-moz-handler-clicktoplay {
     display: inline-block;
     overflow: hidden;
     -moz-binding: url('chrome://mozapps/content/plugins/pluginProblem.xml#pluginProblem') !important;
 }
--- a/toolkit/mozapps/plugins/content/pluginProblemContent.css
+++ b/toolkit/mozapps/plugins/content/pluginProblemContent.css
@@ -8,21 +8,23 @@ html|applet:not([width]), html|applet[wi
 
 html|object:not([height]), html|object[height=""],
 html|embed:not([height]), html|embed[height=""],
 html|applet:not([height]), html|applet[height=""] {
   height: 200px;
 }
 
 :-moz-type-unsupported .mainBox,
+:-moz-handler-clicktoplay .mainBox,
 :-moz-handler-disabled .mainBox,
 :-moz-handler-blocked .mainBox {
   -moz-user-focus: normal;
 }
 :-moz-type-unsupported .mainBox:focus,
+:-moz-handler-clicktoplay .mainBox:focus,
 :-moz-handler-disabled .mainBox:focus,
 :-moz-handler-blocked .mainBox:focus {
   outline: 1px dotted;
 }
 
 .mainBox {
   width: inherit;
   height: inherit;
@@ -35,16 +37,17 @@ html|applet:not([height]), html|applet[h
   direction: rtl;
 }
 
 .msg {
   display: none;
 }
 
 :-moz-type-unsupported .msgUnsupported,
+:-moz-handler-clicktoplay .msgClickToPlay,
 :-moz-handler-disabled .msgDisabled,
 :-moz-handler-disabled .msgManagePlugins,
 :-moz-handler-blocked .msgBlocked,
 :-moz-handler-crashed .msgCrashed {
   display: block;
 }
 
 .installStatus[status="ready"] .msgInstallPlugin {
--- a/toolkit/themes/pinstripe/mozapps/plugins/pluginProblem.css
+++ b/toolkit/themes/pinstripe/mozapps/plugins/pluginProblem.css
@@ -29,16 +29,19 @@ html|a {
   background-repeat: no-repeat;
 }
 :-moz-type-unsupported .icon {
   background-image: url(chrome://mozapps/skin/plugins/contentPluginMissing.png);
 }
 :-moz-type-unsupported .icon[status="ready"] {
   background-image: url(chrome://mozapps/skin/plugins/contentPluginDownload.png);
 }
+:-moz-handler-clicktoplay .icon {
+  background-image: url(chrome://mozapps/skin/plugins/contentPluginMissing.png);
+}
 :-moz-handler-disabled .icon {
   background-image: url(chrome://mozapps/skin/plugins/contentPluginDisabled.png);
 }
 :-moz-handler-blocked .icon {
   background-image: url(chrome://mozapps/skin/plugins/contentPluginBlocked.png);
 }
 :-moz-handler-crashed .icon {
   background-image: url(chrome://mozapps/skin/plugins/contentPluginCrashed.png);
--- a/toolkit/themes/winstripe/mozapps/plugins/pluginProblem.css
+++ b/toolkit/themes/winstripe/mozapps/plugins/pluginProblem.css
@@ -29,16 +29,19 @@ html|a {
   background-repeat: no-repeat;
 }
 :-moz-type-unsupported .icon {
   background-image: url(chrome://mozapps/skin/plugins/contentPluginMissing.png);
 }
 :-moz-type-unsupported .icon[status="ready"] {
   background-image: url(chrome://mozapps/skin/plugins/contentPluginDownload.png);
 }
+:-moz-handler-clicktoplay .icon {
+  background-image: url(chrome://mozapps/skin/plugins/contentPluginMissing.png);
+}
 :-moz-handler-disabled .icon {
   background-image: url(chrome://mozapps/skin/plugins/contentPluginDisabled.png);
 }
 :-moz-handler-blocked .icon {
   background-image: url(chrome://mozapps/skin/plugins/contentPluginBlocked.png);
 }
 :-moz-handler-crashed .icon {
   background-image: url(chrome://mozapps/skin/plugins/contentPluginCrashed.png);