Bug 1029104 - Convert XPathExpression to WebIDL bindings, various small fixes. r=bz.
authorPeter Van der Beken <peterv@propagandism.org>
Thu, 04 Jul 2013 17:40:10 +0200
changeset 191342 6f97e210af1d5801161814c0992f1090877d5a48
parent 191341 c134a28bc14357b0d6fb45e4308666f61fc21936
child 191343 9cbda3d9a79c45b15cb612cf79efef7dcca0bf96
push id27041
push userphilringnalda@gmail.com
push dateSun, 29 Jun 2014 00:39:21 +0000
treeherdermozilla-central@afa67a2f7905 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1029104
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 1029104 - Convert XPathExpression to WebIDL bindings, various small fixes. r=bz.
content/xul/templates/src/nsXMLBinding.cpp
content/xul/templates/src/nsXMLBinding.h
content/xul/templates/src/nsXULTemplateQueryProcessorXML.cpp
content/xul/templates/src/nsXULTemplateQueryProcessorXML.h
content/xul/templates/src/nsXULTemplateResultXML.cpp
content/xul/templates/src/nsXULTemplateResultXML.h
--- a/content/xul/templates/src/nsXMLBinding.cpp
+++ b/content/xul/templates/src/nsXMLBinding.cpp
@@ -10,70 +10,50 @@
 #include "mozilla/dom/XPathResult.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 NS_IMPL_CYCLE_COLLECTING_NATIVE_ADDREF(nsXMLBindingSet)
 NS_IMPL_CYCLE_COLLECTING_NATIVE_RELEASE(nsXMLBindingSet)
 
-NS_IMPL_CYCLE_COLLECTION_CLASS(nsXMLBindingSet)
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXMLBindingSet)
-  nsXMLBinding* binding = tmp->mFirst;
-  while (binding) {
-    binding->mExpr = nullptr;
-    binding = binding->mNext;
-  }
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXMLBindingSet)
-  nsXMLBinding* binding = tmp->mFirst;
-  while (binding) {
-    NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "nsXMLBinding::mExpr"); 
-    cb.NoteXPCOMChild(binding->mExpr);
-    binding = binding->mNext;
-  }
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+NS_IMPL_CYCLE_COLLECTION(nsXMLBindingSet, mFirst)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsXMLBindingSet, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsXMLBindingSet, Release)
 
 nsXMLBindingSet::~nsXMLBindingSet()
 {}
 
-nsresult
+void
 nsXMLBindingSet::AddBinding(nsIAtom* aVar, nsIDOMXPathExpression* aExpr)
 {
   nsAutoPtr<nsXMLBinding> newbinding(new nsXMLBinding(aVar, aExpr));
-  NS_ENSURE_TRUE(newbinding, NS_ERROR_OUT_OF_MEMORY);
 
   if (mFirst) {
     nsXMLBinding* binding = mFirst;
 
     while (binding) {
       // if the target variable is already used in a binding, ignore it
       // since it won't be useful for anything
       if (binding->mVar == aVar)
-        return NS_OK;
+        return;
 
       // add the binding at the end of the list
       if (!binding->mNext) {
         binding->mNext = newbinding;
-        break;
+        return;
       }
 
       binding = binding->mNext;
     }
   }
   else {
     mFirst = newbinding;
   }
-
-  return NS_OK;
 }
 
 int32_t
 nsXMLBindingSet::LookupTargetIndex(nsIAtom* aTargetVariable,
                                    nsXMLBinding** aBinding)
 {
   int32_t idx = 0;
   nsXMLBinding* binding = mFirst;
@@ -97,49 +77,42 @@ nsXMLBindingValues::GetAssignmentFor(nsX
                                      int32_t aIndex,
                                      uint16_t aType)
 {
   XPathResult* value = mValues.SafeElementAt(aIndex);
   if (value) {
     return value;
   }
 
-  nsCOMPtr<nsIDOMNode> contextNode;
-  aResult->GetNode(getter_AddRefs(contextNode));
+  nsCOMPtr<nsIDOMNode> contextNode = do_QueryInterface(aResult->Node());
   if (!contextNode) {
     return nullptr;
   }
 
   mValues.EnsureLengthAtLeast(aIndex + 1);
 
   nsCOMPtr<nsISupports> resultsupports;
   aBinding->mExpr->Evaluate(contextNode, aType,
                             nullptr, getter_AddRefs(resultsupports));
 
   mValues.ReplaceElementAt(aIndex, XPathResult::FromSupports(resultsupports));
 
   return mValues[aIndex];
 }
 
-void
+nsINode*
 nsXMLBindingValues::GetNodeAssignmentFor(nsXULTemplateResultXML* aResult,
                                          nsXMLBinding* aBinding,
-                                         int32_t aIndex,
-                                         nsIDOMNode** aNode)
+                                         int32_t aIndex)
 {
   XPathResult* result = GetAssignmentFor(aResult, aBinding, aIndex,
                                          XPathResult::FIRST_ORDERED_NODE_TYPE);
 
-  nsINode* node;
   ErrorResult rv;
-  if (result && (node = result->GetSingleNodeValue(rv))) {
-    CallQueryInterface(node, aNode);
-  } else {
-    *aNode = nullptr;
-  }
+  return result ? result->GetSingleNodeValue(rv) : nullptr;
 }
 
 void
 nsXMLBindingValues::GetStringAssignmentFor(nsXULTemplateResultXML* aResult,
                                            nsXMLBinding* aBinding,
                                            int32_t aIndex,
                                            nsAString& aValue)
 {
--- a/content/xul/templates/src/nsXMLBinding.h
+++ b/content/xul/templates/src/nsXMLBinding.h
@@ -6,16 +6,17 @@
 #ifndef nsXMLBinding_h__
 #define nsXMLBinding_h__
 
 #include "nsAutoPtr.h"
 #include "nsIAtom.h"
 #include "nsCycleCollectionParticipant.h"
 #include "mozilla/Attributes.h"
 
+class nsINode;
 class nsXULTemplateResultXML;
 class nsXMLBindingValues;
 namespace mozilla {
 namespace dom {
 class XPathResult;
 }
 }
 
@@ -39,16 +40,38 @@ struct nsXMLBinding {
   }
 
   ~nsXMLBinding()
   {
     MOZ_COUNT_DTOR(nsXMLBinding);
   }
 };
 
+inline void
+ImplCycleCollectionUnlink(nsXMLBinding* aBinding)
+{
+  while (aBinding) {
+    aBinding->mExpr = nullptr;
+    aBinding = aBinding->mNext;
+  }
+}
+
+inline void
+ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
+                            nsXMLBinding* aBinding,
+                            const char* aName,
+                            uint32_t aFlags = 0)
+{
+  while (aBinding) {
+    CycleCollectionNoteChild(aCallback, aBinding->mExpr.get(),
+                             "nsXMLBinding::mExpr", aFlags);
+    aBinding = aBinding->mNext;
+  }
+}
+
 /**
  * a collection of <binding> descriptors. This object is refcounted by
  * nsXMLBindingValues objects and the query processor.
  */
 class nsXMLBindingSet MOZ_FINAL
 {
   ~nsXMLBindingSet();
 
@@ -66,17 +89,17 @@ public:
   NS_METHOD_(MozExternalRefCountType) AddRef();
   NS_METHOD_(MozExternalRefCountType) Release();
   NS_DECL_OWNINGTHREAD
   NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsXMLBindingSet)
 
   /**
    * Add a binding to the set
    */
-  nsresult
+  void
   AddBinding(nsIAtom* aVar, nsIDOMXPathExpression* aExpr);
 
   /**
    * The nsXMLBindingValues class stores an array of values, one for each
    * target symbol that could be set by the bindings in the set.
    * LookupTargetIndex determines the index into the array for a given
    * target symbol.
    */
@@ -126,21 +149,20 @@ public:
    * aType the type of result expected
    */
   mozilla::dom::XPathResult*
   GetAssignmentFor(nsXULTemplateResultXML* aResult,
                    nsXMLBinding* aBinding,
                    int32_t idx,
                    uint16_t type);
 
-  void
+  nsINode*
   GetNodeAssignmentFor(nsXULTemplateResultXML* aResult,
                        nsXMLBinding* aBinding,
-                       int32_t idx,
-                       nsIDOMNode** aValue);
+                       int32_t idx);
 
   void
   GetStringAssignmentFor(nsXULTemplateResultXML* aResult,
                          nsXMLBinding* aBinding,
                          int32_t idx,
                          nsAString& aValue);
 };
 
--- a/content/xul/templates/src/nsXULTemplateQueryProcessorXML.cpp
+++ b/content/xul/templates/src/nsXULTemplateQueryProcessorXML.cpp
@@ -16,20 +16,21 @@
 #include "nsGkAtoms.h"
 #include "nsIURI.h"
 #include "nsIArray.h"
 #include "nsIScriptContext.h"
 #include "nsArrayUtils.h"
 #include "nsPIDOMWindow.h"
 #include "nsXULContentUtils.h"
 #include "nsXMLHttpRequest.h"
-
+#include "mozilla/dom/XPathEvaluator.h"
 #include "nsXULTemplateQueryProcessorXML.h"
 #include "nsXULTemplateResultXML.h"
 #include "nsXULSortService.h"
+#include "mozilla/dom/Element.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 NS_IMPL_ISUPPORTS(nsXMLQuery, nsXMLQuery)
 
 //----------------------------------------------------------------------
 //
@@ -48,25 +49,23 @@ nsXULTemplateResultSetXML::HasMoreElemen
     *aResult = !rv.Failed() && mPosition < length;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTemplateResultSetXML::GetNext(nsISupports **aResult)
 {
     ErrorResult rv;
-    nsCOMPtr<nsIDOMNode> node =
-        do_QueryInterface(mResults->SnapshotItem(mPosition, rv));
+    nsINode* node = mResults->SnapshotItem(mPosition, rv);
     if (rv.Failed()) {
         return rv.ErrorCode();
     }
 
     nsXULTemplateResultXML* result =
-        new nsXULTemplateResultXML(mQuery, node, mBindingSet);
-    NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
+        new nsXULTemplateResultXML(mQuery, node->AsContent(), mBindingSet);
 
     ++mPosition;
     *aResult = result;
     NS_ADDREF(result);
     return NS_OK;
 }
 
 
@@ -212,18 +211,17 @@ nsXULTemplateQueryProcessorXML::Initiali
     // the datasource is either a document or a DOM element
     nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(aDatasource);
     if (doc)
         doc->GetDocumentElement(getter_AddRefs(mRoot));
     else
       mRoot = do_QueryInterface(aDatasource);
     NS_ENSURE_STATE(mRoot);
 
-    mEvaluator = do_CreateInstance("@mozilla.org/dom/xpath-evaluator;1");
-    NS_ENSURE_TRUE(mEvaluator, NS_ERROR_OUT_OF_MEMORY);
+    mEvaluator = new XPathEvaluator();
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTemplateQueryProcessorXML::Done()
 {
     mGenerationStarted = false;
@@ -250,61 +248,57 @@ nsXULTemplateQueryProcessorXML::CompileQ
     content->GetAttr(kNameSpaceID_None, nsGkAtoms::expr, expr);
 
     // if an expression is not specified, then the default is to
     // just take all of the children
     if (expr.IsEmpty())
         expr.Assign('*');
 
     nsCOMPtr<nsIDOMXPathExpression> compiledexpr;
-    rv = CreateExpression(expr, aQueryNode, getter_AddRefs(compiledexpr));
+    rv = CreateExpression(expr, content, getter_AddRefs(compiledexpr));
     if (NS_FAILED(rv)) {
         nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_BAD_XPATH);
         return rv;
     }
 
     nsRefPtr<nsXMLQuery> query =
         new nsXMLQuery(this, aMemberVariable, compiledexpr);
-    NS_ENSURE_TRUE(query, NS_ERROR_OUT_OF_MEMORY);
 
     for (nsIContent* condition = content->GetFirstChild();
          condition;
          condition = condition->GetNextSibling()) {
 
         if (condition->NodeInfo()->Equals(nsGkAtoms::assign,
                                           kNameSpaceID_XUL)) {
             nsAutoString var;
             condition->GetAttr(kNameSpaceID_None, nsGkAtoms::var, var);
 
             nsAutoString expr;
             condition->GetAttr(kNameSpaceID_None, nsGkAtoms::expr, expr);
 
             // ignore assignments without a variable or an expression
             if (!var.IsEmpty() && !expr.IsEmpty()) {
-                nsCOMPtr<nsIDOMNode> conditionNode =
-                    do_QueryInterface(condition);
-                rv = CreateExpression(expr, conditionNode,
+                rv = CreateExpression(expr, condition,
                                       getter_AddRefs(compiledexpr));
                 if (NS_FAILED(rv)) {
                     nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_BAD_ASSIGN_XPATH);
                     return rv;
                 }
 
                 nsCOMPtr<nsIAtom> varatom = do_GetAtom(var);
 
-                rv = query->AddBinding(varatom, compiledexpr);
-                NS_ENSURE_SUCCESS(rv, rv);
+                query->AddBinding(varatom, compiledexpr);
             }
         }
     }
 
     *_retval = query;
     NS_ADDREF(*_retval);
 
-    return rv;
+    return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTemplateQueryProcessorXML::GenerateResults(nsISupports* aDatasource,
                                                 nsIXULTemplateResult* aRef,
                                                 nsISupports* aQuery,
                                                 nsISimpleEnumerator** aResults)
 {
@@ -335,17 +329,16 @@ nsXULTemplateQueryProcessorXML::Generate
                                  XPathResult::ORDERED_NODE_SNAPSHOT_TYPE,
                                  nullptr, getter_AddRefs(exprsupportsresults));
     NS_ENSURE_SUCCESS(rv, rv);
 
     XPathResult* exprresults = XPathResult::FromSupports(exprsupportsresults);
     nsXULTemplateResultSetXML* results =
         new nsXULTemplateResultSetXML(xmlquery, exprresults,
                                       xmlquery->GetBindingSet());
-    NS_ENSURE_TRUE(results, NS_ERROR_OUT_OF_MEMORY);
 
     *aResults = results;
     NS_ADDREF(*aResults);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -358,50 +351,51 @@ nsXULTemplateQueryProcessorXML::AddBindi
         return NS_ERROR_FAILURE;
 
     nsRefPtr<nsXMLBindingSet> bindings = mRuleToBindingsMap.GetWeak(aRuleNode);
     if (!bindings) {
         bindings = new nsXMLBindingSet();
         mRuleToBindingsMap.Put(aRuleNode, bindings);
     }
 
+    nsCOMPtr<nsINode> ruleNode = do_QueryInterface(aRuleNode);
     nsCOMPtr<nsIDOMXPathExpression> compiledexpr;
     nsresult rv =
-        CreateExpression(aExpr, aRuleNode, getter_AddRefs(compiledexpr));
+        CreateExpression(aExpr, ruleNode, getter_AddRefs(compiledexpr));
     if (NS_FAILED(rv)) {
         nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_BAD_BINDING_XPATH);
         return NS_OK;
     }
 
     // aRef isn't currently used for XML query processors
-    return bindings->AddBinding(aVar, compiledexpr);
+    bindings->AddBinding(aVar, compiledexpr);
+    return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTemplateQueryProcessorXML::TranslateRef(nsISupports* aDatasource,
                                              const nsAString& aRefString,
                                              nsIXULTemplateResult** aRef)
 {
     *aRef = nullptr;
 
     // the datasource is either a document or a DOM element
-    nsCOMPtr<nsIDOMElement> rootElement;
-    nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(aDatasource);
+    nsCOMPtr<Element> rootElement;
+    nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDatasource);
     if (doc)
-        doc->GetDocumentElement(getter_AddRefs(rootElement));
+        rootElement = doc->GetRootElement();
     else
         rootElement = do_QueryInterface(aDatasource);
 
     // if no root element, just return. The document may not have loaded yet
     if (!rootElement)
         return NS_OK;
     
     nsXULTemplateResultXML* result =
         new nsXULTemplateResultXML(nullptr, rootElement, nullptr);
-    NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
 
     *aRef = result;
     NS_ADDREF(*aRef);
 
     return NS_OK;
 }
 
 
@@ -431,29 +425,24 @@ nsXULTemplateQueryProcessorXML::CompareR
 nsXMLBindingSet*
 nsXULTemplateQueryProcessorXML::GetOptionalBindingsForRule(nsIDOMNode* aRuleNode)
 {
     return mRuleToBindingsMap.GetWeak(aRuleNode);
 }
 
 nsresult
 nsXULTemplateQueryProcessorXML::CreateExpression(const nsAString& aExpr,
-                                                 nsIDOMNode* aNode,
+                                                 nsINode* aNode,
                                                  nsIDOMXPathExpression** aCompiledExpr)
 {
-    nsCOMPtr<nsIDOMXPathNSResolver> nsResolver;
-
-    nsCOMPtr<nsIDOMDocument> doc;
-    aNode->GetOwnerDocument(getter_AddRefs(doc));
-
-    nsCOMPtr<nsIDOMXPathEvaluator> eval = do_QueryInterface(doc);
-    if (eval) {
-        nsresult rv =
-             eval->CreateNSResolver(aNode, getter_AddRefs(nsResolver));
-        NS_ENSURE_SUCCESS(rv, rv);
+    ErrorResult rv;
+    nsCOMPtr<nsIDOMXPathNSResolver> nsResolver =
+        aNode->OwnerDoc()->CreateNSResolver(aNode, rv);
+    if (rv.Failed()) {
+        return rv.ErrorCode();
     }
 
     return mEvaluator->CreateExpression(aExpr, nsResolver, aCompiledExpr);
 }
 
 NS_IMETHODIMP
 nsXULTemplateQueryProcessorXML::HandleEvent(nsIDOMEvent* aEvent)
 {
--- a/content/xul/templates/src/nsXULTemplateQueryProcessorXML.h
+++ b/content/xul/templates/src/nsXULTemplateQueryProcessorXML.h
@@ -44,25 +44,24 @@ class nsXMLQuery MOZ_FINAL : public nsIS
 
     // return a weak reference to the expression used to generate results
     nsIDOMXPathExpression* GetResultsExpression() { return mResultsExpr; }
 
     // return a weak reference to the additional required bindings
     nsXMLBindingSet* GetBindingSet() { return mRequiredBindings; }
 
     // add a required binding for the query
-    nsresult
+    void
     AddBinding(nsIAtom* aVar, nsIDOMXPathExpression* aExpr)
     {
         if (!mRequiredBindings) {
             mRequiredBindings = new nsXMLBindingSet();
-            NS_ENSURE_TRUE(mRequiredBindings, NS_ERROR_OUT_OF_MEMORY);
         }
 
-        return mRequiredBindings->AddBinding(aVar, aExpr);
+        mRequiredBindings->AddBinding(aVar, aExpr);
     }
 
     nsXMLQuery(nsXULTemplateQueryProcessorXML* aProcessor,
                         nsIAtom* aMemberVariable,
                         nsIDOMXPathExpression* aResultsExpr)
         : mProcessor(aProcessor),
           mMemberVariable(aMemberVariable),
           mResultsExpr(aResultsExpr)
@@ -140,17 +139,17 @@ public:
 
     nsXMLBindingSet*
     GetOptionalBindingsForRule(nsIDOMNode* aRuleNode);
 
     // create an XPath expression from aExpr, using aNode for
     // resolving namespaces
     nsresult
     CreateExpression(const nsAString& aExpr,
-                     nsIDOMNode* aNode,
+                     nsINode* aNode,
                      nsIDOMXPathExpression** aCompiledExpr);
 
 private:
 
     ~nsXULTemplateQueryProcessorXML() {}
 
     bool mGenerationStarted;
 
--- a/content/xul/templates/src/nsXULTemplateResultXML.cpp
+++ b/content/xul/templates/src/nsXULTemplateResultXML.cpp
@@ -13,27 +13,25 @@
 #include "nsXULTemplateResultXML.h"
 #include "nsXMLBinding.h"
 
 static uint32_t sTemplateId = 0;
 
 NS_IMPL_ISUPPORTS(nsXULTemplateResultXML, nsIXULTemplateResult)
 
 nsXULTemplateResultXML::nsXULTemplateResultXML(nsXMLQuery* aQuery,
-                                               nsIDOMNode* aNode,
+                                               nsIContent* aNode,
                                                nsXMLBindingSet* aBindings)
     : mQuery(aQuery), mNode(aNode)
 {
-    nsCOMPtr<nsIContent> content = do_QueryInterface(mNode);
-
     // If the node has an id, create the uri from it. Otherwise, there isn't
     // anything to identify the node with so just use a somewhat random number.
-    nsCOMPtr<nsIAtom> id = content->GetID();
+    nsCOMPtr<nsIAtom> id = mNode->GetID();
     if (id) {
-      nsCOMPtr<nsIURI> uri = content->GetBaseURI();
+      nsCOMPtr<nsIURI> uri = mNode->GetBaseURI();
       nsAutoCString spec;
       uri->GetSpec(spec);
 
       mId = NS_ConvertUTF8toUTF16(spec);
 
       nsAutoString idstr;
       id->ToString(idstr);
       mId += NS_LITERAL_STRING("#") + idstr;
@@ -47,20 +45,17 @@ nsXULTemplateResultXML::nsXULTemplateRes
     if (aBindings)
         mRequiredValues.SetBindingSet(aBindings);
 }
 
 NS_IMETHODIMP
 nsXULTemplateResultXML::GetIsContainer(bool* aIsContainer)
 {
     // a node is considered a container if it has children
-    if (mNode)
-        mNode->HasChildNodes(aIsContainer);
-    else
-        *aIsContainer = false;
+    *aIsContainer = mNode && mNode->HasChildNodes();
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTemplateResultXML::GetIsEmpty(bool* aIsEmpty)
 {
     // a node is considered empty if it has no elements as children
     nsCOMPtr<nsIContent> content = do_QueryInterface(mNode);
@@ -143,38 +138,35 @@ nsXULTemplateResultXML::GetBindingFor(ns
 }
 
 NS_IMETHODIMP
 nsXULTemplateResultXML::GetBindingObjectFor(nsIAtom* aVar, nsISupports** aValue)
 {
     NS_ENSURE_ARG_POINTER(aVar);
 
     nsXMLBinding* binding;
-    nsCOMPtr<nsIDOMNode> node;
+    nsCOMPtr<nsISupports> node;
 
     if (mQuery && aVar == mQuery->GetMemberVariable()) {
         node = mNode;
     }
     else {
         int32_t idx = mRequiredValues.LookupTargetIndex(aVar, &binding);
         if (idx > 0) {
-            mRequiredValues.GetNodeAssignmentFor(this, binding, idx,
-                                                 getter_AddRefs(node));
+            node = mRequiredValues.GetNodeAssignmentFor(this, binding, idx);
         }
         else {
             idx = mOptionalValues.LookupTargetIndex(aVar, &binding);
             if (idx > 0) {
-                mOptionalValues.GetNodeAssignmentFor(this, binding, idx,
-                                                     getter_AddRefs(node));
+                node = mOptionalValues.GetNodeAssignmentFor(this, binding, idx);
             }
         }
     }
 
-    *aValue = node;
-    NS_IF_ADDREF(*aValue);
+    node.forget(aValue);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTemplateResultXML::RuleMatched(nsISupports* aQueryNode,
                                     nsIDOMNode* aRuleNode)
 {
     // when a rule matches, set the bindings that must be used.
@@ -190,15 +182,8 @@ nsXULTemplateResultXML::RuleMatched(nsIS
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTemplateResultXML::HasBeenRemoved()
 {
     return NS_OK;
 }
-
-void
-nsXULTemplateResultXML::GetNode(nsIDOMNode** aNode)
-{
-    *aNode = mNode;
-    NS_IF_ADDREF(*aNode);
-}
--- a/content/xul/templates/src/nsXULTemplateResultXML.h
+++ b/content/xul/templates/src/nsXULTemplateResultXML.h
@@ -2,16 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsXULTemplateResultXML_h__
 #define nsXULTemplateResultXML_h__
 
 #include "nsCOMPtr.h"
+#include "nsIContent.h"
 #include "nsIURI.h"
 #include "nsIRDFResource.h"
 #include "nsXULTemplateQueryProcessorXML.h"
 #include "nsIXULTemplateResult.h"
 #include "mozilla/Attributes.h"
 
 /**
  * An single result of an query
@@ -19,36 +20,39 @@
 class nsXULTemplateResultXML MOZ_FINAL : public nsIXULTemplateResult
 {
 public:
     NS_DECL_ISUPPORTS
 
     NS_DECL_NSIXULTEMPLATERESULT
 
     nsXULTemplateResultXML(nsXMLQuery* aQuery,
-                           nsIDOMNode* aNode,
+                           nsIContent* aNode,
                            nsXMLBindingSet* aBindings);
 
-    void GetNode(nsIDOMNode** aNode);
+    nsIContent* Node()
+    {
+        return mNode;
+    }
 
 protected:
 
     ~nsXULTemplateResultXML() {}
 
     // ID used for persisting data. It is constructed using the mNode's
     // base uri plus the node's id to form 'baseuri#id'. If the node has no
     // id, then an id of the form 'row<some number>' is generated. In the
     // latter case, persistence will not work as there won't be a unique id.
     nsAutoString mId;
 
     // query that generated the result
     nsCOMPtr<nsXMLQuery> mQuery;
 
     // context node in datasource
-    nsCOMPtr<nsIDOMNode> mNode;
+    nsCOMPtr<nsIContent> mNode;
 
     // assignments in query
     nsXMLBindingValues mRequiredValues;
 
     // extra assignments made by rules (<binding> tags)
     nsXMLBindingValues mOptionalValues;
 };