content/xul/templates/src/nsXULTemplateQueryProcessorXML.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/content/xul/templates/src/nsXULTemplateQueryProcessorXML.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,481 @@
     1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#include "nsCOMPtr.h"
    1.10 +#include "nsAutoPtr.h"
    1.11 +#include "nsIDOMDocument.h"
    1.12 +#include "nsIDOMNode.h"
    1.13 +#include "nsIDOMElement.h"
    1.14 +#include "nsIDOMEvent.h"
    1.15 +#include "nsIDOMXPathNSResolver.h"
    1.16 +#include "nsIDocument.h"
    1.17 +#include "nsIContent.h"
    1.18 +#include "nsComponentManagerUtils.h"
    1.19 +#include "nsGkAtoms.h"
    1.20 +#include "nsIURI.h"
    1.21 +#include "nsIArray.h"
    1.22 +#include "nsIScriptContext.h"
    1.23 +#include "nsArrayUtils.h"
    1.24 +#include "nsPIDOMWindow.h"
    1.25 +#include "nsXULContentUtils.h"
    1.26 +#include "nsXMLHttpRequest.h"
    1.27 +
    1.28 +#include "nsXULTemplateQueryProcessorXML.h"
    1.29 +#include "nsXULTemplateResultXML.h"
    1.30 +#include "nsXULSortService.h"
    1.31 +
    1.32 +using namespace mozilla::dom;
    1.33 +
    1.34 +NS_IMPL_ISUPPORTS(nsXMLQuery, nsXMLQuery)
    1.35 +
    1.36 +//----------------------------------------------------------------------
    1.37 +//
    1.38 +// nsXULTemplateResultSetXML
    1.39 +//
    1.40 +
    1.41 +NS_IMPL_ISUPPORTS(nsXULTemplateResultSetXML, nsISimpleEnumerator)
    1.42 +
    1.43 +NS_IMETHODIMP
    1.44 +nsXULTemplateResultSetXML::HasMoreElements(bool *aResult)
    1.45 +{
    1.46 +    // if GetSnapshotLength failed, then the return type was not a set of
    1.47 +    // nodes, so just return false in this case.
    1.48 +    uint32_t length;
    1.49 +    if (NS_SUCCEEDED(mResults->GetSnapshotLength(&length)))
    1.50 +        *aResult = (mPosition < length);
    1.51 +    else
    1.52 +        *aResult = false;
    1.53 +
    1.54 +    return NS_OK;
    1.55 +}
    1.56 +
    1.57 +NS_IMETHODIMP
    1.58 +nsXULTemplateResultSetXML::GetNext(nsISupports **aResult)
    1.59 +{
    1.60 +    nsCOMPtr<nsIDOMNode> node;
    1.61 +    nsresult rv = mResults->SnapshotItem(mPosition, getter_AddRefs(node));
    1.62 +    NS_ENSURE_SUCCESS(rv, rv);
    1.63 +
    1.64 +    nsXULTemplateResultXML* result =
    1.65 +        new nsXULTemplateResultXML(mQuery, node, mBindingSet);
    1.66 +    NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
    1.67 +
    1.68 +    ++mPosition;
    1.69 +    *aResult = result;
    1.70 +    NS_ADDREF(result);
    1.71 +    return NS_OK;
    1.72 +}
    1.73 +
    1.74 +
    1.75 +//----------------------------------------------------------------------
    1.76 +//
    1.77 +// nsXULTemplateQueryProcessorXML
    1.78 +//
    1.79 +
    1.80 +static PLDHashOperator
    1.81 +TraverseRuleToBindingsMap(nsISupports* aKey, nsXMLBindingSet* aMatch, void* aContext)
    1.82 +{
    1.83 +    nsCycleCollectionTraversalCallback *cb =
    1.84 +        static_cast<nsCycleCollectionTraversalCallback*>(aContext);
    1.85 +    NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "mRuleToBindingsMap key");
    1.86 +    cb->NoteXPCOMChild(aKey);
    1.87 +    NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "mRuleToBindingsMap value");
    1.88 +    cb->NoteNativeChild(aMatch, NS_CYCLE_COLLECTION_PARTICIPANT(nsXMLBindingSet));
    1.89 +    return PL_DHASH_NEXT;
    1.90 +}
    1.91 +  
    1.92 +NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULTemplateQueryProcessorXML)
    1.93 +
    1.94 +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXULTemplateQueryProcessorXML)
    1.95 +    tmp->mRuleToBindingsMap.Clear();
    1.96 +    NS_IMPL_CYCLE_COLLECTION_UNLINK(mRoot)
    1.97 +    NS_IMPL_CYCLE_COLLECTION_UNLINK(mEvaluator)
    1.98 +    NS_IMPL_CYCLE_COLLECTION_UNLINK(mTemplateBuilder)
    1.99 +    NS_IMPL_CYCLE_COLLECTION_UNLINK(mRequest)
   1.100 +NS_IMPL_CYCLE_COLLECTION_UNLINK_END
   1.101 +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULTemplateQueryProcessorXML)
   1.102 +    tmp->mRuleToBindingsMap.EnumerateRead(TraverseRuleToBindingsMap, &cb);
   1.103 +    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRoot)
   1.104 +    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvaluator)
   1.105 +    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTemplateBuilder)
   1.106 +    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRequest)
   1.107 +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
   1.108 +NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXULTemplateQueryProcessorXML)
   1.109 +NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXULTemplateQueryProcessorXML)
   1.110 +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXULTemplateQueryProcessorXML)
   1.111 +    NS_INTERFACE_MAP_ENTRY(nsIXULTemplateQueryProcessor)
   1.112 +    NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener)
   1.113 +    NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXULTemplateQueryProcessor)
   1.114 +NS_INTERFACE_MAP_END
   1.115 +
   1.116 +/*
   1.117 + * Only the first datasource in aDataSource is used, which should be either an
   1.118 + * nsIURI of an XML document, or a DOM node. If the former, GetDatasource will
   1.119 + * load the document asynchronously and return null in aResult. Once the
   1.120 + * document has loaded, the builder's datasource will be set to the XML
   1.121 + * document. If the datasource is a DOM node, the node will be returned in
   1.122 + * aResult.
   1.123 + */
   1.124 +NS_IMETHODIMP
   1.125 +nsXULTemplateQueryProcessorXML::GetDatasource(nsIArray* aDataSources,
   1.126 +                                              nsIDOMNode* aRootNode,
   1.127 +                                              bool aIsTrusted,
   1.128 +                                              nsIXULTemplateBuilder* aBuilder,
   1.129 +                                              bool* aShouldDelayBuilding,
   1.130 +                                              nsISupports** aResult)
   1.131 +{
   1.132 +    *aResult = nullptr;
   1.133 +    *aShouldDelayBuilding = false;
   1.134 +
   1.135 +    nsresult rv;
   1.136 +    uint32_t length;
   1.137 +
   1.138 +    aDataSources->GetLength(&length);
   1.139 +    if (length == 0)
   1.140 +        return NS_OK;
   1.141 +
   1.142 +    // we get only the first item, because the query processor supports only
   1.143 +    // one document as a datasource
   1.144 +
   1.145 +    nsCOMPtr<nsIDOMNode> node = do_QueryElementAt(aDataSources, 0);
   1.146 +    if (node) {
   1.147 +        return CallQueryInterface(node, aResult);
   1.148 +    }
   1.149 +
   1.150 +    nsCOMPtr<nsIURI> uri = do_QueryElementAt(aDataSources, 0);
   1.151 +    if (!uri)
   1.152 +        return NS_ERROR_UNEXPECTED;
   1.153 +
   1.154 +    nsAutoCString uriStr;
   1.155 +    rv = uri->GetSpec(uriStr);
   1.156 +    NS_ENSURE_SUCCESS(rv, rv);
   1.157 +
   1.158 +    nsCOMPtr<nsIContent> root = do_QueryInterface(aRootNode);
   1.159 +    if (!root)
   1.160 +        return NS_ERROR_UNEXPECTED;
   1.161 +
   1.162 +    nsCOMPtr<nsIDocument> doc = root->GetCurrentDoc();
   1.163 +    if (!doc)
   1.164 +        return NS_ERROR_UNEXPECTED;
   1.165 +
   1.166 +    nsIPrincipal *docPrincipal = doc->NodePrincipal();
   1.167 +
   1.168 +    bool hasHadScriptObject = true;
   1.169 +    nsIScriptGlobalObject* scriptObject =
   1.170 +      doc->GetScriptHandlingObject(hasHadScriptObject);
   1.171 +    NS_ENSURE_STATE(scriptObject);
   1.172 +
   1.173 +    nsIScriptContext *context = scriptObject->GetContext();
   1.174 +    NS_ENSURE_TRUE(context, NS_OK);
   1.175 +
   1.176 +    nsCOMPtr<nsIXMLHttpRequest> req =
   1.177 +        do_CreateInstance(NS_XMLHTTPREQUEST_CONTRACTID, &rv);
   1.178 +    NS_ENSURE_SUCCESS(rv, rv);
   1.179 +
   1.180 +    rv = req->Init(docPrincipal, context,
   1.181 +                   scriptObject ? scriptObject : doc->GetScopeObject(),
   1.182 +                   nullptr);
   1.183 +    NS_ENSURE_SUCCESS(rv, rv);
   1.184 +
   1.185 +    rv = req->Open(NS_LITERAL_CSTRING("GET"), uriStr, true,
   1.186 +                   EmptyString(), EmptyString());
   1.187 +    NS_ENSURE_SUCCESS(rv, rv);
   1.188 +
   1.189 +    nsCOMPtr<EventTarget> target(do_QueryInterface(req));
   1.190 +    rv = target->AddEventListener(NS_LITERAL_STRING("load"), this, false);
   1.191 +    NS_ENSURE_SUCCESS(rv, rv);
   1.192 +
   1.193 +    rv = target->AddEventListener(NS_LITERAL_STRING("error"), this, false);
   1.194 +    NS_ENSURE_SUCCESS(rv, rv);
   1.195 +
   1.196 +    rv = req->Send(nullptr);
   1.197 +    NS_ENSURE_SUCCESS(rv, rv);
   1.198 +
   1.199 +    mTemplateBuilder = aBuilder;
   1.200 +    mRequest = req;
   1.201 +
   1.202 +    *aShouldDelayBuilding = true;
   1.203 +    return NS_OK;
   1.204 +}
   1.205 +
   1.206 +NS_IMETHODIMP
   1.207 +nsXULTemplateQueryProcessorXML::InitializeForBuilding(nsISupports* aDatasource,
   1.208 +                                                      nsIXULTemplateBuilder* aBuilder,
   1.209 +                                                      nsIDOMNode* aRootNode)
   1.210 +{
   1.211 +    if (mGenerationStarted)
   1.212 +        return NS_ERROR_UNEXPECTED;
   1.213 +
   1.214 +    // the datasource is either a document or a DOM element
   1.215 +    nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(aDatasource);
   1.216 +    if (doc)
   1.217 +        doc->GetDocumentElement(getter_AddRefs(mRoot));
   1.218 +    else
   1.219 +      mRoot = do_QueryInterface(aDatasource);
   1.220 +    NS_ENSURE_STATE(mRoot);
   1.221 +
   1.222 +    mEvaluator = do_CreateInstance("@mozilla.org/dom/xpath-evaluator;1");
   1.223 +    NS_ENSURE_TRUE(mEvaluator, NS_ERROR_OUT_OF_MEMORY);
   1.224 +
   1.225 +    return NS_OK;
   1.226 +}
   1.227 +
   1.228 +NS_IMETHODIMP
   1.229 +nsXULTemplateQueryProcessorXML::Done()
   1.230 +{
   1.231 +    mGenerationStarted = false;
   1.232 +
   1.233 +    mRuleToBindingsMap.Clear();
   1.234 +
   1.235 +    return NS_OK;
   1.236 +}
   1.237 +
   1.238 +NS_IMETHODIMP
   1.239 +nsXULTemplateQueryProcessorXML::CompileQuery(nsIXULTemplateBuilder* aBuilder,
   1.240 +                                             nsIDOMNode* aQueryNode,
   1.241 +                                             nsIAtom* aRefVariable,
   1.242 +                                             nsIAtom* aMemberVariable,
   1.243 +                                             nsISupports** _retval)
   1.244 +{
   1.245 +    nsresult rv = NS_OK;
   1.246 +
   1.247 +    *_retval = nullptr;
   1.248 +
   1.249 +    nsCOMPtr<nsIContent> content = do_QueryInterface(aQueryNode);
   1.250 +
   1.251 +    nsAutoString expr;
   1.252 +    content->GetAttr(kNameSpaceID_None, nsGkAtoms::expr, expr);
   1.253 +
   1.254 +    // if an expression is not specified, then the default is to
   1.255 +    // just take all of the children
   1.256 +    if (expr.IsEmpty())
   1.257 +        expr.AssignLiteral("*");
   1.258 +
   1.259 +    nsCOMPtr<nsIDOMXPathExpression> compiledexpr;
   1.260 +    rv = CreateExpression(expr, aQueryNode, getter_AddRefs(compiledexpr));
   1.261 +    if (NS_FAILED(rv)) {
   1.262 +        nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_BAD_XPATH);
   1.263 +        return rv;
   1.264 +    }
   1.265 +
   1.266 +    nsRefPtr<nsXMLQuery> query =
   1.267 +        new nsXMLQuery(this, aMemberVariable, compiledexpr);
   1.268 +    NS_ENSURE_TRUE(query, NS_ERROR_OUT_OF_MEMORY);
   1.269 +
   1.270 +    for (nsIContent* condition = content->GetFirstChild();
   1.271 +         condition;
   1.272 +         condition = condition->GetNextSibling()) {
   1.273 +
   1.274 +        if (condition->NodeInfo()->Equals(nsGkAtoms::assign,
   1.275 +                                          kNameSpaceID_XUL)) {
   1.276 +            nsAutoString var;
   1.277 +            condition->GetAttr(kNameSpaceID_None, nsGkAtoms::var, var);
   1.278 +
   1.279 +            nsAutoString expr;
   1.280 +            condition->GetAttr(kNameSpaceID_None, nsGkAtoms::expr, expr);
   1.281 +
   1.282 +            // ignore assignments without a variable or an expression
   1.283 +            if (!var.IsEmpty() && !expr.IsEmpty()) {
   1.284 +                nsCOMPtr<nsIDOMNode> conditionNode =
   1.285 +                    do_QueryInterface(condition);
   1.286 +                rv = CreateExpression(expr, conditionNode,
   1.287 +                                      getter_AddRefs(compiledexpr));
   1.288 +                if (NS_FAILED(rv)) {
   1.289 +                    nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_BAD_ASSIGN_XPATH);
   1.290 +                    return rv;
   1.291 +                }
   1.292 +
   1.293 +                nsCOMPtr<nsIAtom> varatom = do_GetAtom(var);
   1.294 +
   1.295 +                rv = query->AddBinding(varatom, compiledexpr);
   1.296 +                NS_ENSURE_SUCCESS(rv, rv);
   1.297 +            }
   1.298 +        }
   1.299 +    }
   1.300 +
   1.301 +    *_retval = query;
   1.302 +    NS_ADDREF(*_retval);
   1.303 +
   1.304 +    return rv;
   1.305 +}
   1.306 +
   1.307 +NS_IMETHODIMP
   1.308 +nsXULTemplateQueryProcessorXML::GenerateResults(nsISupports* aDatasource,
   1.309 +                                                nsIXULTemplateResult* aRef,
   1.310 +                                                nsISupports* aQuery,
   1.311 +                                                nsISimpleEnumerator** aResults)
   1.312 +{
   1.313 +    if (!aQuery)
   1.314 +        return NS_ERROR_INVALID_ARG;
   1.315 +
   1.316 +    mGenerationStarted = true;
   1.317 +
   1.318 +    nsCOMPtr<nsXMLQuery> xmlquery = do_QueryInterface(aQuery);
   1.319 +    if (!xmlquery)
   1.320 +        return NS_ERROR_INVALID_ARG;
   1.321 +
   1.322 +    nsCOMPtr<nsISupports> supports;
   1.323 +    nsCOMPtr<nsIDOMNode> context;
   1.324 +    if (aRef)
   1.325 +      aRef->GetBindingObjectFor(xmlquery->GetMemberVariable(),
   1.326 +                                getter_AddRefs(supports));
   1.327 +    context = do_QueryInterface(supports);
   1.328 +    if (!context)
   1.329 +        context = mRoot;
   1.330 +
   1.331 +    nsIDOMXPathExpression* expr = xmlquery->GetResultsExpression();
   1.332 +    if (!expr)
   1.333 +        return NS_ERROR_FAILURE;
   1.334 +
   1.335 +    nsCOMPtr<nsISupports> exprsupportsresults;
   1.336 +    nsresult rv = expr->Evaluate(context,
   1.337 +                                 nsIDOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE,
   1.338 +                                 nullptr, getter_AddRefs(exprsupportsresults));
   1.339 +    NS_ENSURE_SUCCESS(rv, rv);
   1.340 +
   1.341 +    nsCOMPtr<nsIDOMXPathResult> exprresults =
   1.342 +        do_QueryInterface(exprsupportsresults);
   1.343 +
   1.344 +    nsXULTemplateResultSetXML* results =
   1.345 +        new nsXULTemplateResultSetXML(xmlquery, exprresults,
   1.346 +                                      xmlquery->GetBindingSet());
   1.347 +    NS_ENSURE_TRUE(results, NS_ERROR_OUT_OF_MEMORY);
   1.348 +
   1.349 +    *aResults = results;
   1.350 +    NS_ADDREF(*aResults);
   1.351 +
   1.352 +    return NS_OK;
   1.353 +}
   1.354 +
   1.355 +NS_IMETHODIMP
   1.356 +nsXULTemplateQueryProcessorXML::AddBinding(nsIDOMNode* aRuleNode,
   1.357 +                                           nsIAtom* aVar,
   1.358 +                                           nsIAtom* aRef,
   1.359 +                                           const nsAString& aExpr)
   1.360 +{
   1.361 +    if (mGenerationStarted)
   1.362 +        return NS_ERROR_FAILURE;
   1.363 +
   1.364 +    nsRefPtr<nsXMLBindingSet> bindings = mRuleToBindingsMap.GetWeak(aRuleNode);
   1.365 +    if (!bindings) {
   1.366 +        bindings = new nsXMLBindingSet();
   1.367 +        mRuleToBindingsMap.Put(aRuleNode, bindings);
   1.368 +    }
   1.369 +
   1.370 +    nsCOMPtr<nsIDOMXPathExpression> compiledexpr;
   1.371 +    nsresult rv =
   1.372 +        CreateExpression(aExpr, aRuleNode, getter_AddRefs(compiledexpr));
   1.373 +    if (NS_FAILED(rv)) {
   1.374 +        nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_BAD_BINDING_XPATH);
   1.375 +        return NS_OK;
   1.376 +    }
   1.377 +
   1.378 +    // aRef isn't currently used for XML query processors
   1.379 +    return bindings->AddBinding(aVar, compiledexpr);
   1.380 +}
   1.381 +
   1.382 +NS_IMETHODIMP
   1.383 +nsXULTemplateQueryProcessorXML::TranslateRef(nsISupports* aDatasource,
   1.384 +                                             const nsAString& aRefString,
   1.385 +                                             nsIXULTemplateResult** aRef)
   1.386 +{
   1.387 +    *aRef = nullptr;
   1.388 +
   1.389 +    // the datasource is either a document or a DOM element
   1.390 +    nsCOMPtr<nsIDOMElement> rootElement;
   1.391 +    nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(aDatasource);
   1.392 +    if (doc)
   1.393 +        doc->GetDocumentElement(getter_AddRefs(rootElement));
   1.394 +    else
   1.395 +        rootElement = do_QueryInterface(aDatasource);
   1.396 +
   1.397 +    // if no root element, just return. The document may not have loaded yet
   1.398 +    if (!rootElement)
   1.399 +        return NS_OK;
   1.400 +    
   1.401 +    nsXULTemplateResultXML* result =
   1.402 +        new nsXULTemplateResultXML(nullptr, rootElement, nullptr);
   1.403 +    NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
   1.404 +
   1.405 +    *aRef = result;
   1.406 +    NS_ADDREF(*aRef);
   1.407 +
   1.408 +    return NS_OK;
   1.409 +}
   1.410 +
   1.411 +
   1.412 +NS_IMETHODIMP
   1.413 +nsXULTemplateQueryProcessorXML::CompareResults(nsIXULTemplateResult* aLeft,
   1.414 +                                               nsIXULTemplateResult* aRight,
   1.415 +                                               nsIAtom* aVar,
   1.416 +                                               uint32_t aSortHints,
   1.417 +                                               int32_t* aResult)
   1.418 +{
   1.419 +    *aResult = 0;
   1.420 +    if (!aVar)
   1.421 +        return NS_OK;
   1.422 +
   1.423 +    nsAutoString leftVal;
   1.424 +    if (aLeft)
   1.425 +        aLeft->GetBindingFor(aVar, leftVal);
   1.426 +
   1.427 +    nsAutoString rightVal;
   1.428 +    if (aRight)
   1.429 +        aRight->GetBindingFor(aVar, rightVal);
   1.430 +
   1.431 +    *aResult = XULSortServiceImpl::CompareValues(leftVal, rightVal, aSortHints);
   1.432 +    return NS_OK;
   1.433 +}
   1.434 +
   1.435 +nsXMLBindingSet*
   1.436 +nsXULTemplateQueryProcessorXML::GetOptionalBindingsForRule(nsIDOMNode* aRuleNode)
   1.437 +{
   1.438 +    return mRuleToBindingsMap.GetWeak(aRuleNode);
   1.439 +}
   1.440 +
   1.441 +nsresult
   1.442 +nsXULTemplateQueryProcessorXML::CreateExpression(const nsAString& aExpr,
   1.443 +                                                 nsIDOMNode* aNode,
   1.444 +                                                 nsIDOMXPathExpression** aCompiledExpr)
   1.445 +{
   1.446 +    nsCOMPtr<nsIDOMXPathNSResolver> nsResolver;
   1.447 +
   1.448 +    nsCOMPtr<nsIDOMDocument> doc;
   1.449 +    aNode->GetOwnerDocument(getter_AddRefs(doc));
   1.450 +
   1.451 +    nsCOMPtr<nsIDOMXPathEvaluator> eval = do_QueryInterface(doc);
   1.452 +    if (eval) {
   1.453 +        nsresult rv =
   1.454 +             eval->CreateNSResolver(aNode, getter_AddRefs(nsResolver));
   1.455 +        NS_ENSURE_SUCCESS(rv, rv);
   1.456 +    }
   1.457 +
   1.458 +    return mEvaluator->CreateExpression(aExpr, nsResolver, aCompiledExpr);
   1.459 +}
   1.460 +
   1.461 +NS_IMETHODIMP
   1.462 +nsXULTemplateQueryProcessorXML::HandleEvent(nsIDOMEvent* aEvent)
   1.463 +{
   1.464 +    NS_PRECONDITION(aEvent, "aEvent null");
   1.465 +    nsAutoString eventType;
   1.466 +    aEvent->GetType(eventType);
   1.467 +
   1.468 +    if (eventType.EqualsLiteral("load") && mTemplateBuilder) {
   1.469 +        NS_ASSERTION(mRequest, "request was not set");
   1.470 +        nsCOMPtr<nsIDOMDocument> doc;
   1.471 +        if (NS_SUCCEEDED(mRequest->GetResponseXML(getter_AddRefs(doc))))
   1.472 +            mTemplateBuilder->SetDatasource(doc);
   1.473 +
   1.474 +        // to avoid leak. we don't need it after...
   1.475 +        mTemplateBuilder = nullptr;
   1.476 +        mRequest = nullptr;
   1.477 +    }
   1.478 +    else if (eventType.EqualsLiteral("error")) {
   1.479 +        mTemplateBuilder = nullptr;
   1.480 +        mRequest = nullptr;
   1.481 +    }
   1.482 +
   1.483 +    return NS_OK;
   1.484 +}

mercurial