Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsInstantiationNode.h"
7 #include "nsTemplateRule.h"
8 #include "nsXULTemplateQueryProcessorRDF.h"
10 #include "prlog.h"
11 #ifdef PR_LOGGING
12 extern PRLogModuleInfo* gXULTemplateLog;
13 #endif
15 nsInstantiationNode::nsInstantiationNode(nsXULTemplateQueryProcessorRDF* aProcessor,
16 nsRDFQuery* aQuery)
17 : mProcessor(aProcessor),
18 mQuery(aQuery)
19 {
20 #ifdef PR_LOGGING
21 PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
22 ("nsInstantiationNode[%p] query=%p", this, aQuery));
23 #endif
25 MOZ_COUNT_CTOR(nsInstantiationNode);
26 }
29 nsInstantiationNode::~nsInstantiationNode()
30 {
31 MOZ_COUNT_DTOR(nsInstantiationNode);
32 }
34 nsresult
35 nsInstantiationNode::Propagate(InstantiationSet& aInstantiations,
36 bool aIsUpdate, bool& aTakenInstantiations)
37 {
38 // In update mode, iterate through the results and call the template
39 // builder to update them. In non-update mode, cache them in the processor
40 // to be used during processing. The results are cached in the processor
41 // so that the simple rules are only computed once. In this situation, all
42 // data for all queries are calculated at once.
43 nsresult rv = NS_OK;
45 aTakenInstantiations = false;
47 if (aIsUpdate) {
48 // Iterate through newly added keys to determine which rules fired.
49 //
50 // XXXwaterson Unfortunately, this could also lead to retractions;
51 // e.g., (container ?a ^empty false) could become "unmatched". How
52 // to track those?
53 nsCOMPtr<nsIDOMNode> querynode;
54 mQuery->GetQueryNode(getter_AddRefs(querynode));
56 InstantiationSet::ConstIterator last = aInstantiations.Last();
57 for (InstantiationSet::ConstIterator inst = aInstantiations.First(); inst != last; ++inst) {
58 nsAssignmentSet assignments = inst->mAssignments;
60 nsCOMPtr<nsIRDFNode> node;
61 assignments.GetAssignmentFor(mQuery->mMemberVariable,
62 getter_AddRefs(node));
63 if (node) {
64 nsCOMPtr<nsIRDFResource> resource = do_QueryInterface(node);
65 if (resource) {
66 nsRefPtr<nsXULTemplateResultRDF> nextresult =
67 new nsXULTemplateResultRDF(mQuery, *inst, resource);
68 if (! nextresult)
69 return NS_ERROR_OUT_OF_MEMORY;
71 rv = mProcessor->AddMemoryElements(*inst, nextresult);
72 if (NS_FAILED(rv))
73 return rv;
75 mProcessor->GetBuilder()->AddResult(nextresult, querynode);
76 }
77 }
78 }
79 }
80 else {
81 nsresult rv = mQuery->SetCachedResults(mProcessor, aInstantiations);
82 if (NS_SUCCEEDED(rv))
83 aTakenInstantiations = true;
84 }
86 return rv;
87 }