Bug 243519. Rework root element frame construction and the CanvasFrame so that the CanvasFrame is an abs-pos container and the root element frame can be positioned. r=fantasai,sr=dbaron
authorRobert O'Callahan <robert@ocallahan.org>
Sat, 06 Sep 2008 21:35:05 +1200
changeset 18885 75919d3eb3d08ce32fcacaf1e8af5bec571efc03
parent 18884 f7414f6cb95badc8eff58fa763e0685f1975d1a5
child 18886 cc98ae28c215e415f19ff4151a52386e40124c1c
push id1795
push userrocallahan@mozilla.com
push dateSat, 06 Sep 2008 09:35:22 +0000
treeherdermozilla-central@75919d3eb3d0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfantasai, dbaron
bugs243519
milestone1.9.1b1pre
Bug 243519. Rework root element frame construction and the CanvasFrame so that the CanvasFrame is an abs-pos container and the root element frame can be positioned. r=fantasai,sr=dbaron
layout/base/crashtests/243519-1.html
layout/base/crashtests/crashtests.list
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsCSSFrameConstructor.h
layout/generic/nsAbsoluteContainingBlock.cpp
layout/generic/nsAbsoluteContainingBlock.h
layout/generic/nsBlockFrame.cpp
layout/generic/nsContainerFrame.cpp
layout/generic/nsFrame.cpp
layout/generic/nsHTMLFrame.cpp
layout/generic/nsHTMLParts.h
layout/generic/nsHTMLReflowState.cpp
layout/generic/nsInlineFrame.cpp
layout/generic/nsPageContentFrame.cpp
layout/generic/nsPageContentFrame.h
layout/generic/nsViewportFrame.cpp
layout/reftests/bugs/200774-1.html
layout/reftests/bugs/243519-1-ref.html
layout/reftests/bugs/243519-1.html
layout/reftests/bugs/243519-2-ref.html
layout/reftests/bugs/243519-2.html
layout/reftests/bugs/243519-3-ref.html
layout/reftests/bugs/243519-3.html
layout/reftests/bugs/243519-4-ref.html
layout/reftests/bugs/243519-4a.html
layout/reftests/bugs/243519-4b.html
layout/reftests/bugs/243519-4c.html
layout/reftests/bugs/243519-4d.html
layout/reftests/bugs/243519-4e.html
layout/reftests/bugs/243519-4f.html
layout/reftests/bugs/243519-5-ref.html
layout/reftests/bugs/243519-5a.html
layout/reftests/bugs/243519-5b.html
layout/reftests/bugs/243519-5c.html
layout/reftests/bugs/243519-5d.html
layout/reftests/bugs/243519-6-ref.html
layout/reftests/bugs/243519-6.html
layout/reftests/bugs/243519-7-ref.html
layout/reftests/bugs/243519-7.html
layout/reftests/bugs/243519-8-ref.svg
layout/reftests/bugs/243519-8.svg
layout/reftests/bugs/243519-9-ref.html
layout/reftests/bugs/243519-9a.html
layout/reftests/bugs/243519-9b.html
layout/reftests/bugs/243519-9c.html
layout/reftests/bugs/243519-9d.html
layout/reftests/bugs/243519-9e.html
layout/reftests/bugs/reftest.list
new file mode 100644
--- /dev/null
+++ b/layout/base/crashtests/243519-1.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<body>
+  <div style="position:absolute;">Hello</div>
+  <div style="position:fixed;">Kitty</div>
+  <script>
+    document.body.offsetTop;
+    document.documentElement.style.display = "table";
+    document.body.offsetTop;
+    document.documentElement..style.display = "";
+    document.body.offsetTop;
+
+    document.documentElement.style.position = "absolute";
+    document.body.offsetTop;
+    document.documentElement.style.display = "table";
+    document.body.offsetTop;
+    document.documentElement..style.display = "";
+    document.body.offsetTop;
+
+    document.documentElement.style.position = "fixed";
+    document.body.offsetTop;
+    document.documentElement.style.display = "table";
+    document.body.offsetTop;
+    document.documentElement..style.display = "";
+  </script>
+</body>
+</html>
--- a/layout/base/crashtests/crashtests.list
+++ b/layout/base/crashtests/crashtests.list
@@ -1,13 +1,14 @@
 load 56746-1.html
 load 143862-1.html
 load 143862-2.html
 load 243159-1.html
 load 243159-2.xhtml
+load 243519-1.html
 load 306940-1.html
 load 310267-1.xml
 load 310638-1.svg
 load 310638-2.html
 load 313086-1.xml
 load 321058-1.xul
 load 321058-2.xul
 load 321077-1.xul
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -1801,19 +1801,19 @@ nsCSSFrameConstructor::nsCSSFrameConstru
   , mRootElementStyleFrame(nsnull)
   , mFixedContainingBlock(nsnull)
   , mDocElementContainingBlock(nsnull)
   , mGfxScrollFrame(nsnull)
   , mPageSequenceFrame(nsnull)
   , mUpdateCount(0)
   , mQuotesDirty(PR_FALSE)
   , mCountersDirty(PR_FALSE)
-  , mInitialContainingBlockIsAbsPosContainer(PR_FALSE)
   , mIsDestroyingFrameTree(PR_FALSE)
   , mRebuildAllStyleData(PR_FALSE)
+  , mHasRootAbsPosContainingBlock(PR_FALSE)
 {
   if (!gGotXBLFormPrefs) {
     gGotXBLFormPrefs = PR_TRUE;
 
     gUseXBLForms =
       nsContentUtils::GetBoolPref("nglayout.debug.enable_xbl_forms");
   }
 
@@ -3967,42 +3967,16 @@ nsCSSFrameConstructor::GetDisplay(nsIFra
   }
   return aFrame->GetStyleContext()->GetStyleDisplay();
 }
 
 /***********************************************
  * END TABLE SECTION
  ***********************************************/
 
-nsresult
-nsCSSFrameConstructor::ConstructDocElementTableFrame(nsIContent*     aDocElement,
-                                                     nsIFrame*       aParentFrame,
-                                                     nsIFrame**      aNewTableFrame,
-                                                     nsFrameConstructorState& aState)
-{
-  nsFrameItems    frameItems;
-
-  // XXXbz this is wrong.  We should at least be setting the fixed container in
-  // the framestate here.  Better yet, we should pass through aState
-  // unmodified.  Can't do that, though, because then a fixed or absolute
-  // positioned root table with auto offsets would look for a block to compute
-  // its hypothetical box and crash.  So we just disable fixed positioning
-  // altogether in documents where the root is a table.  Oh, well.
-  nsFrameConstructorState state(mPresShell, nsnull, nsnull, nsnull,
-                                aState.mFrameState);
-  ConstructFrame(state, aDocElement, aParentFrame, frameItems);
-  *aNewTableFrame = frameItems.childList;
-  if (!*aNewTableFrame) {
-    NS_WARNING("cannot get table contentFrame");
-    // XXXbz maybe better to return the error from ConstructFrame?
-    return NS_ERROR_FAILURE;
-  }
-  return NS_OK;
-}
-
 static PRBool CheckOverflow(nsPresContext* aPresContext,
                             const nsStyleDisplay* aDisplay)
 {
   if (aDisplay->mOverflowX == NS_STYLE_OVERFLOW_VISIBLE)
     return PR_FALSE;
 
   if (aDisplay->mOverflowX == NS_STYLE_OVERFLOW_CLIP)
     aPresContext->SetViewportOverflowOverride(NS_STYLE_OVERFLOW_HIDDEN,
@@ -4088,39 +4062,16 @@ nsCSSFrameConstructor::PropagateScrollTo
  * New one
  */
 nsresult
 nsCSSFrameConstructor::ConstructDocElementFrame(nsFrameConstructorState& aState,
                                                 nsIContent*              aDocElement,
                                                 nsIFrame*                aParentFrame,
                                                 nsIFrame**               aNewFrame)
 {
-    // how the root frame hierarchy should look
-
-    /*
-
----------------No Scrollbars------
-
-
-     AreaFrame or BoxFrame (InitialContainingBlock)
-  
-
-
----------------Gfx Scrollbars ------
-
-
-     ScrollFrame
-
-         ^
-         |
-         |
-     AreaFrame or BoxFrame (InitialContainingBlock)
-          
-*/    
-
   *aNewFrame = nsnull;
 
   if (!mTempFrameTreeState)
     aState.mPresShell->CaptureHistoryState(getter_AddRefs(mTempFrameTreeState));
 
   // ----- reattach gfx scrollbars ------
   // Gfx scrollframes were created in the root frame but the primary frame map may have been destroyed if a 
   // new style sheet was loaded so lets reattach the frames to their content.
@@ -4184,157 +4135,219 @@ nsCSSFrameConstructor::ConstructDocEleme
     PropagateScrollToViewport() == aDocElement;
 
   NS_ASSERTION(!display->IsScrollableOverflow() || 
                aState.mPresContext->IsPaginated() ||
                propagatedScrollToViewport,
                "Scrollbars should have been propagated to the viewport");
 #endif
 
-  nsIFrame* contentFrame = nsnull;
-  PRBool isBlockFrame = PR_FALSE;
+  nsFrameConstructorSaveState absoluteSaveState;
+  if (mHasRootAbsPosContainingBlock) {
+    // Push the absolute containing block now so we can absolutely position
+    // the root element
+    aState.PushAbsoluteContainingBlock(mDocElementContainingBlock, absoluteSaveState);
+  }
+
   nsresult rv;
 
   // The rules from CSS 2.1, section 9.2.4, have already been applied
   // by the style system, so we can assume that display->mDisplay is
   // either NONE, BLOCK, or TABLE.
 
   PRBool docElemIsTable = (display->mDisplay == NS_STYLE_DISPLAY_TABLE) &&
                           !IsSpecialContent(aDocElement, aDocElement->Tag(),
                                             aDocElement->GetNameSpaceID(),
                                             styleContext);
 
+  // contentFrame is the primary frame for the root element. *aNewFrame
+  // is the frame that will be the child of the initial containing block.
+  // These are usually the same frame but they can be different, in
+  // particular if the root frame is positioned, in which case
+  // contentFrame is the out-of-flow frame and *aNewFrame is the
+  // placeholder.
+  nsIFrame* contentFrame;
+  PRBool processChildren = PR_FALSE;
   if (docElemIsTable) {
+    nsIFrame* innerTableFrame;
+    nsFrameItems frameItems;
     // if the document is a table then just populate it.
-    rv = ConstructDocElementTableFrame(aDocElement, aParentFrame, &contentFrame,
-                                       aState);
-    if (NS_FAILED(rv)) {
+    rv = ConstructTableFrame(aState, aDocElement,
+                             aParentFrame, styleContext,
+                             kNameSpaceID_None, PR_FALSE, frameItems, contentFrame,
+                             innerTableFrame);
+    if (NS_FAILED(rv))
       return rv;
-    }
-    styleContext = contentFrame->GetStyleContext();
+    if (!contentFrame || !frameItems.childList)
+      return NS_ERROR_FAILURE;
+    *aNewFrame = frameItems.childList;
+    NS_ASSERTION(!frameItems.childList->GetNextSibling(),
+                 "multiple root element frames");
   } else {
     // otherwise build a box or a block
 #ifdef MOZ_XUL
     if (aDocElement->IsNodeOfType(nsINode::eXUL)) {
       contentFrame = NS_NewDocElementBoxFrame(mPresShell, styleContext);
+      if (NS_UNLIKELY(!contentFrame)) {
+        return NS_ERROR_OUT_OF_MEMORY;
+      }
+      InitAndRestoreFrame(aState, aDocElement, aParentFrame, nsnull, contentFrame);
+      *aNewFrame = contentFrame;
+      processChildren = PR_TRUE;
     }
     else
 #endif 
 #ifdef MOZ_SVG
     if (aDocElement->GetNameSpaceID() == kNameSpaceID_SVG) {
       if (aDocElement->Tag() == nsGkAtoms::svg && NS_SVGEnabled()) {
         contentFrame = NS_NewSVGOuterSVGFrame(mPresShell, aDocElement, styleContext);
+        if (NS_UNLIKELY(!contentFrame)) {
+          return NS_ERROR_OUT_OF_MEMORY;
+        }
+        InitAndRestoreFrame(aState, aDocElement,
+                            aState.GetGeometricParent(display, aParentFrame),
+                            nsnull, contentFrame);
+
+        // AddChild takes care of transforming the frame tree for fixed-pos
+        // or abs-pos situations
+        nsFrameItems frameItems;
+        rv = aState.AddChild(contentFrame, frameItems, aDocElement,
+                             styleContext, aParentFrame);
+        if (NS_FAILED(rv) || !frameItems.childList) {
+          return rv;
+        }
+        *aNewFrame = frameItems.childList;
+        processChildren = PR_TRUE;
+
+        // See if we need to create a view, e.g. the frame is absolutely positioned
+        nsHTMLContainerFrame::CreateViewForFrame(contentFrame, aParentFrame, PR_FALSE);
       } else {
         return NS_ERROR_FAILURE;
       }
     }
     else 
 #endif
     {
-      contentFrame = NS_NewDocumentElementFrame(mPresShell, styleContext);
-      isBlockFrame = PR_TRUE;
-    }
-    
-    if (NS_UNLIKELY(!contentFrame)) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
-
-    // initialize the child
-    InitAndRestoreFrame(aState, aDocElement, aParentFrame, nsnull, contentFrame);
+      contentFrame = NS_NewBlockFrame(mPresShell, styleContext,
+        NS_BLOCK_SPACE_MGR|NS_BLOCK_MARGIN_ROOT);
+      if (!contentFrame)
+        return NS_ERROR_OUT_OF_MEMORY;
+      nsFrameItems frameItems;
+      rv = ConstructBlock(aState, display, aDocElement,
+                          aState.GetGeometricParent(display, aParentFrame),
+                          aParentFrame, styleContext, &contentFrame,
+                          frameItems, display->IsPositioned());
+      if (NS_FAILED(rv) || !frameItems.childList)
+        return rv;
+      *aNewFrame = frameItems.childList;
+      NS_ASSERTION(!frameItems.childList->GetNextSibling(),
+                   "multiple root element frames");
+    }
   }
 
   // set the primary frame
   aState.mFrameManager->SetPrimaryFrameFor(aDocElement, contentFrame);
 
-  *aNewFrame = contentFrame;
-
   mInitialContainingBlock = contentFrame;
-  mInitialContainingBlockIsAbsPosContainer = PR_FALSE;
 
   // Figure out which frame has the main style for the document element,
   // assigning it to mRootElementStyleFrame.
   // Backgrounds should be propagated from that frame to the viewport.
   PRBool isChild;
   contentFrame->GetParentStyleContextFrame(aState.mPresContext,
           &mRootElementStyleFrame, &isChild);
   if (!isChild) {
     mRootElementStyleFrame = mInitialContainingBlock;
   }
 
-  // if it was a table then we don't need to process our children.
-  if (!docElemIsTable) {
-    // Process the child content
-    nsFrameConstructorSaveState absoluteSaveState;
-    nsFrameConstructorSaveState floatSaveState;
-    nsFrameItems                childItems;
-
-    if (isBlockFrame) {
-      PRBool haveFirstLetterStyle, haveFirstLineStyle;
-      ShouldHaveSpecialBlockStyle(aDocElement, styleContext,
-                                  &haveFirstLetterStyle, &haveFirstLineStyle);
-      mInitialContainingBlockIsAbsPosContainer = PR_TRUE;
-      aState.PushAbsoluteContainingBlock(contentFrame, absoluteSaveState);
-      aState.PushFloatContainingBlock(contentFrame, floatSaveState,
-                                      haveFirstLetterStyle,
-                                      haveFirstLineStyle);
-    }
+  if (processChildren) {
+    // Still need to process the child content
+    nsFrameItems childItems;
 
     // Create any anonymous frames the doc element frame requires
     // This must happen before ProcessChildren to ensure that popups are
     // never constructed before the popupset.
     CreateAnonymousFrames(nsnull, aState, aDocElement, contentFrame,
                           PR_FALSE, childItems, PR_TRUE);
+    NS_ASSERTION(!nsLayoutUtils::GetAsBlock(contentFrame),
+                 "Only XUL and SVG frames should reach here");
     ProcessChildren(aState, aDocElement, contentFrame, PR_TRUE, childItems,
-                    isBlockFrame);
+                    PR_FALSE);
 
     // Set the initial child lists
     contentFrame->SetInitialChildList(nsnull, childItems.childList);
   }
 
   return NS_OK;
 }
 
 
 nsresult
 nsCSSFrameConstructor::ConstructRootFrame(nsIContent*     aDocElement,
                                           nsIFrame**      aNewFrame)
 {
   AUTO_LAYOUT_PHASE_ENTRY_POINT(mPresShell->GetPresContext(), FrameC);
   NS_PRECONDITION(aNewFrame, "null out param");
   
-  // how the root frame hierarchy should look
-
     /*
-
----------------No Scrollbars------
-
-
-
-     ViewPortFrame (FixedContainingBlock) <---- RootView
-
-         ^
-         |
-     RootFrame(DocElementContainingBlock)
-  
-
-
----------------Gfx Scrollbars ------
-
-
-     ViewPortFrame (FixedContainingBlock) <---- RootView
-
-         ^
-         |
-     ScrollFrame
-
-         ^
-         |
-     RootFrame(DocElementContainingBlock)
-          
-*/    
+       how the root frame hierarchy should look
+
+  Galley presentation, non-XUL, with scrolling (i.e. not a frameset):
+  
+      ViewportFrame [fixed-cb]
+        nsHTMLScrollFrame
+          CanvasFrame [abs-cb]
+            root element frame (nsBlockFrame, nsSVGOuterSVGFrame,
+                                nsTableOuterFrame, nsPlaceholderFrame)
+
+  Galley presentation, non-XUL, without scrolling (i.e. a frameset):
+  
+      ViewportFrame [fixed-cb]
+        CanvasFrame [abs-cb]
+          root element frame (nsBlockFrame)
+
+  Galley presentation, XUL
+  
+      ViewportFrame [fixed-cb]
+        nsRootBoxFrame
+          root element frame (nsDocElementBoxFrame)
+
+  Print presentation, non-XUL
+
+      ViewportFrame
+        nsSimplePageSequenceFrame
+          nsPageFrame [fixed-cb]
+            nsPageContentFrame
+              CanvasFrame [abs-cb]
+                root element frame (nsBlockFrame, nsSVGOuterSVGFrame,
+                                    nsTableOuterFrame, nsPlaceholderFrame)
+
+  Print-preview presentation, non-XUL
+
+      ViewportFrame
+        nsHTMLScrollFrame
+          nsSimplePageSequenceFrame
+            nsPageFrame [fixed-cb]
+              nsPageContentFrame
+                CanvasFrame [abs-cb]
+                  root element frame (nsBlockFrame, nsSVGOuterSVGFrame,
+                                      nsTableOuterFrame, nsPlaceholderFrame)
+
+  Print/print preview of XUL is not supported.
+  [fixed-cb]: the default containing block for fixed-pos content
+  [abs-cb]: the default containing block for abs-pos content
+ 
+  Meaning of nsCSSFrameConstructor fields:
+    mInitialContainingBlock is "root element frame".
+    mDocElementContainingBlock is the parent of mInitialContainingBlock
+      (i.e. CanvasFrame or nsRootBoxFrame)
+    mFixedContainingBlock is the [fixed-cb]
+    mGfxScrollFrame is the nsHTMLScrollFrame mentioned above, or null if there isn't one
+    mPageSequenceFrame is the nsSimplePageSequenceFrame, or null if there isn't one
+*/
 
   // Set up our style rule observer.
   {
     mPresShell->StyleSet()->SetBindingManager(mDocument->BindingManager());
   }
 
   // --------- BUILD VIEWPORT -----------
   nsIFrame*                 viewportFrame = nsnull;
@@ -4389,16 +4402,17 @@ nsCSSFrameConstructor::ConstructRootFram
     {
       // pass a temporary stylecontext, the correct one will be set later
       rootFrame = NS_NewRootBoxFrame(mPresShell, viewportPseudoStyle);
     } else
 #endif
     {
       // pass a temporary stylecontext, the correct one will be set later
       rootFrame = NS_NewCanvasFrame(mPresShell, viewportPseudoStyle);
+      mHasRootAbsPosContainingBlock = PR_TRUE;
     }
 
     rootPseudo = nsCSSAnonBoxes::canvas;
     mDocElementContainingBlock = rootFrame;
   } else {
     // Create a page sequence frame
     rootFrame = NS_NewSimplePageSequenceFrame(mPresShell, viewportPseudoStyle);
     mPageSequenceFrame = rootFrame;
@@ -4517,40 +4531,41 @@ nsCSSFrameConstructor::ConstructRootFram
   
   if (isScrollable) {
     FinishBuildingScrollFrame(parentFrame, rootFrame);
   }
   
   if (isPaginated) { // paginated
     // Create the first page
     // Set the initial child lists
-    nsIFrame *pageFrame, *pageContentFrame;
+    nsIFrame *pageFrame, *canvasFrame;
     ConstructPageFrame(mPresShell, presContext, rootFrame, nsnull,
-                       pageFrame, pageContentFrame);
+                       pageFrame, canvasFrame);
     rootFrame->SetInitialChildList(nsnull, pageFrame);
 
     // The eventual parent of the document element frame.
     // XXX should this be set for every new page (in ConstructPageFrame)?
-    mDocElementContainingBlock = pageContentFrame;
+    mDocElementContainingBlock = canvasFrame;
+    mHasRootAbsPosContainingBlock = PR_TRUE;
   }
 
   viewportFrame->SetInitialChildList(nsnull, newFrame);
   
   *aNewFrame = viewportFrame;
 
   return NS_OK;
 }
 
 nsresult
-nsCSSFrameConstructor::ConstructPageFrame(nsIPresShell*   aPresShell,
+nsCSSFrameConstructor::ConstructPageFrame(nsIPresShell*  aPresShell,
                                           nsPresContext* aPresContext,
-                                          nsIFrame*       aParentFrame,
-                                          nsIFrame*       aPrevPageFrame,
-                                          nsIFrame*&      aPageFrame,
-                                          nsIFrame*&      aPageContentFrame)
+                                          nsIFrame*      aParentFrame,
+                                          nsIFrame*      aPrevPageFrame,
+                                          nsIFrame*&     aPageFrame,
+                                          nsIFrame*&     aCanvasFrame)
 {
   nsStyleContext* parentStyleContext = aParentFrame->GetStyleContext();
   nsStyleSet *styleSet = aPresShell->StyleSet();
 
   nsRefPtr<nsStyleContext> pagePseudoStyle;
   pagePseudoStyle = styleSet->ResolvePseudoStyleFor(nsnull,
                                                     nsCSSAnonBoxes::page,
                                                     parentStyleContext);
@@ -4563,31 +4578,47 @@ nsCSSFrameConstructor::ConstructPageFram
   // the pages easier and faster.
   aPageFrame->Init(nsnull, aParentFrame, aPrevPageFrame);
 
   nsRefPtr<nsStyleContext> pageContentPseudoStyle;
   pageContentPseudoStyle = styleSet->ResolvePseudoStyleFor(nsnull,
                                                            nsCSSAnonBoxes::pageContent,
                                                            pagePseudoStyle);
 
-  aPageContentFrame = NS_NewPageContentFrame(aPresShell, pageContentPseudoStyle);
-  if (NS_UNLIKELY(!aPageContentFrame))
+  nsIFrame* pageContentFrame = NS_NewPageContentFrame(aPresShell, pageContentPseudoStyle);
+  if (NS_UNLIKELY(!pageContentFrame))
     return NS_ERROR_OUT_OF_MEMORY;
 
   // Initialize the page content frame and force it to have a view. Also make it the
   // containing block for fixed elements which are repeated on every page.
   nsIFrame* prevPageContentFrame = nsnull;
   if (aPrevPageFrame) {
     prevPageContentFrame = aPrevPageFrame->GetFirstChild(nsnull);
     NS_ASSERTION(prevPageContentFrame, "missing page content frame");
   }
-  aPageContentFrame->Init(nsnull, aPageFrame, prevPageContentFrame);
-  mFixedContainingBlock = aPageContentFrame;
-
-  aPageFrame->SetInitialChildList(nsnull, aPageContentFrame);
+  pageContentFrame->Init(nsnull, aPageFrame, prevPageContentFrame);
+  aPageFrame->SetInitialChildList(nsnull, pageContentFrame);
+  mFixedContainingBlock = pageContentFrame;
+
+  nsRefPtr<nsStyleContext> canvasPseudoStyle;
+  canvasPseudoStyle = styleSet->ResolvePseudoStyleFor(nsnull,
+                                                      nsCSSAnonBoxes::canvas,
+                                                      pageContentPseudoStyle);
+
+  aCanvasFrame = NS_NewCanvasFrame(aPresShell, canvasPseudoStyle);
+  if (NS_UNLIKELY(!aCanvasFrame))
+    return NS_ERROR_OUT_OF_MEMORY;
+
+  nsIFrame* prevCanvasFrame = nsnull;
+  if (prevPageContentFrame) {
+    prevCanvasFrame = prevPageContentFrame->GetFirstChild(nsnull);
+    NS_ASSERTION(prevCanvasFrame, "missing canvas frame");
+  }
+  aCanvasFrame->Init(nsnull, pageContentFrame, prevCanvasFrame);
+  pageContentFrame->SetInitialChildList(nsnull, aCanvasFrame);
 
   return NS_OK;
 }
 
 /* static */
 nsresult
 nsCSSFrameConstructor::CreatePlaceholderFrameFor(nsIPresShell*    aPresShell, 
                                                  nsIContent*      aContent,
@@ -6676,27 +6707,34 @@ nsCSSFrameConstructor::InitAndRestoreFra
 
   return rv;
 }
 
 already_AddRefed<nsStyleContext>
 nsCSSFrameConstructor::ResolveStyleContext(nsIFrame*         aParentFrame,
                                            nsIContent*       aContent)
 {
-  nsStyleContext* parentStyleContext;
+  nsStyleContext* parentStyleContext = nsnull;
   if (aContent->GetParent()) {
     aParentFrame = nsFrame::CorrectStyleParentFrame(aParentFrame, nsnull);
   
-    // Resolve the style context based on the content object and the parent
-    // style context
-    parentStyleContext = aParentFrame->GetStyleContext();
+    if (aParentFrame) {
+      // Resolve the style context based on the content object and the parent
+      // style context
+      parentStyleContext = aParentFrame->GetStyleContext();
+    } else {
+      // Perhaps aParentFrame is a canvasFrame and we're replicating
+      // fixed-pos frames.
+      // XXX should we create a way to tell ConstructFrame which style
+      // context to use, and pass it the style context for the
+      // previous page's fixed-pos frame?
+    }
   } else {
     // This has got to be a call from ConstructDocElementTableFrame.
-    // Not sure how best to asserrt that here.
-    parentStyleContext = nsnull;
+    // Not sure how best to assert that here.
   }
 
   nsStyleSet *styleSet = mPresShell->StyleSet();
 
   if (aContent->IsNodeOfType(nsINode::eELEMENT)) {
     return styleSet->ResolveStyleFor(aContent, parentStyleContext);
   } else {
 
@@ -7499,27 +7537,33 @@ nsCSSFrameConstructor::ReconstructDocEle
 
   nsresult rv = NS_OK;
 
   // XXXbz is that null-check needed?  Why?
   if (mDocument && mPresShell) {
     nsIContent *rootContent = mDocument->GetRootContent();
     
     if (rootContent) {
+      nsFrameConstructorState state(mPresShell, mFixedContainingBlock,
+                                    nsnull, nsnull, mTempFrameTreeState);
+
       // Before removing the frames associated with the content object, ask them to save their
       // state onto a temporary state object.
-      CaptureStateForFramesOf(rootContent, mTempFrameTreeState);
-
-      nsFrameConstructorState state(mPresShell, mFixedContainingBlock,
-                                    nsnull, nsnull, mTempFrameTreeState);
+      CaptureStateFor(state.mFrameManager->GetRootFrame(), mTempFrameTreeState);
 
       // Get the frame that corresponds to the document element
       nsIFrame* docElementFrame =
         state.mFrameManager->GetPrimaryFrameFor(rootContent, -1);
-        
+
+      if (docElementFrame) {
+        // Destroy out-of-flow frames that might not be in the frame subtree
+        // rooted at docElementFrame
+        ::DeletingFrameSubtree(state.mFrameManager, docElementFrame);
+      }
+
       // Remove any existing fixed items: they are always on the
       // FixedContainingBlock.  Note that this has to be done before we call
       // ClearPlaceholderFrameMap(), since RemoveFixedItems uses the
       // placeholder frame map.
       rv = RemoveFixedItems(state);
       if (NS_SUCCEEDED(rv)) {
         // Clear the hash tables that map from content to frame and out-of-flow
         // frame to placeholder frame
@@ -7527,27 +7571,24 @@ nsCSSFrameConstructor::ReconstructDocEle
         state.mFrameManager->ClearPlaceholderFrameMap();
         state.mFrameManager->ClearUndisplayedContentMap();
 
         if (docElementFrame) {
           // Take the docElementFrame, and remove it from its parent.
         
           // XXXbz So why can't we reuse ContentRemoved?
 
-          NS_ASSERTION(docElementFrame->GetParent() == mDocElementContainingBlock,
-                       "Unexpected doc element parent frame");
-
           // Notify self that we will destroy the entire frame tree, this blocks
           // RemoveMappingsForFrameSubtree() which would otherwise lead to a
           // crash since we cleared the placeholder map above (bug 398982).
           PRBool wasDestroyingFrameTree = mIsDestroyingFrameTree;
           WillDestroyFrameTree();
-          // Remove the old document element hieararchy
-          rv = state.mFrameManager->RemoveFrame(mDocElementContainingBlock,
-                                                nsnull, docElementFrame);
+          // Remove the old document element hierarchy
+          rv = state.mFrameManager->RemoveFrame(docElementFrame->GetParent(),
+                    GetChildListNameFor(docElementFrame), docElementFrame);
           mIsDestroyingFrameTree = wasDestroyingFrameTree;
           if (NS_FAILED(rv)) {
             return rv;
           }
         }
         
         mInitialContainingBlock = nsnull;
         mRootElementStyleFrame = nsnull;
@@ -7634,19 +7675,18 @@ nsCSSFrameConstructor::GetAbsoluteContai
     }
   }
 
   // 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 initial containing block if it
-  // supports abs pos kids.
-  return mInitialContainingBlockIsAbsPosContainer ? mInitialContainingBlock : nsnull;
+  // If we didn't find it, then use the document element containing block
+  return mHasRootAbsPosContainingBlock ? mDocElementContainingBlock : nsnull;
 }
 
 nsIFrame*
 nsCSSFrameConstructor::GetFloatContainingBlock(nsIFrame* aFrame)
 {
   NS_PRECONDITION(mInitialContainingBlock, "no initial containing block");
   
   // Starting with aFrame, look for a frame that is a float containing block.
@@ -10221,19 +10261,19 @@ nsCSSFrameConstructor::CreateContinuingF
 
     if (newFrame) {
       newFrame->Init(content, aParentFrame, aFrame);
       // XXXbz should we be passing in a non-null aContentParentFrame?
       nsHTMLContainerFrame::CreateViewForFrame(newFrame, nsnull, PR_FALSE);
     }
 
   } else if (nsGkAtoms::pageFrame == frameType) {
-    nsIFrame* pageContentFrame;
+    nsIFrame* canvasFrame;
     rv = ConstructPageFrame(shell, aPresContext, aParentFrame, aFrame,
-                            newFrame, pageContentFrame);
+                            newFrame, canvasFrame);
   } else if (nsGkAtoms::tableOuterFrame == frameType) {
     rv = CreateContinuingOuterTableFrame(shell, aPresContext, aFrame, aParentFrame,
                                          content, styleContext, &newFrame);
 
   } else if (nsGkAtoms::tableFrame == frameType) {
     rv = CreateContinuingTableFrame(shell, aPresContext, aFrame, aParentFrame,
                                     content, styleContext, &newFrame);
 
@@ -10412,27 +10452,27 @@ nsCSSFrameConstructor::CreateContinuingF
     newFrame->SetNextContinuation(nextContinuation);
   }
   return NS_OK;
 }
 
 nsresult
 nsCSSFrameConstructor::ReplicateFixedFrames(nsPageContentFrame* aParentFrame)
 {
-  // Now deal with fixed-pos things....  They should appear on all pages, and
-  // the placeholders must be kids of a block, so we want to move over the
-  // placeholders when processing the child of the pageContentFrame.
+  // Now deal with fixed-pos things....  They should appear on all pages,
+  // so we want to move over the placeholders when processing the child
+  // of the pageContentFrame.
 
   nsIFrame* prevPageContentFrame = aParentFrame->GetPrevInFlow();
   if (!prevPageContentFrame) {
     return NS_OK;
   }
-  nsIFrame* docRootFrame = aParentFrame->GetFirstChild(nsnull);
-  nsIFrame* prevDocRootFrame = prevPageContentFrame->GetFirstChild(nsnull);
-  if (!docRootFrame || !prevDocRootFrame) {
+  nsIFrame* canvasFrame = aParentFrame->GetFirstChild(nsnull);
+  nsIFrame* prevCanvasFrame = prevPageContentFrame->GetFirstChild(nsnull);
+  if (!canvasFrame || !prevCanvasFrame) {
     // document's root element frame missing
     return NS_ERROR_UNEXPECTED;
   }
 
   nsFrameItems fixedPlaceholders;
   nsIFrame* firstFixed = prevPageContentFrame->GetFirstChild(nsGkAtoms::fixedList);
   if (!firstFixed) {
     return NS_OK;
@@ -10450,29 +10490,29 @@ nsCSSFrameConstructor::ReplicateFixedFra
   // Iterate across fixed frames and replicate each whose placeholder is a
   // descendant of aFrame. (We don't want to explicitly copy placeholders that
   // are within fixed frames, because that would cause duplicates on the new
   // page - bug 389619)
   for (nsIFrame* fixed = firstFixed; fixed; fixed = fixed->GetNextSibling()) {
     nsIFrame* prevPlaceholder = nsnull;
     mPresShell->GetPlaceholderFrameFor(fixed, &prevPlaceholder);
     if (prevPlaceholder &&
-        nsLayoutUtils::IsProperAncestorFrame(prevDocRootFrame, prevPlaceholder)) {
+        nsLayoutUtils::IsProperAncestorFrame(prevCanvasFrame, prevPlaceholder)) {
       nsresult rv = ConstructFrame(state, fixed->GetContent(),
-                                   docRootFrame, fixedPlaceholders);
+                                   canvasFrame, fixedPlaceholders);
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
 
   // Add the placeholders to our primary child list.
-  // XXXbz this is a little screwed up, since the fixed frames will have the
-  // wrong parent block and hence auto-positioning will be broken.  Oh, well.
-  NS_ASSERTION(!docRootFrame->GetFirstChild(nsnull),
+  // XXXbz this is a little screwed up, since the fixed frames will have 
+  // broken auto-positioning. Oh, well.
+  NS_ASSERTION(!canvasFrame->GetFirstChild(nsnull),
                "leaking frames; doc root continuation must be empty");
-  docRootFrame->SetInitialChildList(nsnull, fixedPlaceholders.childList);
+  canvasFrame->SetInitialChildList(nsnull, fixedPlaceholders.childList);
   return NS_OK;
 }
 
 static PRBool
 IsBindingAncestor(nsIContent* aContent, nsIContent* aBindingRoot)
 {
   while (PR_TRUE) {
     // Native-anonymous content doesn't contain insertion points, so
--- a/layout/base/nsCSSFrameConstructor.h
+++ b/layout/base/nsCSSFrameConstructor.h
@@ -265,17 +265,17 @@ private:
   nsresult ReinsertContent(nsIContent*    aContainer,
                            nsIContent*    aChild);
 
   nsresult ConstructPageFrame(nsIPresShell*  aPresShell, 
                               nsPresContext* aPresContext,
                               nsIFrame*      aParentFrame,
                               nsIFrame*      aPrevPageFrame,
                               nsIFrame*&     aPageFrame,
-                              nsIFrame*&     aPageContentFrame);
+                              nsIFrame*&     aCanvasFrame);
 
   void DoContentStateChanged(nsIContent*     aContent,
                              PRInt32         aStateMask);
 
   /* aMinHint is the minimal change that should be made to the element */
   void RestyleElement(nsIContent*     aContent,
                       nsIFrame*       aPrimaryFrame,
                       nsChangeHint    aMinHint);
@@ -1159,16 +1159,19 @@ private:
     nsCOMPtr<nsIPresShell> mPresShell;
     nsLazyFrameConstructionCallback* mCallback;
     void* mArg;
   };
 
   nsIDocument*        mDocument;  // Weak ref
   nsIPresShell*       mPresShell; // Weak ref
 
+  // See the comment at the start of ConstructRootFrame for more details
+  // about the following frames.
+  
   // This is not the real CSS 2.1 "initial containing block"! It is just
   // the outermost frame for the root element.
   nsIFrame*           mInitialContainingBlock;
   // This is the frame for the root element that has no pseudo-element style.
   nsIFrame*           mRootElementStyleFrame;
   // This is the containing block for fixed-pos frames --- the viewport
   nsIFrame*           mFixedContainingBlock;
   // This is the containing block that contains the root element ---
@@ -1176,19 +1179,20 @@ private:
   nsIFrame*           mDocElementContainingBlock;
   nsIFrame*           mGfxScrollFrame;
   nsIFrame*           mPageSequenceFrame;
   nsQuoteList         mQuoteList;
   nsCounterManager    mCounterManager;
   PRUint16            mUpdateCount;
   PRPackedBool        mQuotesDirty : 1;
   PRPackedBool        mCountersDirty : 1;
-  PRPackedBool        mInitialContainingBlockIsAbsPosContainer : 1;
   PRPackedBool        mIsDestroyingFrameTree : 1;
   PRPackedBool        mRebuildAllStyleData : 1;
+  // This is true if mDocElementContainingBlock supports absolute positioning
+  PRPackedBool        mHasRootAbsPosContainingBlock : 1;
 
   nsRevocableEventPtr<RestyleEvent> mRestyleEvent;
 
   nsCOMPtr<nsILayoutHistoryState> mTempFrameTreeState;
 
   nsDataHashtable<nsISupportsHashKey, RestyleData> mPendingRestyles;
 
   static nsIXBLService * gXBLService;
--- a/layout/generic/nsAbsoluteContainingBlock.cpp
+++ b/layout/generic/nsAbsoluteContainingBlock.cpp
@@ -47,27 +47,16 @@
 #include "nsHTMLContainerFrame.h"
 #include "nsHTMLParts.h"
 #include "nsPresContext.h"
 
 #ifdef DEBUG
 #include "nsBlockFrame.h"
 #endif
 
-
-nsresult
-nsAbsoluteContainingBlock::FirstChild(const nsIFrame* aDelegatingFrame,
-                                      nsIAtom*        aListName,
-                                      nsIFrame**      aFirstChild) const
-{
-  NS_PRECONDITION(GetChildListName() == aListName, "unexpected child list name");
-  *aFirstChild = mAbsoluteFrames.FirstChild();
-  return NS_OK;
-}
-
 nsresult
 nsAbsoluteContainingBlock::SetInitialChildList(nsIFrame*       aDelegatingFrame,
                                                nsIAtom*        aListName,
                                                nsIFrame*       aChildList)
 {
   NS_PRECONDITION(GetChildListName() == aListName, "unexpected child list name");
 #ifdef NS_DEBUG
   nsFrame::VerifyDirtyBitSet(aChildList);
--- a/layout/generic/nsAbsoluteContainingBlock.h
+++ b/layout/generic/nsAbsoluteContainingBlock.h
@@ -79,20 +79,17 @@ public:
                  mChildListName == nsGkAtoms::fixedList,
                  "should either represent position:fixed or absolute content");
   }
 
 #ifdef DEBUG
   nsIAtom* GetChildListName() const { return mChildListName; }
 #endif
 
-  nsresult FirstChild(const nsIFrame* aDelegatingFrame,
-                      nsIAtom*        aListName,
-                      nsIFrame**      aFirstChild) const;
-  nsIFrame* GetFirstChild() { return mAbsoluteFrames.FirstChild(); }
+  nsIFrame* GetFirstChild() const { return mAbsoluteFrames.FirstChild(); }
 
   nsresult SetInitialChildList(nsIFrame*       aDelegatingFrame,
                                nsIAtom*        aListName,
                                nsIFrame*       aChildList);
   nsresult AppendFrames(nsIFrame*      aDelegatingFrame,
                         nsIAtom*       aListName,
                         nsIFrame*      aFrameList);
   nsresult InsertFrames(nsIFrame*      aDelegatingFrame,
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -515,19 +515,17 @@ nsBlockFrame::GetBaseline() const
 
 /////////////////////////////////////////////////////////////////////////////
 // Child frame enumeration
 
 nsIFrame*
 nsBlockFrame::GetFirstChild(nsIAtom* aListName) const
 {
   if (nsGkAtoms::absoluteList == aListName) {
-    nsIFrame* result = nsnull;
-    mAbsoluteContainer.FirstChild(this, aListName, &result);
-    return result;
+    return mAbsoluteContainer.GetFirstChild();
   }
   else if (nsnull == aListName) {
     return (mLines.empty()) ? nsnull : mLines.front()->mFirstChild;
   }
   else if (aListName == nsGkAtoms::overflowList) {
     nsLineList* overflowLines = GetOverflowLines();
     return overflowLines ? overflowLines->front()->mFirstChild : nsnull;
   }
@@ -798,37 +796,35 @@ CalculateContainingBlockSizeForAbsolutes
 
   nsSize cbSize(aFrameSize);
     // Containing block is relative to the padding edge
   const nsMargin& border =
     aReflowState.mComputedBorderPadding - aReflowState.mComputedPadding;
   cbSize.width -= border.LeftRight();
   cbSize.height -= border.TopBottom();
 
-  if (frame->GetParent()->GetContent() == frame->GetContent()) {
-    // We are a wrapped frame for the content. Use the container's
-    // dimensions, if they have been precomputed.
+  if (frame->GetParent()->GetContent() == frame->GetContent() &&
+      frame->GetParent()->GetType() != nsGkAtoms::canvasFrame) {
+    // We are a wrapped frame for the content (and the wrapper is not the
+    // canvas frame, whose size is not meaningful here).
+    // Use the container's dimensions, if they have been precomputed.
     // XXX This is a hack! We really should be waiting until the outermost
     // frame is fully reflowed and using the resulting dimensions, even
     // if they're intrinsic.
     // In fact we should be attaching absolute children to the outermost
     // frame and not always sticking them in block frames.
 
     // First, find the reflow state for the outermost frame for this
     // content.
     const nsHTMLReflowState* aLastRS = &aReflowState;
     const nsHTMLReflowState* lastButOneRS = &aReflowState;
-    PRBool isCanvasBlock = PR_FALSE;
     while (aLastRS->parentReflowState &&
            aLastRS->parentReflowState->frame->GetContent() == frame->GetContent()) {
       lastButOneRS = aLastRS;
       aLastRS = aLastRS->parentReflowState;
-      if (aLastRS->frame->GetType() == nsGkAtoms::canvasFrame) {
-        isCanvasBlock = PR_TRUE;
-      }
     }
     if (aLastRS != &aReflowState) {
       // Scrollbars need to be specifically excluded, if present, because they are outside the
       // padding-edge. We need better APIs for getting the various boxes from a frame.
       nsIScrollableFrame* scrollFrame;
       CallQueryInterface(aLastRS->frame, &scrollFrame);
       nsMargin scrollbars(0,0,0,0);
       if (scrollFrame) {
@@ -839,33 +835,21 @@ CalculateContainingBlockSizeForAbsolutes
           scrollbars.top = scrollbars.bottom = 0;
         }
         if (!lastButOneRS->mFlags.mAssumingVScrollbar) {
           scrollbars.left = scrollbars.right = 0;
         }
       }
       // We found a reflow state for the outermost wrapping frame, so use
       // its computed metrics if available
-      // XXX grotesque hack for Firefox 2 compatibility until we can
-      // properly fix abs-pos containers! If this is the block for
-      // the root element, don't adjust the width here, just use the block's
-      // width. We have to do this because the abs-pos frame will be
-      // positioned relative to the block, not the canvas frame, and the
-      // block might have borders and margin which will throw things off
-      // if we use the canvas frame width.
-      // Positioning abs-pos frames relative to the canvas is bug 425432.
-      if (aLastRS->ComputedWidth() != NS_UNCONSTRAINEDSIZE && !isCanvasBlock) {
+      if (aLastRS->ComputedWidth() != NS_UNCONSTRAINEDSIZE) {
         cbSize.width = PR_MAX(0,
           aLastRS->ComputedWidth() + aLastRS->mComputedPadding.LeftRight() - scrollbars.LeftRight());
       }
       if (aLastRS->ComputedHeight() != NS_UNCONSTRAINEDSIZE) {
-        // XXX This can be terribly wrong if we're the root element's block,
-        // because our margin and borders will be included in the height
-        // here but the abs-pos element(s) are positioned relative to
-        // our content rect...
         cbSize.height = PR_MAX(0,
           aLastRS->ComputedHeight() + aLastRS->mComputedPadding.TopBottom() - scrollbars.TopBottom());
       }
     }
   }
 
   return cbSize;
 }
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -1579,16 +1579,19 @@ nsContainerFrame::List(FILE* out, PRInt3
             NS_LossyConvertUTF16toASCII(atomString).get());
   }
 
   // Output the children
   nsIAtom* listName = nsnull;
   PRInt32 listIndex = 0;
   PRBool outputOneList = PR_FALSE;
   do {
+    if (!outputOneList) {
+      fputs("\n", out);
+    }
     nsIFrame* kid = GetFirstChild(listName);
     if (nsnull != kid) {
       if (outputOneList) {
         IndentBy(out, aIndent);
       }
       outputOneList = PR_TRUE;
       nsAutoString tmp;
       if (nsnull != listName) {
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -5554,22 +5554,29 @@ nsFrame::CorrectStyleParentFrame(nsIFram
          // ancestor.
          aChildPseudo != nsGkAtoms::placeholderFrame)) {
       return parent;
     }
 
     parent = parent->GetParent();
   } while (parent);
 
-  // We can get here if aProspectiveParent is the scrollframe for a viewport
-  // and the kids are the anonymous scrollbars.
-  NS_ASSERTION(aProspectiveParent->GetStyleContext()->GetPseudoType() ==
-                 nsCSSAnonBoxes::viewportScroll,
+  if (aProspectiveParent->GetStyleContext()->GetPseudoType() ==
+      nsCSSAnonBoxes::viewportScroll) {
+    // aProspectiveParent is the scrollframe for a viewport
+    // and the kids are the anonymous scrollbars
+    return aProspectiveParent;
+  }
+
+  // We can get here if the root element is absolutely positioned.
+  // We can't test for this very accurately, but it can only happen
+  // when the prospective parent is a canvas frame.
+  NS_ASSERTION(aProspectiveParent->GetType() == nsGkAtoms::canvasFrame,
                "Should have found a parent before this");
-  return aProspectiveParent;
+  return nsnull;
 }
 
 nsresult
 nsFrame::DoGetParentStyleContextFrame(nsPresContext* aPresContext,
                                       nsIFrame**      aProviderFrame,
                                       PRBool*         aIsChild)
 {
   *aIsChild = PR_FALSE;
--- a/layout/generic/nsHTMLFrame.cpp
+++ b/layout/generic/nsHTMLFrame.cpp
@@ -49,68 +49,82 @@
 #include "nsGUIEvent.h"
 #include "nsStyleConsts.h"
 #include "nsGkAtoms.h"
 #include "nsIEventStateManager.h"
 #include "nsIDeviceContext.h"
 #include "nsIPresShell.h"
 #include "nsIScrollPositionListener.h"
 #include "nsDisplayList.h"
+#include "nsAbsoluteContainingBlock.h"
 
 // for focus
 #include "nsIDOMWindowInternal.h"
 #include "nsIFocusController.h"
 #include "nsIScrollableFrame.h"
 #include "nsIScrollableView.h"
 #include "nsIDocShell.h"
 #include "nsICanvasFrame.h"
 
 #ifdef DEBUG_rods
 //#define DEBUG_CANVAS_FOCUS
 #endif
 
+#define CANVAS_ABS_POS_CHILD_LIST NS_CONTAINER_LIST_COUNT_INCL_OC
+
 // Interface IDs
 
 /**
  * Root frame class.
  *
  * The root frame is the parent frame for the document element's frame.
  * It only supports having a single child frame which must be an area
  * frame
  */
 class CanvasFrame : public nsHTMLContainerFrame, 
                     public nsIScrollPositionListener, 
                     public nsICanvasFrame {
 public:
   CanvasFrame(nsStyleContext* aContext)
-  : nsHTMLContainerFrame(aContext), mDoPaintFocus(PR_FALSE) {}
+  : nsHTMLContainerFrame(aContext), mDoPaintFocus(PR_FALSE),
+    mAbsoluteContainer(nsGkAtoms::absoluteList) {}
 
    // nsISupports
   NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
 
   NS_IMETHOD Init(nsIContent*      aContent,
                   nsIFrame*        aParent,
                   nsIFrame*        aPrevInFlow);
   virtual void Destroy();
 
+  NS_IMETHOD SetInitialChildList(nsIAtom*        aListName,
+                                 nsIFrame*       aChildList);
   NS_IMETHOD AppendFrames(nsIAtom*        aListName,
                           nsIFrame*       aFrameList);
   NS_IMETHOD InsertFrames(nsIAtom*        aListName,
                           nsIFrame*       aPrevFrame,
                           nsIFrame*       aFrameList);
   NS_IMETHOD RemoveFrame(nsIAtom*        aListName,
                          nsIFrame*       aOldFrame);
 
+  virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const;
+  virtual nsIFrame* GetFirstChild(nsIAtom* aListName) const;
+
   virtual nscoord GetMinWidth(nsIRenderingContext *aRenderingContext);
   virtual nscoord GetPrefWidth(nsIRenderingContext *aRenderingContext);
   NS_IMETHOD Reflow(nsPresContext*          aPresContext,
                     nsHTMLReflowMetrics&     aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
                     nsReflowStatus&          aStatus);
   virtual PRBool IsContainingBlock() const { return PR_TRUE; }
+  virtual PRBool IsFrameOfType(PRUint32 aFlags) const
+  {
+    return nsHTMLContainerFrame::IsFrameOfType(aFlags &
+             ~(nsIFrame::eCanContainOverflowContainers));
+  }
 
   NS_IMETHOD BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                               const nsRect&           aDirtyRect,
                               const nsDisplayListSet& aLists);
 
   void PaintFocus(nsIRenderingContext& aRenderingContext, nsPoint aPt);
 
   // nsIScrollPositionListener
@@ -123,31 +137,47 @@ public:
 
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::canvasFrame
    */
   virtual nsIAtom* GetType() const;
 
+  virtual nsresult StealFrame(nsPresContext* aPresContext,
+                              nsIFrame*      aChild,
+                              PRBool         aForceNormal)
+  {
+    NS_ASSERTION(!aForceNormal, "No-one should be passing this in here");
+
+    // CanvasFrame keeps overflow container continuations of its child
+    // frame in main child list
+    nsresult rv = nsContainerFrame::StealFrame(aPresContext, aChild, PR_TRUE);
+    if (NS_FAILED(rv)) {
+      rv = nsContainerFrame::StealFrame(aPresContext, aChild);
+    }
+    return rv;
+  }
+
 #ifdef DEBUG
   NS_IMETHOD GetFrameName(nsAString& aResult) const;
 #endif
   NS_IMETHOD GetContentForEvent(nsPresContext* aPresContext,
                                 nsEvent* aEvent,
                                 nsIContent** aContent);
 
   nsRect CanvasArea() const;
 
 protected:
   virtual PRIntn GetSkipSides() const;
 
   // Data members
-  PRPackedBool             mDoPaintFocus;
-  nsCOMPtr<nsIViewManager> mViewManager;
+  PRPackedBool              mDoPaintFocus;
+  nsCOMPtr<nsIViewManager>  mViewManager;
+  nsAbsoluteContainingBlock mAbsoluteContainer;
 
 private:
   NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
   NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
 };
 
 
 //----------------------------------------------------------------------
@@ -193,16 +223,18 @@ CanvasFrame::Init(nsIContent*      aCont
   }
 
   return rv;
 }
 
 void
 CanvasFrame::Destroy()
 {
+  mAbsoluteContainer.DestroyFrames(this);
+
   nsIScrollableView* scrollingView = nsnull;
   mViewManager->GetRootScrollableView(&scrollingView);
   if (scrollingView) {
     scrollingView->RemoveScrollPositionListener(this);
   }
 
   nsHTMLContainerFrame::Destroy();
 }
@@ -241,30 +273,42 @@ CanvasFrame::ScrollPositionDidChange(nsI
   return NS_OK;
 }
 
 NS_IMETHODIMP
 CanvasFrame::SetHasFocus(PRBool aHasFocus)
 {
   if (mDoPaintFocus != aHasFocus) {
     mDoPaintFocus = aHasFocus;
-    nsIViewManager* vm = PresContext()->PresShell()->GetViewManager();
-    if (vm) {
-      vm->UpdateAllViews(NS_VMREFRESH_NO_SYNC);
-    }
+    mViewManager->UpdateAllViews(NS_VMREFRESH_NO_SYNC);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
+CanvasFrame::SetInitialChildList(nsIAtom*        aListName,
+                                 nsIFrame*       aChildList)
+{
+  if (nsGkAtoms::absoluteList == aListName)
+    return mAbsoluteContainer.SetInitialChildList(this, aListName, aChildList);
+
+  NS_ASSERTION(aListName || !aChildList || !aChildList->GetNextSibling(),
+               "Primary child list can have at most one frame in it");
+  return nsHTMLContainerFrame::SetInitialChildList(aListName, aChildList);
+}
+
+NS_IMETHODIMP
 CanvasFrame::AppendFrames(nsIAtom*        aListName,
                           nsIFrame*       aFrameList)
 {
   nsresult  rv;
 
+  if (nsGkAtoms::absoluteList == aListName)
+    return mAbsoluteContainer.AppendFrames(this, aListName, aFrameList);
+
   NS_ASSERTION(!aListName, "unexpected child list name");
   NS_PRECONDITION(mFrames.IsEmpty(), "already have a child frame");
   if (aListName) {
     // We only support unnamed principal child list
     rv = NS_ERROR_INVALID_ARG;
 
   } else if (!mFrames.IsEmpty()) {
     // We only allow a single child frame
@@ -287,16 +331,19 @@ CanvasFrame::AppendFrames(nsIAtom*      
 
 NS_IMETHODIMP
 CanvasFrame::InsertFrames(nsIAtom*        aListName,
                           nsIFrame*       aPrevFrame,
                           nsIFrame*       aFrameList)
 {
   nsresult  rv;
 
+  if (nsGkAtoms::absoluteList == aListName)
+    return mAbsoluteContainer.InsertFrames(this, aListName, 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) {
     rv = NS_ERROR_UNEXPECTED;
   } else {
     rv = AppendFrames(aListName, aFrameList);
   }
@@ -305,16 +352,19 @@ CanvasFrame::InsertFrames(nsIAtom*      
 }
 
 NS_IMETHODIMP
 CanvasFrame::RemoveFrame(nsIAtom*        aListName,
                          nsIFrame*       aOldFrame)
 {
   nsresult  rv;
 
+  if (nsGkAtoms::absoluteList == aListName)
+    return mAbsoluteContainer.RemoveFrame(this, aListName, aOldFrame);
+
   NS_ASSERTION(!aListName, "unexpected child list name");
   if (aListName) {
     // We only support the unnamed principal child list
     rv = NS_ERROR_INVALID_ARG;
   
   } else if (aOldFrame == mFrames.FirstChild()) {
     // It's our one and only child frame
     // Damage the area occupied by the deleted frame
@@ -330,16 +380,34 @@ CanvasFrame::RemoveFrame(nsIAtom*       
                             NS_FRAME_HAS_DIRTY_CHILDREN);
   } else {
     rv = NS_ERROR_FAILURE;
   }
 
   return rv;
 }
 
+nsIAtom*
+CanvasFrame::GetAdditionalChildListName(PRInt32 aIndex) const
+{
+  if (CANVAS_ABS_POS_CHILD_LIST == aIndex)
+    return nsGkAtoms::absoluteList;
+
+  return nsHTMLContainerFrame::GetAdditionalChildListName(aIndex);
+}
+
+nsIFrame*
+CanvasFrame::GetFirstChild(nsIAtom* aListName) const
+{
+  if (nsGkAtoms::absoluteList == aListName)
+    return mAbsoluteContainer.GetFirstChild();
+
+  return nsHTMLContainerFrame::GetFirstChild(aListName);
+}
+
 nsRect CanvasFrame::CanvasArea() const
 {
   nsRect result(GetOverflowRect());
 
   nsIScrollableFrame *scrollableFrame;
   CallQueryInterface(GetParent(), &scrollableFrame);
   if (scrollableFrame) {
     nsIScrollableView* scrollableView = scrollableFrame->GetScrollableView();
@@ -414,31 +482,38 @@ public:
 };
 
 NS_IMETHODIMP
 CanvasFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                               const nsRect&           aDirtyRect,
                               const nsDisplayListSet& aLists)
 {
   nsresult rv;
+
+  if (GetPrevInFlow()) {
+    DisplayOverflowContainers(aBuilder, aDirtyRect, aLists);
+  }
+
+  aBuilder->MarkFramesForDisplayList(this, mAbsoluteContainer.GetFirstChild(), 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)) { 
     rv = aLists.BorderBackground()->AppendNewToTop(new (aBuilder)
            nsDisplayCanvasBackground(this));
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
-  nsIFrame* kid = GetFirstChild(nsnull);
-  if (kid) {
+  nsIFrame* kid;
+  for (kid = GetFirstChild(nsnull); kid; kid = kid->GetNextSibling()) {
     // Put our child into its own pseudo-stack.
     rv = BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists,
                                   DISPLAY_CHILD_FORCE_PSEUDO_STACKING_CONTEXT);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
 #ifdef DEBUG_CANVAS_FOCUS
   nsCOMPtr<nsIContent> focusContent;
@@ -523,88 +598,150 @@ CanvasFrame::GetPrefWidth(nsIRenderingCo
   if (mFrames.IsEmpty())
     result = 0;
   else
     result = mFrames.FirstChild()->GetPrefWidth(aRenderingContext);
   return result;
 }
 
 NS_IMETHODIMP
-CanvasFrame::Reflow(nsPresContext*          aPresContext,
+CanvasFrame::Reflow(nsPresContext*           aPresContext,
                     nsHTMLReflowMetrics&     aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
                     nsReflowStatus&          aStatus)
 {
   DO_GLOBAL_REFLOW_COUNT("CanvasFrame");
   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
   NS_FRAME_TRACE_REFLOW_IN("CanvasFrame::Reflow");
 
   // Initialize OUT parameter
   aStatus = NS_FRAME_COMPLETE;
 
-  // Reflow our one and only child frame
+  CanvasFrame* prevCanvasFrame = static_cast<CanvasFrame*>
+                                               (GetPrevInFlow());
+  if (prevCanvasFrame) {
+    nsIFrame* overflow = prevCanvasFrame->GetOverflowFrames(aPresContext, PR_TRUE);
+    if (overflow) {
+      NS_ASSERTION(!overflow->GetNextSibling(),
+                   "must have doc root as canvas frame's only child");
+      nsHTMLContainerFrame::ReparentFrameView(aPresContext, overflow, prevCanvasFrame, this);
+      // Prepend overflow to the our child list. There may already be
+      // children placeholders for fixed-pos elements, which don't get
+      // reflowed but must not be lost until the canvas frame is destroyed.
+      mFrames.InsertFrames(this, nsnull, overflow);
+    }
+  }
+
+  // Reflow our one and only normal child frame. It's either the root
+  // element's frame or a placeholder for that frame, if the root element
+  // is abs-pos or fixed-pos. We may have additional children which
+  // are placeholders for continuations of fixed-pos content, but those
+  // don't need to be reflowed. The normal child is always comes before
+  // the fixed-pos placeholders, because we insert it at the start
+  // of the child list, above.
   nsHTMLReflowMetrics kidDesiredSize;
   if (mFrames.IsEmpty()) {
     // We have no child frame, so return an empty size
     aDesiredSize.width = aDesiredSize.height = 0;
   } else {
     nsIFrame* kidFrame = mFrames.FirstChild();
     PRBool kidDirty = (kidFrame->GetStateBits() & NS_FRAME_IS_DIRTY) != 0;
 
-    // We must specify an unconstrained available height, because constrained
-    // is only for when we're paginated...
     nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame,
                                      nsSize(aReflowState.availableWidth,
-                                            NS_UNCONSTRAINEDSIZE));
+                                            aReflowState.availableHeight));
 
     if (aReflowState.mFlags.mVResize &&
         (kidFrame->GetStateBits() & NS_FRAME_CONTAINS_RELATIVE_HEIGHT)) {
       // Tell our kid it's being vertically resized too.  Bit of a
       // hack for framesets.
       kidReflowState.mFlags.mVResize = PR_TRUE;
     }
-    
+
+    nsPoint kidPt(kidReflowState.mComputedMargin.left,
+                  kidReflowState.mComputedMargin.top);
+    // Apply CSS relative positioning
+    const nsStyleDisplay* styleDisp = kidFrame->GetStyleDisplay();
+    if (NS_STYLE_POSITION_RELATIVE == styleDisp->mPosition) {
+      kidPt += nsPoint(kidReflowState.mComputedOffsets.left,
+                       kidReflowState.mComputedOffsets.top);
+    }
+
     // Reflow the frame
     ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState,
-                kidReflowState.mComputedMargin.left, kidReflowState.mComputedMargin.top,
-                0, aStatus);
+                kidPt.x, kidPt.y, 0, aStatus);
 
     // Complete the reflow and position and size the child frame
     FinishReflowChild(kidFrame, aPresContext, &kidReflowState, kidDesiredSize,
-                      kidReflowState.mComputedMargin.left,
-                      kidReflowState.mComputedMargin.top, 0);
+                      kidPt.x, kidPt.y, 0);
+
+    if (!NS_FRAME_IS_FULLY_COMPLETE(aStatus)) {
+      nsIFrame* nextFrame = kidFrame->GetNextInFlow();
+      NS_ASSERTION(nextFrame || aStatus & NS_FRAME_REFLOW_NEXTINFLOW,
+        "If it's incomplete and has no nif yet, it must flag a nif reflow.");
+      if (!nextFrame) {
+        nsresult rv = nsHTMLContainerFrame::CreateNextInFlow(aPresContext,
+                                              this, kidFrame, nextFrame);
+        NS_ENSURE_SUCCESS(rv, rv);
+        kidFrame->SetNextSibling(nextFrame->GetNextSibling());
+        nextFrame->SetNextSibling(nsnull);
+        SetOverflowFrames(aPresContext, nextFrame);
+        // Root overflow containers will be normal children of
+        // the canvas frame, but that's ok because there
+        // aren't any other frames we need to isolate them from
+        // during reflow.
+      }
+      if (NS_FRAME_OVERFLOW_IS_INCOMPLETE(aStatus)) {
+        nextFrame->AddStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER);
+      }
+    }
 
     // If the child frame was just inserted, then we're responsible for making sure
     // it repaints
     if (kidDirty) {
       // But we have a new child, which will affect our background, so
       // invalidate our whole rect.
       // Note: Even though we request to be sized to our child's size, our
       // scroll frame ensures that we are always the size of the viewport.
       // Also note: GetPosition() on a CanvasFrame is always going to return
       // (0, 0). We only want to invalidate GetRect() since GetOverflowRect()
       // could also include overflow to our top and left (out of the viewport)
       // which doesn't need to be painted.
       nsIFrame* viewport = PresContext()->GetPresShell()->GetRootFrame();
       viewport->Invalidate(nsRect(nsPoint(0, 0), viewport->GetSize()));
     }
-
+    
     // Return our desired size (which doesn't matter)
-    aDesiredSize.width = aReflowState.availableWidth;
-    aDesiredSize.height = kidDesiredSize.height +
-                          kidReflowState.mComputedMargin.TopBottom();
+    aDesiredSize.width = aReflowState.ComputedWidth();
+    aDesiredSize.height = aReflowState.ComputedHeight();
 
     aDesiredSize.mOverflowArea.UnionRect(
       nsRect(0, 0, aDesiredSize.width, aDesiredSize.height),
-      kidDesiredSize.mOverflowArea +
-        nsPoint(kidReflowState.mComputedMargin.left,
-                kidReflowState.mComputedMargin.top));
-    FinishAndStoreOverflow(&aDesiredSize);
+      kidDesiredSize.mOverflowArea + kidPt);
+
+    if (mAbsoluteContainer.HasAbsoluteFrames()) {
+      PRBool widthChanged = aDesiredSize.width != mRect.width;
+      PRBool heightChanged = aDesiredSize.height != mRect.height;
+      nsRect absPosBounds;
+      mAbsoluteContainer.Reflow(this, aPresContext, aReflowState, aStatus,
+                                aDesiredSize.width, aDesiredSize.height,
+                                PR_TRUE, widthChanged, heightChanged,
+                                &absPosBounds);
+      aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, absPosBounds);
+    }
   }
 
+  if (prevCanvasFrame) {
+    ReflowOverflowContainerChildren(aPresContext, aReflowState,
+                                    aDesiredSize.mOverflowArea, 0,
+                                    aStatus);
+  }
+
+  FinishAndStoreOverflow(&aDesiredSize);
+
   NS_FRAME_TRACE_REFLOW_OUT("CanvasFrame::Reflow", aStatus);
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
   return NS_OK;
 }
 
 PRIntn
 CanvasFrame::GetSkipSides() const
 {
--- a/layout/generic/nsHTMLParts.h
+++ b/layout/generic/nsHTMLParts.h
@@ -108,41 +108,34 @@ nsIFrame*
 NS_NewAreaFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, PRUint32 aFlags);
 
 // These AreaFrame's shrink wrap around their contents
 inline nsIFrame*
 NS_NewTableCellInnerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) {
   return NS_NewBlockFrame(aPresShell, aContext);
 }
 
-// This type of AreaFrame is the document root, a margin root, and the
-// initial containing block for absolutely positioned elements
+// This type of BlockFrame is a margin root, but does not shrink wrap
 inline nsIFrame*
-NS_NewDocumentElementFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) {
-  return NS_NewAreaFrame(aPresShell, aContext, NS_BLOCK_SPACE_MGR|NS_BLOCK_MARGIN_ROOT);
+NS_NewAbsoluteItemWrapperFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) {
+  return NS_NewBlockFrame(aPresShell, aContext, NS_BLOCK_SPACE_MGR|NS_BLOCK_MARGIN_ROOT);
 }
 
-// This type of AreaFrame is a margin root, but does not shrink wrap
-inline nsIFrame*
-NS_NewAbsoluteItemWrapperFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) {
-  return NS_NewAreaFrame(aPresShell, aContext, NS_BLOCK_SPACE_MGR|NS_BLOCK_MARGIN_ROOT);
-}
-
-// This type of AreaFrame shrink wraps
+// This type of BlockFrame shrink wraps
 inline nsIFrame*
 NS_NewFloatingItemWrapperFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) {
-  return NS_NewAreaFrame(aPresShell, aContext,
+  return NS_NewBlockFrame(aPresShell, aContext,
     NS_BLOCK_SPACE_MGR|NS_BLOCK_MARGIN_ROOT);
 }
 
-// This type of AreaFrame doesn't use its own space manager and
+// This type of BlockFrame doesn't use its own space manager and
 // doesn't shrink wrap.
 inline nsIFrame*
 NS_NewRelativeItemWrapperFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, PRUint32 aFlags) {
-  return NS_NewAreaFrame(aPresShell, aContext, aFlags);
+  return NS_NewBlockFrame(aPresShell, aContext, aFlags);
 }
 
 nsIFrame*
 NS_NewBRFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
 nsIFrame*
 NS_NewCommentFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
--- a/layout/generic/nsHTMLReflowState.cpp
+++ b/layout/generic/nsHTMLReflowState.cpp
@@ -1526,35 +1526,17 @@ nsHTMLReflowState::ComputeContainingBloc
       aContainingBlockHeight = aContainingBlockRS->frame->GetRect().height -
         computedBorder.TopBottom();
       NS_ASSERTION(aContainingBlockHeight >= 0,
                    "Negative containing block height!");
     } else {
       // If the ancestor is block-level, the containing block is formed by the
       // padding edge of the ancestor
       aContainingBlockWidth += aContainingBlockRS->mComputedPadding.LeftRight();
-
-      // If the containing block is the initial containing block and it has a
-      // height that depends on its content, then use the viewport height instead.
-      // This gives us a reasonable value against which to compute percentage
-      // based heights and to do bottom relative positioning
-      if ((NS_AUTOHEIGHT == aContainingBlockHeight) &&
-          nsLayoutUtils::IsInitialContainingBlock(aContainingBlockRS->frame)) {
-
-        // Use the viewport height as the containing block height
-        const nsHTMLReflowState* rs = aContainingBlockRS->parentReflowState;
-        while (rs) {
-          aContainingBlockHeight = rs->mComputedHeight;
-          rs = rs->parentReflowState;
-        }
-
-      } else {
-        aContainingBlockHeight +=
-          aContainingBlockRS->mComputedPadding.TopBottom();
-      }
+      aContainingBlockHeight += aContainingBlockRS->mComputedPadding.TopBottom();
     }
   } else {
     // an element in quirks mode gets a containing block based on looking for a
     // parent with a non-auto height if the element has a percent height
     if (NS_AUTOHEIGHT == aContainingBlockHeight) {
       if (eCompatibility_NavQuirks == aPresContext->CompatibilityMode() &&
           mStylePosition->mHeight.GetUnit() == eStyleUnit_Percent) {
         aContainingBlockHeight = CalcQuirkContainingBlockHeight(aContainingBlockRS);
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -1068,21 +1068,18 @@ nsPositionedInlineFrame::GetAdditionalCh
     return nsGkAtoms::absoluteList;
   }
   return nsnull;
 }
 
 nsIFrame*
 nsPositionedInlineFrame::GetFirstChild(nsIAtom* aListName) const
 {
-  if (nsGkAtoms::absoluteList == aListName) {
-    nsIFrame* result = nsnull;
-    mAbsoluteContainer.FirstChild(this, aListName, &result);
-    return result;
-  }
+  if (nsGkAtoms::absoluteList == aListName)
+    return mAbsoluteContainer.GetFirstChild();
 
   return nsInlineFrame::GetFirstChild(aListName);
 }
 
 nsIAtom*
 nsPositionedInlineFrame::GetType() const
 {
   return nsGkAtoms::positionedInlineFrame;
--- a/layout/generic/nsPageContentFrame.cpp
+++ b/layout/generic/nsPageContentFrame.cpp
@@ -64,137 +64,48 @@ nsPageContentFrame::ComputeSize(nsIRende
 {
   NS_ASSERTION(mPD, "Pages are supposed to have page data");
   nscoord height = (!mPD || mPD->mReflowSize.height == NS_UNCONSTRAINEDSIZE)
                    ? NS_UNCONSTRAINEDSIZE
                    : (mPD->mReflowSize.height - mPD->mReflowMargin.TopBottom());
   return nsSize(aAvailableWidth, height);
 }
 
-/**
- * Returns true if aFrame is a placeholder for one of our fixed frames.
- */
-inline PRBool
-nsPageContentFrame::IsFixedPlaceholder(nsIFrame* aFrame)
-{
-  if (!aFrame || nsGkAtoms::placeholderFrame != aFrame->GetType())
-    return PR_FALSE;
-
-  return static_cast<nsPlaceholderFrame*>(aFrame)->GetOutOfFlowFrame()
-           ->GetParent() == this;
-}
-
-/**
- * Steals replicated fixed placeholder frames from aDocRoot so they don't
- * get in the way of reflow.
- */
-inline nsFrameList
-nsPageContentFrame::StealFixedPlaceholders(nsIFrame* aDocRoot)
-{
-  nsPresContext* presContext = PresContext();
-  nsFrameList list;
-  if (GetPrevInFlow()) {
-    for (nsIFrame* f = aDocRoot->GetFirstChild(nsnull);
-        IsFixedPlaceholder(f); f = aDocRoot->GetFirstChild(nsnull)) {
-      nsresult rv = static_cast<nsContainerFrame*>(aDocRoot)
-                      ->StealFrame(presContext, f);
-      NS_ENSURE_SUCCESS(rv, list);
-      list.AppendFrame(nsnull, f);
-    }
-  }
-  return list;
-}
-
-/**
- * Restores stolen replicated fixed placeholder frames to aDocRoot.
- */
-static inline nsresult
-ReplaceFixedPlaceholders(nsIFrame*    aDocRoot,
-                         nsFrameList& aPlaceholderList)
-{
-  nsresult rv = NS_OK;
-  if (aPlaceholderList.NotEmpty()) {
-    rv = static_cast<nsContainerFrame*>(aDocRoot)
-           ->AddFrames(aPlaceholderList.FirstChild(), nsnull);
-  }
-  return rv;
-}
-
 NS_IMETHODIMP
 nsPageContentFrame::Reflow(nsPresContext*           aPresContext,
                            nsHTMLReflowMetrics&     aDesiredSize,
                            const nsHTMLReflowState& aReflowState,
                            nsReflowStatus&          aStatus)
 {
   DO_GLOBAL_REFLOW_COUNT("nsPageContentFrame");
   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
   aStatus = NS_FRAME_COMPLETE;  // initialize out parameter
   nsresult rv = NS_OK;
 
-  // A PageContentFrame must always have one child: the doc root element's frame.
-  // We only need to get overflow frames if we don't already have that child;
-  // Also we need to avoid repeating the call to ReplicateFixedFrames.
-  nsPageContentFrame* prevPageContentFrame = static_cast<nsPageContentFrame*>
-                                               (GetPrevInFlow());
-  if (mFrames.IsEmpty() && prevPageContentFrame) {
-    // Pull the doc root frame's continuation and copy fixed frames.
-    nsIFrame* overflow = prevPageContentFrame->GetOverflowFrames(aPresContext, PR_TRUE);
-    NS_ASSERTION(overflow && !overflow->GetNextSibling(),
-                 "must have doc root as pageContentFrame's only child");
-    nsHTMLContainerFrame::ReparentFrameView(aPresContext, overflow, prevPageContentFrame, this);
-    // Prepend overflow to the page content frame. There may already be
-    // children placeholders which don't get reflowed but must not be
-    // lost until the page content frame is destroyed.
-    mFrames.InsertFrames(this, nsnull, overflow);
+  if (GetPrevInFlow() && (GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
     nsresult rv = aPresContext->PresShell()->FrameConstructor()
                     ->ReplicateFixedFrames(this);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
+  // A PageContentFrame must always have one child: the canvas frame.
   // Resize our frame allowing it only to be as big as we are
   // XXX Pay attention to the page's border and padding...
   if (mFrames.NotEmpty()) {
     nsIFrame* frame = mFrames.FirstChild();
     nsSize  maxSize(aReflowState.availableWidth, aReflowState.availableHeight);
     nsHTMLReflowState kidReflowState(aPresContext, aReflowState, frame, maxSize);
+    kidReflowState.SetComputedHeight(aReflowState.availableHeight);
 
     mPD->mPageContentSize  = aReflowState.availableWidth;
 
-    // Get replicated fixed frames' placeholders out of the way
-    nsFrameList stolenPlaceholders = StealFixedPlaceholders(frame);
-
     // Reflow the page content area
     rv = ReflowChild(frame, aPresContext, aDesiredSize, kidReflowState, 0, 0, 0, aStatus);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    // Put removed fixed placeholders back
-    rv = ReplaceFixedPlaceholders(frame, stolenPlaceholders);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    if (!NS_FRAME_IS_FULLY_COMPLETE(aStatus)) {
-      nsIFrame* nextFrame = frame->GetNextInFlow();
-      NS_ASSERTION(nextFrame || aStatus & NS_FRAME_REFLOW_NEXTINFLOW,
-        "If it's incomplete and has no nif yet, it must flag a nif reflow.");
-      if (!nextFrame) {
-        nsresult rv = nsHTMLContainerFrame::CreateNextInFlow(aPresContext,
-                                              this, frame, nextFrame);
-        NS_ENSURE_SUCCESS(rv, rv);
-        frame->SetNextSibling(nextFrame->GetNextSibling());
-        nextFrame->SetNextSibling(nsnull);
-        SetOverflowFrames(aPresContext, nextFrame);
-        // Root overflow containers will be normal children of
-        // the pageContentFrame, but that's ok because there
-        // aren't any other frames we need to isolate them from
-        // during reflow.
-      }
-      if (NS_FRAME_OVERFLOW_IS_INCOMPLETE(aStatus)) {
-        nextFrame->AddStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER);
-      }
-    }
-
     // The document element's background should cover the entire canvas, so
     // take into account the combined area and any space taken up by
     // absolutely positioned elements
     nsMargin padding(0,0,0,0);
 
     // XXXbz this screws up percentage padding (sets padding to zero
     // in the percentage padding case)
     kidReflowState.mStylePadding->GetPadding(padding);
--- a/layout/generic/nsPageContentFrame.h
+++ b/layout/generic/nsPageContentFrame.h
@@ -78,16 +78,12 @@ public:
   // Debugging
   NS_IMETHOD  GetFrameName(nsAString& aResult) const;
 #endif
 
 protected:
   nsPageContentFrame(nsStyleContext* aContext) : ViewportFrame(aContext) {}
 
   nsSharedPageData*         mPD;
-
-private:
-  PRBool IsFixedPlaceholder(nsIFrame* aFrame);
-  nsFrameList StealFixedPlaceholders(nsIFrame* aDocRoot);
 };
 
 #endif /* nsPageContentFrame_h___ */
 
--- a/layout/generic/nsViewportFrame.cpp
+++ b/layout/generic/nsViewportFrame.cpp
@@ -174,21 +174,18 @@ ViewportFrame::GetAdditionalChildListNam
   }
 
   return nsnull;
 }
 
 nsIFrame*
 ViewportFrame::GetFirstChild(nsIAtom* aListName) const
 {
-  if (nsGkAtoms::fixedList == aListName) {
-    nsIFrame* result = nsnull;
-    mFixedContainer.FirstChild(this, aListName, &result);
-    return result;
-  }
+  if (nsGkAtoms::fixedList == aListName)
+    return mFixedContainer.GetFirstChild();
 
   return nsContainerFrame::GetFirstChild(aListName);
 }
 
 /* virtual */ nscoord
 ViewportFrame::GetMinWidth(nsIRenderingContext *aRenderingContext)
 {
   nscoord result;
@@ -304,18 +301,17 @@ ViewportFrame::Reflow(nsPresContext*    
                           : 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
-  nsIFrame* f;
-  mFixedContainer.FirstChild(this, nsGkAtoms::fixedList, &f);
+  nsIFrame* f = mFixedContainer.GetFirstChild();
   NS_ASSERTION(!f || (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(),
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/200774-1.html
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" 
+   "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" class="reftest-print">
+
+<head>
+<title>Fixed DIV, Multipe Page Testcase</title>
+<style type="text/css">
+div.header { position: fixed;
+	width: 100%;
+	height: 1.5em;
+	top: 0;
+	font-style: italic;
+	background-color: white;
+	color: black }
+</style>
+</head>
+
+<body>
+
+<div class="header">I stay on the top of the web page and each printed page.</div>
+
+<h1>Fixed DIV, multiple page testcase</h1>
+
+<hr />
+
+<p>Maybe related to bug 163800?</p>
+
+<p>Similar to 193686 and 197808, but there are <i>no</i> forms involved in this crash.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+<p>Repeating text, to get  us onto the next page.</p>
+
+</body>
+</html>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-1-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<style>
+body { margin:0; }
+.pos { position:absolute; width:100px; height:100px; }
+</style>
+</head>
+<body>
+<div style="height:10000px; margin:0; margin:10px; border:20px solid black; padding:30px;"></div>
+<script>
+window.scrollTo(0,50);
+</script>
+<div class="pos" style="top:0; left:60px; background:yellow;"></div>
+<div class="pos" style="right:0; top:60px; background:orange;"></div>
+<div class="pos" style="bottom:0; left:60px; background:brown;"></div>
+<div class="pos" style="left:0; top:60px; background:pink;"></div>
+</div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-1.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<style>
+html { margin:10px; border:20px solid black; padding:30px; }
+body { height:10000px; margin:0; }
+div { position:absolute; width:100px; height:100px; }
+</style>
+</head>
+<body>
+<script>
+window.scrollTo(0,50);
+</script>
+<div style="top:0; background:yellow;"></div>
+<div style="right:0; background:orange;"></div>
+<div style="bottom:0; background:brown;"></div>
+<div style="left:0; background:pink;"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-2-ref.html
@@ -0,0 +1,7 @@
+<!DOCTYPE HTML>
+<html>
+<body style="-moz-column-count:2; margin:0;">
+Hello<br>
+Kitty
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-2.html
@@ -0,0 +1,7 @@
+<!DOCTYPE HTML>
+<html style="-moz-column-count:2;">
+<body style="margin:0;">
+Hello<br>
+Kitty
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-3-ref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML>
+<html class="reftest-print">
+<head>
+<style>
+body { margin:0; }
+.pos { position:absolute; width:100px; height:100px; }
+</style>
+</head>
+<body>
+<div class="pos" style="top:0; left:60px; border:10px solid yellow;"></div>
+<div class="pos" style="right:0; top:60px; border:10px solid orange;"></div>
+<div class="pos" style="bottom:0; left:60px; border:10px solid brown;"></div>
+<div class="pos" style="left:0; top:60px; border:10px solid pink;"></div>
+<div style="margin:10px; border:20px solid black; padding:30px;"></div>
+</div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-3.html
@@ -0,0 +1,16 @@
+<!DOCTYPE HTML>
+<html class="reftest-print">
+<head>
+<style>
+html { margin:10px; border:20px solid black; padding:30px; }
+body { margin:0; }
+div { position:absolute; width:100px; height:100px; }
+</style>
+</head>
+<body>
+<div style="top:0; border:10px solid yellow;"></div>
+<div style="right:0; border:10px solid orange;"></div>
+<div style="bottom:0; border:10px solid brown;"></div>
+<div style="left:0; border:10px solid pink;"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-4-ref.html
@@ -0,0 +1,7 @@
+<!DOCTYPE HTML>
+<html style="background:yellow;">
+<body>
+<div style="position:absolute; top:100px; left:100px; width:100px; height:100px;
+            border:10px solid black;"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-4a.html
@@ -0,0 +1,6 @@
+<!DOCTYPE HTML>
+<html style="position:absolute; left:100px; top:100px; width:100px; height:100px;
+             background:yellow; border:10px solid black;">
+<body>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-4b.html
@@ -0,0 +1,6 @@
+<!DOCTYPE HTML>
+<html style="position:fixed; left:100px; top:100px; width:100px; height:100px;
+             background:yellow; border:10px solid black;">
+<body>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-4c.html
@@ -0,0 +1,6 @@
+<!DOCTYPE HTML>
+<html style="position:absolute; left:100px; top:100px; width:100px; height:100px;
+             background:yellow; border:10px solid black; display:table;">
+<body>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-4d.html
@@ -0,0 +1,6 @@
+<!DOCTYPE HTML>
+<html style="position:fixed; left:100px; top:100px; width:100px; height:100px;
+             background:yellow; border:10px solid black; display:table">
+<body>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-4e.html
@@ -0,0 +1,6 @@
+<!DOCTYPE HTML>
+<html style="display:table">
+<body style="position:absolute; left:100px; top:100px; width:100px; height:100px; border:10px solid black;
+             background:yellow; margin:0">
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-4f.html
@@ -0,0 +1,6 @@
+<!DOCTYPE HTML>
+<html style="display:table">
+<body style="position:fixed; left:100px; top:100px; width:100px; height:100px; border:10px solid black;
+             background:yellow; margin:0">
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-5-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE HTML>
+<html style="background:yellow;">
+<body style="margin:0">
+<div style="border:10px solid black; width:100px; height:100px;"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-5a.html
@@ -0,0 +1,6 @@
+<!DOCTYPE HTML>
+<html style="position:absolute; width:100px; height:100px;
+             background:yellow; border:10px solid black;">
+<body>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-5b.html
@@ -0,0 +1,6 @@
+<!DOCTYPE HTML>
+<html style="position:absolute; width:100px; height:100px; display:table;
+             background:yellow; border:10px solid black;">
+<body>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-5c.html
@@ -0,0 +1,6 @@
+<!DOCTYPE HTML>
+<html style="position:fixed; width:100px; height:100px;
+             background:yellow; border:10px solid black;">
+<body>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-5d.html
@@ -0,0 +1,6 @@
+<!DOCTYPE HTML>
+<html style="position:fixed; width:100px; height:100px; display:table;
+             background:yellow; border:10px solid black;">
+<body>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-6-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML>
+<html class="reftest-print">
+<head>
+<style>
+div { margin:10px; border:20px solid black; padding:30px; height:4in; position:absolute; }
+body { margin:0; }
+</style>
+</head>
+<body>
+<div></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-6.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML>
+<html class="reftest-print">
+<head>
+<style>
+html { margin:10px; border:20px solid black; padding:30px; height:4in; position:absolute; }
+body { margin:0; }
+</style>
+</head>
+<body>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-7-ref.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML>
+<html>
+<body style="margin:0;">
+<div style="position:relative; top:100px; left:100px; height:100px; border:10px solid black;">
+  <div style="position:absolute; bottom:0; height:30px; border:10px solid orange;">
+  </div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-7.html
@@ -0,0 +1,5 @@
+<!DOCTYPE HTML>
+<html style="position:relative; top:100px; left:100px; height:100px; border:10px solid black;">
+<body style="position:absolute; margin:0; bottom:0; height:30px; border:10px solid orange;">
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-8-ref.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+  <rect fill="lime" x="100" y="100" width="100" height="100"/>
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-8.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" style="position:absolute; left:100px; top:100px; overflow:hidden;">
+  <rect fill="lime" width="100" height="100"/>
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-9-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE HTML>
+<html>
+<body style="margin:0">
+<div style="position:fixed; width:50%; height:50%; left:50px; top:50px; border:10px solid black;"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-9a.html
@@ -0,0 +1,3 @@
+<!DOCTYPE HTML>
+<html style="width:50%; height:50%; margin:50px; border:10px solid black;">
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-9b.html
@@ -0,0 +1,3 @@
+<!DOCTYPE HTML>
+<html style="position:absolute; left:50px; top:50px; width:50%; height:50%; border:10px solid black;">
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-9c.html
@@ -0,0 +1,2 @@
+<html style="width:50%; height:50%; margin:50px; border:10px solid black;">
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-9d.html
@@ -0,0 +1,2 @@
+<html style="position:absolute; left:50px; top:50px; width:50%; height:50%; border:10px solid black;">
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/243519-9e.html
@@ -0,0 +1,5 @@
+<!DOCTYPE HTML>
+<html>
+<body style="position:absolute; width:50%; height:50%; top:50px; left:50px; margin:0; border:10px solid black;">
+</body>
+</html>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -120,16 +120,17 @@ fails == 25888-3r.html 25888-3r-ref.html
 == 163504-1b.html 163504-1-ref.html
 == 163504-2a.html 163504-2-ref.html
 == 163504-2b.html 163504-2-ref.html
 == 169749-1.html 169749-1-ref.html
 == 172073-1.html 172073-1-ref.html
 == 180085-1.html 180085-1-ref.html
 == 180085-2.html 180085-2-ref.html
 == 185388-1.html 185388-1-ref.html
+!= 200774-1.html about:blank # really a crashtest
 == 201215-1.html 201215-1-ref.html
 == 201293-1a.html 201293-1-ref.html
 == 201293-1b.html 201293-1-ref.html
 == 201293-1c.html 201293-1-ref.html
 == 201293-1d.html 201293-1-ref.html
 == 206516-1.html 206516-1-ref.html
 == 210094-1a.html 210094-1-ref.html
 == 210094-1b.html 210094-1-ref.html
@@ -161,16 +162,37 @@ fails == 25888-3r.html 25888-3r-ref.html
 == 234686-19.html 234686-ref.html
 == 234964-1.html 234964-1-ref.html
 == 234964-2.html 234964-2-ref.html
 == 235593-1.html 235593-1-ref.html
 == 236539-1.html 236539-1-ref.html
 == 240470-1.html 240470-1-ref.html
 == 243266-1.html 243266-1-ref.html
 == 243302-1.html 243302-1-ref.html
+== 243519-1.html 243519-1-ref.html
+== 243519-2.html 243519-2-ref.html
+== 243519-3.html 243519-3-ref.html
+== 243519-4a.html 243519-4-ref.html
+== 243519-4b.html 243519-4-ref.html
+== 243519-4c.html 243519-4-ref.html
+== 243519-4d.html 243519-4-ref.html
+== 243519-4e.html 243519-4-ref.html
+== 243519-4f.html 243519-4-ref.html
+== 243519-5a.html 243519-5-ref.html
+== 243519-5b.html 243519-5-ref.html
+== 243519-5c.html 243519-5-ref.html
+== 243519-5d.html 243519-5-ref.html
+== 243519-6.html 243519-6-ref.html
+== 243519-7.html 243519-7-ref.html
+== 243519-8.svg 243519-8-ref.svg
+== 243519-9a.html 243519-9-ref.html
+== 243519-9b.html 243519-9-ref.html
+== 243519-9c.html 243519-9-ref.html
+== 243519-9d.html 243519-9-ref.html
+== 243519-9e.html 243519-9-ref.html
 == 244135-1.html 244135-1-ref.html
 == 244135-2.html 244135-2-ref.html
 == 244932-1.html 244932-1-ref.html
 == 249982-1.html 249982-1-ref.html
 == 253701-1.html 253701-1-ref.html
 == 255820-1.html 255820-1-ref.html
 == 262151-1.html 262151-1-ref.html
 #== 263683-1.html 263683-1-ref.html