Bug 1001994. r=roc
authorMats Palmgren <mats@mozilla.com>
Mon, 07 Jul 2014 16:08:42 +0000
changeset 192688 a5d6027756ae1f19046bc52ba92faec97e582e65
parent 192687 fdc900ad296f1cdf849d51b633f135ace7ecb288
child 192689 c6adaead7adfcba6912e2c153fb734f8cabdf5f2
push id27093
push userkwierso@gmail.com
push dateMon, 07 Jul 2014 23:01:28 +0000
treeherdermozilla-central@7f9db2379b3f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs1001994
milestone33.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1001994. r=roc
layout/generic/nsInlineFrame.cpp
layout/generic/nsInlineFrame.h
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -172,16 +172,30 @@ nsInlineFrame::PeekOffsetCharacter(bool 
     // We're before the frame and moving forward, or after it and moving backwards:
     // skip to the other side, but keep going.
     *aOffset = 1 - startOffset;
   }
   return CONTINUE;
 }
 
 void
+nsInlineFrame::DestroyFrom(nsIFrame* aDestructRoot)
+{
+  nsFrameList* overflowFrames = GetOverflowFrames();
+  if (overflowFrames) {
+    // Fixup the parent pointers for any child frames on the OverflowList.
+    // nsIFrame::DestroyFrom depends on that to find the sticky scroll
+    // container (an ancestor).
+    nsIFrame* lineContainer = nsLayoutUtils::FindNearestBlockAncestor(this);
+    DrainSelfOverflowListInternal(eForDestroy, lineContainer);
+  }
+  nsContainerFrame::DestroyFrom(aDestructRoot);
+}
+
+void
 nsInlineFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists)
 {
   BuildDisplayListForInline(aBuilder, aDirtyRect, aLists);
 
   // The sole purpose of this is to trigger display of the selection
   // window for Named Anchors, which don't have any children and
@@ -417,21 +431,22 @@ nsInlineFrame::DrainSelfOverflowListInte
     // The frames on our own overflowlist may have been pushed by a
     // previous lazilySetParentPointer Reflow so we need to ensure the
     // correct parent pointer.  This is sometimes skipped by Reflow.
     if (!(aFlags & eDontReparentFrames)) {
       nsIFrame* firstChild = overflowFrames->FirstChild();
       if (aLineContainer && aLineContainer->GetPrevContinuation()) {
         ReparentFloatsForInlineChild(aLineContainer, firstChild, true);
       }
-      const bool inFirstLine = (aFlags & eInFirstLine);
+      const bool doReparentSC =
+        (aFlags & eInFirstLine) && !(aFlags & eForDestroy);
       RestyleManager* restyleManager = PresContext()->RestyleManager();
       for (nsIFrame* f = firstChild; f; f = f->GetNextSibling()) {
         f->SetParent(this);
-        if (inFirstLine) {
+        if (doReparentSC) {
           restyleManager->ReparentStyleContext(f);
           nsLayoutUtils::MarkDescendantsDirty(f);
         }
       }
     }
     bool result = !overflowFrames->IsEmpty();
     mFrames.AppendFrames(nullptr, *overflowFrames);
     return result;
--- a/layout/generic/nsInlineFrame.h
+++ b/layout/generic/nsInlineFrame.h
@@ -58,16 +58,18 @@ public:
   virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE;
 
   virtual bool IsEmpty() MOZ_OVERRIDE;
   virtual bool IsSelfEmpty() MOZ_OVERRIDE;
 
   virtual FrameSearchResult PeekOffsetCharacter(bool aForward, int32_t* aOffset,
                                      bool aRespectClusters = true) MOZ_OVERRIDE;
   
+  virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
+
   // nsIHTMLReflow overrides
   virtual void AddInlineMinWidth(nsRenderingContext *aRenderingContext,
                                  InlineMinWidthData *aData) MOZ_OVERRIDE;
   virtual void AddInlinePrefWidth(nsRenderingContext *aRenderingContext,
                                   InlinePrefWidthData *aData) MOZ_OVERRIDE;
   virtual nsSize ComputeSize(nsRenderingContext *aRenderingContext,
                              nsSize aCBSize, nscoord aAvailableWidth,
                              nsSize aMargin, nsSize aBorder, nsSize aPadding,
@@ -160,16 +162,19 @@ protected:
                           InlineReflowState& aState);
 
 private:
   // Helper method for DrainSelfOverflowList() to deal with lazy parenting
   // (which we only do for nsInlineFrame, not nsFirstLineFrame).
   enum DrainFlags {
     eDontReparentFrames = 1, // skip reparenting the overflow list frames
     eInFirstLine = 2, // the request is for an inline descendant of a nsFirstLineFrame
+    eForDestroy = 4, // the request is from DestroyFrom; in this case we do the
+                     // minimal work required since the frame is about to be
+                     // destroyed (just fixup parent pointers)
   };
   /**
    * Move any frames on our overflow list to the end of our principal list.
    * @param aFlags one or more of the above DrainFlags
    * @param aLineContainer the nearest line container ancestor
    * @return true if there were any overflow frames
    */
   bool DrainSelfOverflowListInternal(DrainFlags aFlags,