Line data Source code
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/. */
5 :
6 : #include "nsXULTemplateResultRDF.h"
7 : #include "nsXULContentUtils.h"
8 :
9 : // XXXndeakin for some reason, making this class have classinfo breaks trees.
10 : //#include "nsIDOMClassInfo.h"
11 :
12 0 : NS_IMPL_CYCLE_COLLECTION(nsXULTemplateResultRDF, mQuery)
13 :
14 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXULTemplateResultRDF)
15 0 : NS_INTERFACE_MAP_ENTRY(nsIXULTemplateResult)
16 0 : NS_INTERFACE_MAP_ENTRY(nsISupports)
17 0 : NS_INTERFACE_MAP_END
18 :
19 0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXULTemplateResultRDF)
20 0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXULTemplateResultRDF)
21 :
22 0 : nsXULTemplateResultRDF::nsXULTemplateResultRDF(nsIRDFResource* aNode)
23 : : mQuery(nullptr),
24 0 : mNode(aNode)
25 : {
26 0 : }
27 :
28 0 : nsXULTemplateResultRDF::nsXULTemplateResultRDF(nsRDFQuery* aQuery,
29 : const Instantiation& aInst,
30 0 : nsIRDFResource *aNode)
31 : : mQuery(aQuery),
32 : mNode(aNode),
33 0 : mInst(aInst)
34 : {
35 0 : }
36 :
37 0 : nsXULTemplateResultRDF::~nsXULTemplateResultRDF()
38 : {
39 0 : }
40 :
41 : NS_IMETHODIMP
42 0 : nsXULTemplateResultRDF::GetIsContainer(bool* aIsContainer)
43 : {
44 0 : *aIsContainer = false;
45 :
46 0 : if (mNode) {
47 0 : nsXULTemplateQueryProcessorRDF* processor = GetProcessor();
48 0 : if (processor)
49 0 : return processor->CheckContainer(mNode, aIsContainer);
50 : }
51 :
52 0 : return NS_OK;
53 : }
54 :
55 : NS_IMETHODIMP
56 0 : nsXULTemplateResultRDF::GetIsEmpty(bool* aIsEmpty)
57 : {
58 0 : *aIsEmpty = true;
59 :
60 0 : if (mNode) {
61 0 : nsXULTemplateQueryProcessorRDF* processor = GetProcessor();
62 0 : if (processor)
63 0 : return processor->CheckEmpty(mNode, aIsEmpty);
64 : }
65 :
66 0 : return NS_OK;
67 : }
68 :
69 : NS_IMETHODIMP
70 0 : nsXULTemplateResultRDF::GetMayProcessChildren(bool* aMayProcessChildren)
71 : {
72 : // RDF always allows recursion
73 0 : *aMayProcessChildren = true;
74 0 : return NS_OK;
75 : }
76 :
77 : NS_IMETHODIMP
78 0 : nsXULTemplateResultRDF::GetId(nsAString& aId)
79 : {
80 0 : if (! mNode)
81 0 : return NS_ERROR_FAILURE;
82 :
83 : const char* uri;
84 0 : mNode->GetValueConst(&uri);
85 :
86 0 : CopyUTF8toUTF16(uri, aId);
87 :
88 0 : return NS_OK;
89 : }
90 :
91 : NS_IMETHODIMP
92 0 : nsXULTemplateResultRDF::GetResource(nsIRDFResource** aResource)
93 : {
94 0 : *aResource = mNode;
95 0 : NS_IF_ADDREF(*aResource);
96 0 : return NS_OK;
97 : }
98 :
99 : NS_IMETHODIMP
100 0 : nsXULTemplateResultRDF::GetType(nsAString& aType)
101 : {
102 0 : aType.Truncate();
103 :
104 0 : nsresult rv = NS_OK;
105 :
106 0 : nsXULTemplateQueryProcessorRDF* processor = GetProcessor();
107 0 : if (processor) {
108 : bool found;
109 0 : rv = processor->CheckIsSeparator(mNode, &found);
110 0 : if (NS_SUCCEEDED(rv) && found)
111 0 : aType.AssignLiteral("separator");
112 : }
113 :
114 0 : return rv;
115 : }
116 :
117 : NS_IMETHODIMP
118 0 : nsXULTemplateResultRDF::GetBindingFor(nsIAtom* aVar, nsAString& aValue)
119 : {
120 0 : nsCOMPtr<nsIRDFNode> val;
121 0 : GetAssignment(aVar, getter_AddRefs(val));
122 :
123 0 : return nsXULContentUtils::GetTextForNode(val, aValue);
124 : }
125 :
126 : NS_IMETHODIMP
127 0 : nsXULTemplateResultRDF::GetBindingObjectFor(nsIAtom* aVar, nsISupports** aValue)
128 : {
129 0 : GetAssignment(aVar, (nsIRDFNode **)aValue);
130 :
131 0 : return NS_OK;
132 : }
133 :
134 : NS_IMETHODIMP
135 0 : nsXULTemplateResultRDF::RuleMatched(nsISupports* aQuery, nsIDOMNode* aRuleNode)
136 : {
137 : // when a rule matches, set the bindings that must be used.
138 0 : nsXULTemplateQueryProcessorRDF* processor = GetProcessor();
139 0 : if (processor) {
140 0 : RDFBindingSet* bindings = processor->GetBindingsForRule(aRuleNode);
141 0 : if (bindings) {
142 0 : nsresult rv = mBindingValues.SetBindingSet(bindings);
143 0 : if (NS_FAILED(rv))
144 0 : return rv;
145 :
146 0 : bindings->AddDependencies(mNode, this);
147 : }
148 : }
149 :
150 0 : return NS_OK;
151 : }
152 :
153 : NS_IMETHODIMP
154 0 : nsXULTemplateResultRDF::HasBeenRemoved()
155 : {
156 : // when a result is no longer used, clean up the dependencies and
157 : // memory elements that refer to it
158 0 : mBindingValues.RemoveDependencies(mNode, this);
159 :
160 0 : nsXULTemplateQueryProcessorRDF* processor = GetProcessor();
161 0 : if (processor)
162 0 : processor->RemoveMemoryElements(mInst, this);
163 :
164 0 : return NS_OK;
165 : }
166 :
167 :
168 : void
169 0 : nsXULTemplateResultRDF::GetAssignment(nsIAtom* aVar, nsIRDFNode** aValue)
170 : {
171 : // look up a variable in the assignments map
172 0 : *aValue = nullptr;
173 0 : mInst.mAssignments.GetAssignmentFor(aVar, aValue);
174 :
175 : // if not found, look up the variable in the bindings
176 0 : if (! *aValue)
177 0 : mBindingValues.GetAssignmentFor(this, aVar, aValue);
178 0 : }
179 :
180 :
181 : bool
182 0 : nsXULTemplateResultRDF::SyncAssignments(nsIRDFResource* aSubject,
183 : nsIRDFResource* aPredicate,
184 : nsIRDFNode* aTarget)
185 : {
186 : // synchronize the bindings when an assertion is added or removed
187 0 : RDFBindingSet* bindingset = mBindingValues.GetBindingSet();
188 0 : if (bindingset) {
189 0 : return bindingset->SyncAssignments(aSubject, aPredicate, aTarget,
190 0 : (aSubject == mNode) ? mQuery->GetMemberVariable() : nullptr,
191 0 : this, mBindingValues);
192 : }
193 :
194 0 : return false;
195 : }
196 :
197 : bool
198 0 : nsXULTemplateResultRDF::HasMemoryElement(const MemoryElement& aMemoryElement)
199 : {
200 0 : MemoryElementSet::ConstIterator last = mInst.mSupport.Last();
201 0 : for (MemoryElementSet::ConstIterator element = mInst.mSupport.First();
202 : element != last; ++element) {
203 0 : if ((*element).Equals(aMemoryElement))
204 0 : return true;
205 : }
206 :
207 0 : return false;
208 : }
|