From: Neil Deakin <neil@mozilla.com>
Date: Fri, 21 Jan 2011 14:48:59 -0500
Subject: Bug 553808, assertion setting template datasources, r=smaug, a=clegnitto

---
 content/xul/templates/src/nsXULTemplateBuilder.cpp |   19 ++++++++-----------
 content/xul/templates/src/nsXULTemplateBuilder.h   |   15 +++++++++++++++
 2 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/content/xul/templates/src/nsXULTemplateBuilder.cpp b/content/xul/templates/src/nsXULTemplateBuilder.cpp
index 08016d9..5ae3122 100644
--- a/content/xul/templates/src/nsXULTemplateBuilder.cpp
+++ b/content/xul/templates/src/nsXULTemplateBuilder.cpp
@@ -1115,14 +1115,9 @@ nsXULTemplateBuilder::AttributeChanged(nsIDocument* aDocument,
         // Check for a change to the 'datasources' attribute. If so, setup
         // mDB by parsing the new value and rebuild.
         else if (aAttribute == nsGkAtoms::datasources) {
-            Uninit(PR_FALSE);  // Reset results
-            
-            PRBool shouldDelay;
-            LoadDataSources(aDocument, &shouldDelay);
-            if (!shouldDelay)
-                nsContentUtils::AddScriptRunner(
-                    NS_NEW_RUNNABLE_METHOD(nsXULTemplateBuilder, this,
-                                           RunnableRebuild));
+            nsContentUtils::AddScriptRunner(
+                NS_NEW_RUNNABLE_METHOD(nsXULTemplateBuilder, this,
+                                       RunnableLoadAndRebuild));
         }
     }
 }
@@ -1139,8 +1134,9 @@ nsXULTemplateBuilder::ContentRemoved(nsIDocument* aDocument,
         if (mQueryProcessor)
             mQueryProcessor->Done();
 
-        // use false since content is going away anyway
-        Uninit(PR_FALSE);
+        // Pass false to Uninit since content is going away anyway
+        nsContentUtils::AddScriptRunner(
+            NS_NEW_RUNNABLE_METHOD(nsXULTemplateBuilder, this, UninitFalse));
 
         aDocument->RemoveObserver(this);
 
@@ -1177,7 +1173,8 @@ nsXULTemplateBuilder::NodeWillBeDestroyed(const nsINode* aNode)
     mCompDB = nsnull;
     mRoot = nsnull;
 
-    Uninit(PR_TRUE);
+    nsContentUtils::AddScriptRunner(
+        NS_NEW_RUNNABLE_METHOD(nsXULTemplateBuilder, this, UninitTrue));
 }
 
 
diff --git a/content/xul/templates/src/nsXULTemplateBuilder.h b/content/xul/templates/src/nsXULTemplateBuilder.h
index b938f4f..764cc86 100644
--- a/content/xul/templates/src/nsXULTemplateBuilder.h
+++ b/content/xul/templates/src/nsXULTemplateBuilder.h
@@ -46,6 +46,7 @@
 #include "nsStubDocumentObserver.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIContent.h"
+#include "nsIDocument.h"
 #include "nsIObserver.h"
 #include "nsIRDFCompositeDataSource.h"
 #include "nsIRDFContainer.h"
@@ -153,6 +154,20 @@ public:
     RebuildAll() = 0; // must be implemented by subclasses
 
     void RunnableRebuild() { Rebuild(); }
+    void RunnableLoadAndRebuild() {
+      Uninit(PR_FALSE);  // Reset results
+
+      nsCOMPtr<nsIDocument> doc = mRoot ? mRoot->GetDocument() : nsnull;
+      if (doc) {
+        PRBool shouldDelay;
+        LoadDataSources(doc, &shouldDelay);
+        if (!shouldDelay) {
+          Rebuild();
+        }
+      }
+    }
+    void UninitFalse() { Uninit(PR_FALSE); }
+    void UninitTrue() { Uninit(PR_TRUE); }
 
     /**
      * Find the <template> tag that applies for this builder
