Bug 1110277 patch 7 - Call CreateNeededFrames from ~ReframingStyleContexts. r=bzbarsky
authorL. David Baron <dbaron@dbaron.org>
Tue, 13 Jan 2015 21:03:13 -0800
changeset 238144 2a1f0e8d1fc923bc51ac43e027584bc3a19a8259
parent 238143 30666c55966ead13b7093be8be56820b3f9cfe76
child 238145 4182615c7586af74dd20cf024282f6a4a17e8994
push id4610
push userjlund@mozilla.com
push dateMon, 30 Mar 2015 18:32:55 +0000
treeherdermozilla-esr52@4df54044d9ef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs1110277
milestone38.0a1
Bug 1110277 patch 7 - Call CreateNeededFrames from ~ReframingStyleContexts. r=bzbarsky I don't have any tests that exercise this code, and I can't even find a codepath that demonstrates that it's needed, since the lazy reconstruction that happens during style-triggered frame reconstruction all appears to go through PostRestyleEvent rather than MaybeConstructLazily. But I think we should either do this or add an assertion that it's not needed, and given that it's one line, it seems like we may as well just do it. (Note also that we're currently calling CreateNeededFrames at the start of style reresolution, in RestyleManager::ProcessPendingRestyles; this adds a call at the end.)
layout/base/RestyleManager.cpp
layout/base/RestyleManager.h
--- a/layout/base/RestyleManager.cpp
+++ b/layout/base/RestyleManager.cpp
@@ -990,16 +990,26 @@ RestyleManager::ReframingStyleContexts::
   : mRestyleManager(aRestyleManager)
   , mRestorePointer(mRestyleManager->mReframingStyleContexts)
 {
   MOZ_ASSERT(!mRestyleManager->mReframingStyleContexts,
              "shouldn't construct recursively");
   mRestyleManager->mReframingStyleContexts = this;
 }
 
+RestyleManager::ReframingStyleContexts::~ReframingStyleContexts()
+{
+  // Before we go away, we need to flush out any frame construction that
+  // was enqueued, so that we start transitions.
+  // Note that this is a little bit evil in that we're calling into code
+  // that calls our member functions from our destructor, but it's at
+  // the beginning of our destructor, so it shouldn't be too bad.
+  mRestyleManager->mPresContext->FrameConstructor()->CreateNeededFrames();
+}
+
 static inline dom::Element*
 ElementForStyleContext(nsIContent* aParentContent,
                        nsIFrame* aFrame,
                        nsCSSPseudoElements::Type aPseudoType);
 
 // Forwarded nsIDocumentObserver method, to handle restyling (and
 // passing the notification to the frame).
 nsresult
--- a/layout/base/RestyleManager.h
+++ b/layout/base/RestyleManager.h
@@ -176,25 +176,26 @@ public:
    * In all cases, the content node in the hash table is the real
    * content node, not the anonymous content node we create for ::before
    * or ::after.  The content node passed to the Get and Put methods is,
    * however, the content node to be associate with the frame's style
    * context.
    */
   typedef nsRefPtrHashtable<nsRefPtrHashKey<nsIContent>, nsStyleContext>
             ReframingStyleContextTable;
-  class MOZ_STACK_CLASS ReframingStyleContexts {
+  class MOZ_STACK_CLASS ReframingStyleContexts MOZ_FINAL {
   public:
     /**
      * Construct a ReframingStyleContexts object.  The caller must
      * ensure that aRestyleManager lives at least as long as the
      * object.  (This is generally easy since the caller is typically a
      * method of RestyleManager.)
      */
     explicit ReframingStyleContexts(RestyleManager* aRestyleManager);
+    ~ReframingStyleContexts();
 
     void Put(nsIContent* aContent, nsStyleContext* aStyleContext) {
       MOZ_ASSERT(aContent);
       nsCSSPseudoElements::Type pseudoType = aStyleContext->GetPseudoType();
       if (pseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement) {
         mElementContexts.Put(aContent, aStyleContext);
       } else if (pseudoType == nsCSSPseudoElements::ePseudo_before) {
         MOZ_ASSERT(aContent->Tag() == nsGkAtoms::mozgeneratedcontentbefore);