Bug 812893 - When inserting a frame into the [Excess]OverflowContinuations list, also move its continuations there if they are in the same parent. r=roc a=bbajaj
authorMats Palmgren <matspal@gmail.com>
Tue, 29 Jan 2013 01:11:50 +0100
changeset 127345 c99a75cf84ffc730880b61d90318cbef08cb144d
parent 127344 c82e639f1907ee9b3dfa3cfdcf319e985cbcd905
child 127346 019452f32c213c8abd8630aa4ad2c09f5026b6a1
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, bbajaj
bugs812893
milestone20.0a2
Bug 812893 - When inserting a frame into the [Excess]OverflowContinuations list, also move its continuations there if they are in the same parent. r=roc a=bbajaj
layout/generic/nsContainerFrame.cpp
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -1638,45 +1638,45 @@ nsOverflowContinuationTracker::Insert(ns
 {
   NS_PRECONDITION(aOverflowCont, "null frame pointer");
   NS_PRECONDITION(!mSkipOverflowContainerChildren || mWalkOOFFrames ==
                   !!(aOverflowCont->GetStateBits() & NS_FRAME_OUT_OF_FLOW),
                   "shouldn't insert frame that doesn't match walker type");
   NS_PRECONDITION(aOverflowCont->GetPrevInFlow(),
                   "overflow containers must have a prev-in-flow");
   nsresult rv = NS_OK;
-  bool convertedToOverflowContainer = false;
+  bool reparented = false;
   nsPresContext* presContext = aOverflowCont->PresContext();
-  if (!mSentry || aOverflowCont != mSentry->GetNextInFlow()) {
-    // Not in our list, so we need to add it
+  const bool addToList = !mSentry || aOverflowCont != mSentry->GetNextInFlow();
+  if (addToList) {
     if (aOverflowCont->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) {
       // aOverflowCont is in some other overflow container list,
       // steal it first
       NS_ASSERTION(!(mOverflowContList &&
                      mOverflowContList->ContainsFrame(aOverflowCont)),
                    "overflow containers out of order");
       rv = static_cast<nsContainerFrame*>(aOverflowCont->GetParent())
              ->StealFrame(presContext, aOverflowCont);
       NS_ENSURE_SUCCESS(rv, rv);
     }
     else {
       aOverflowCont->AddStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER);
-      convertedToOverflowContainer = true;
     }
     if (!mOverflowContList) {
       mOverflowContList = new nsFrameList();
       rv = mParent->SetPropTableFrames(presContext, mOverflowContList,
         nsContainerFrame::ExcessOverflowContainersProperty());
       NS_ENSURE_SUCCESS(rv, rv);
       SetUpListWalker();
     }
     if (aOverflowCont->GetParent() != mParent) {
       nsContainerFrame::ReparentFrameView(presContext, aOverflowCont,
                                           aOverflowCont->GetParent(),
                                           mParent);
+      reparented = true;
     }
     mOverflowContList->InsertFrame(mParent, mPrevOverflowCont, aOverflowCont);
     aReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW;
   }
 
   // If we need to reflow it, mark it dirty
   if (aReflowStatus & NS_FRAME_REFLOW_NEXTINFLOW)
     aOverflowCont->AddStateBits(NS_FRAME_IS_DIRTY);
@@ -1684,26 +1684,30 @@ nsOverflowContinuationTracker::Insert(ns
   // It's in our list, just step forward
   StepForward();
   NS_ASSERTION(mPrevOverflowCont == aOverflowCont ||
                (mSkipOverflowContainerChildren &&
                 (mPrevOverflowCont->GetStateBits() & NS_FRAME_OUT_OF_FLOW) !=
                 (aOverflowCont->GetStateBits() & NS_FRAME_OUT_OF_FLOW)),
               "OverflowContTracker in unexpected state");
 
-  if (convertedToOverflowContainer) {
+  if (addToList) {
     // Convert all non-overflow-container continuations of aOverflowCont
     // into overflow containers and move them to our overflow
     // tracker. This preserves the invariant that the next-continuations
     // of an overflow container are also overflow containers.
     nsIFrame* f = aOverflowCont->GetNextContinuation();
-    if (f && !(f->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER)) {
-      nsContainerFrame* parent = static_cast<nsContainerFrame*>(f->GetParent());
-      rv = parent->StealFrame(presContext, f);
-      NS_ENSURE_SUCCESS(rv, rv);
+    if (f && (!(f->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) ||
+              (!reparented && f->GetParent() == mParent) ||
+              (reparented && f->GetParent() != mParent))) {
+      if (!(f->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER)) {
+        nsContainerFrame* parent = static_cast<nsContainerFrame*>(f->GetParent());
+        rv = parent->StealFrame(presContext, f);
+        NS_ENSURE_SUCCESS(rv, rv);
+      }
       Insert(f, aReflowStatus);
     }
   }
   return rv;
 }
 
 void
 nsOverflowContinuationTracker::Finish(nsIFrame* aChild)