Bug 577607 part 3. Use the main doc refresh driver for resource documents and the parent document's refresh driver for documents that are not roots of their type. r=roc, a=joe
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 11 Aug 2010 17:05:27 -0400
changeset 50366 4e326cd7bac60c799977bcc4bd374f1b04f842cd
parent 50365 7d133a2a7d203c6b8d3b4d37cbee0abce2970272
child 50367 bf2386d0cc1b9de8a779e94a938ebb11a896d909
push idunknown
push userunknown
push dateunknown
reviewersroc, joe
bugs577607
milestone2.0b4pre
Bug 577607 part 3. Use the main doc refresh driver for resource documents and the parent document's refresh driver for documents that are not roots of their type. r=roc, a=joe
layout/base/nsPresContext.cpp
layout/base/nsPresShell.cpp
layout/base/nsRefreshDriver.h
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -259,17 +259,17 @@ nsPresContext::~nsPresContext()
   SetShell(nsnull);
 
   if (mTransitionManager) {
     mTransitionManager->Disconnect();
   }
 
   // Disconnect the refresh driver *after* the transition manager, which
   // needs it.
-  if (mRefreshDriver) {
+  if (mRefreshDriver && mRefreshDriver->PresContext() == this) {
     mRefreshDriver->Disconnect();
   }
 
   if (mEventManager) {
     // unclear if these are needed, but can't hurt
     mEventManager->NotifyDestroyPresContext(this);
     mEventManager->SetPresContext(nsnull);
 
@@ -886,19 +886,47 @@ nsPresContext::Init(nsIDeviceContext* aD
     return NS_ERROR_OUT_OF_MEMORY;
 
   NS_ADDREF(mEventManager);
 
   mTransitionManager = new nsTransitionManager(this);
   if (!mTransitionManager)
     return NS_ERROR_OUT_OF_MEMORY;
 
-  mRefreshDriver = new nsRefreshDriver(this);
-  if (!mRefreshDriver)
-    return NS_ERROR_OUT_OF_MEMORY;
+  if (mDocument->GetDisplayDocument()) {
+    NS_ASSERTION(mDocument->GetDisplayDocument()->GetShell() &&
+                 mDocument->GetDisplayDocument()->GetShell()->GetPresContext(),
+                 "Why are we being initialized?");
+    mRefreshDriver = mDocument->GetDisplayDocument()->GetShell()->
+      GetPresContext()->RefreshDriver();
+  } else {
+    nsIDocument* parent = mDocument->GetParentDocument();
+    if (parent) {
+      NS_ASSERTION(parent->GetShell() && parent->GetShell()->GetPresContext(),
+                   "How did we get a presshell?");
+
+      // We don't have our container set yet at this point
+      nsCOMPtr<nsISupports> ourContainer = mDocument->GetContainer();
+
+      nsCOMPtr<nsIDocShellTreeItem> ourItem = do_QueryInterface(ourContainer);
+      if (ourItem) {
+        nsCOMPtr<nsIDocShellTreeItem> parentItem;
+        ourItem->GetSameTypeParent(getter_AddRefs(parentItem));
+        if (parentItem) {
+          mRefreshDriver = parent->GetShell()->GetPresContext()->RefreshDriver();
+        }
+      }
+    }
+
+    if (!mRefreshDriver) {
+      mRefreshDriver = new nsRefreshDriver(this);
+      if (!mRefreshDriver)
+        return NS_ERROR_OUT_OF_MEMORY;
+    }
+  }
 
   mLangService = do_GetService(NS_LANGUAGEATOMSERVICE_CONTRACTID);
 
   // Register callbacks so we're notified when the preferences change
   nsContentUtils::RegisterPrefCallback("font.",
                                        nsPresContext::PrefChangedCallback,
                                        this);
   nsContentUtils::RegisterPrefCallback("browser.display.",
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -7262,17 +7262,18 @@ PresShell::Freeze()
     mCaret->SetCaretVisible(PR_FALSE);
 
   mPaintingSuppressed = PR_TRUE;
 
   if (mDocument)
     mDocument->EnumerateSubDocuments(FreezeSubDocument, nsnull);
 
   nsPresContext* presContext = GetPresContext();
-  if (presContext) {
+  if (presContext &&
+      presContext->RefreshDriver()->PresContext() == presContext) {
     presContext->RefreshDriver()->Freeze();
   }
 }
 
 void
 PresShell::FireOrClearDelayedEvents(PRBool aFireEvents)
 {
   mNoDelayedMouseEvents = PR_FALSE;
@@ -7315,17 +7316,18 @@ ThawSubDocument(nsIDocument *aDocument, 
 
   return PR_TRUE;
 }
 
 void
 PresShell::Thaw()
 {
   nsPresContext* presContext = GetPresContext();
-  if (presContext) {
+  if (presContext &&
+      presContext->RefreshDriver()->PresContext() == presContext) {
     presContext->RefreshDriver()->Thaw();
   }
 
   mDocument->EnumerateFreezableElements(ThawElement, this);
 
   if (mDocument)
     mDocument->EnumerateSubDocuments(ThawSubDocument, nsnull);
 
--- a/layout/base/nsRefreshDriver.h
+++ b/layout/base/nsRefreshDriver.h
@@ -157,16 +157,21 @@ public:
   void Freeze();
 
   /**
    * Thaw the refresh driver.  If needed, it should start delivering
    * refreshes again.
    */
   void Thaw();
 
+  /**
+   * Return the prescontext we were initialized with
+   */
+  nsPresContext* PresContext() const { return mPresContext; }
+
 #ifdef DEBUG
   /**
    * Check whether the given observer is an observer for the given flush type
    */
   PRBool IsRefreshObserver(nsARefreshObserver *aObserver,
 			   mozFlushType aFlushType);
 #endif