content/xul/templates/src/nsXMLBinding.cpp

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:b603780263b4
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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 "nsXULTemplateQueryProcessorXML.h"
7 #include "nsXULTemplateResultXML.h"
8 #include "nsXMLBinding.h"
9
10 NS_IMPL_CYCLE_COLLECTING_NATIVE_ADDREF(nsXMLBindingSet)
11 NS_IMPL_CYCLE_COLLECTING_NATIVE_RELEASE(nsXMLBindingSet)
12
13 NS_IMPL_CYCLE_COLLECTION_CLASS(nsXMLBindingSet)
14
15 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXMLBindingSet)
16 nsXMLBinding* binding = tmp->mFirst;
17 while (binding) {
18 binding->mExpr = nullptr;
19 binding = binding->mNext;
20 }
21 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
22
23 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXMLBindingSet)
24 nsXMLBinding* binding = tmp->mFirst;
25 while (binding) {
26 NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "nsXMLBinding::mExpr");
27 cb.NoteXPCOMChild(binding->mExpr);
28 binding = binding->mNext;
29 }
30 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
31
32 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsXMLBindingSet, AddRef)
33 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsXMLBindingSet, Release)
34
35 nsresult
36 nsXMLBindingSet::AddBinding(nsIAtom* aVar, nsIDOMXPathExpression* aExpr)
37 {
38 nsAutoPtr<nsXMLBinding> newbinding(new nsXMLBinding(aVar, aExpr));
39 NS_ENSURE_TRUE(newbinding, NS_ERROR_OUT_OF_MEMORY);
40
41 if (mFirst) {
42 nsXMLBinding* binding = mFirst;
43
44 while (binding) {
45 // if the target variable is already used in a binding, ignore it
46 // since it won't be useful for anything
47 if (binding->mVar == aVar)
48 return NS_OK;
49
50 // add the binding at the end of the list
51 if (!binding->mNext) {
52 binding->mNext = newbinding;
53 break;
54 }
55
56 binding = binding->mNext;
57 }
58 }
59 else {
60 mFirst = newbinding;
61 }
62
63 return NS_OK;
64 }
65
66 int32_t
67 nsXMLBindingSet::LookupTargetIndex(nsIAtom* aTargetVariable,
68 nsXMLBinding** aBinding)
69 {
70 int32_t idx = 0;
71 nsXMLBinding* binding = mFirst;
72
73 while (binding) {
74 if (binding->mVar == aTargetVariable) {
75 *aBinding = binding;
76 return idx;
77 }
78 idx++;
79 binding = binding->mNext;
80 }
81
82 *aBinding = nullptr;
83 return -1;
84 }
85
86 void
87 nsXMLBindingValues::GetAssignmentFor(nsXULTemplateResultXML* aResult,
88 nsXMLBinding* aBinding,
89 int32_t aIndex,
90 uint16_t aType,
91 nsIDOMXPathResult** aValue)
92 {
93 *aValue = mValues.SafeObjectAt(aIndex);
94
95 if (!*aValue) {
96 nsCOMPtr<nsIDOMNode> contextNode;
97 aResult->GetNode(getter_AddRefs(contextNode));
98 if (contextNode) {
99 nsCOMPtr<nsISupports> resultsupports;
100 aBinding->mExpr->Evaluate(contextNode, aType,
101 nullptr, getter_AddRefs(resultsupports));
102
103 nsCOMPtr<nsIDOMXPathResult> result = do_QueryInterface(resultsupports);
104 if (result && mValues.ReplaceObjectAt(result, aIndex))
105 *aValue = result;
106 }
107 }
108
109 NS_IF_ADDREF(*aValue);
110 }
111
112 void
113 nsXMLBindingValues::GetNodeAssignmentFor(nsXULTemplateResultXML* aResult,
114 nsXMLBinding* aBinding,
115 int32_t aIndex,
116 nsIDOMNode** aNode)
117 {
118 nsCOMPtr<nsIDOMXPathResult> result;
119 GetAssignmentFor(aResult, aBinding, aIndex,
120 nsIDOMXPathResult::FIRST_ORDERED_NODE_TYPE,
121 getter_AddRefs(result));
122
123 if (result)
124 result->GetSingleNodeValue(aNode);
125 else
126 *aNode = nullptr;
127 }
128
129 void
130 nsXMLBindingValues::GetStringAssignmentFor(nsXULTemplateResultXML* aResult,
131 nsXMLBinding* aBinding,
132 int32_t aIndex,
133 nsAString& aValue)
134 {
135 nsCOMPtr<nsIDOMXPathResult> result;
136 GetAssignmentFor(aResult, aBinding, aIndex,
137 nsIDOMXPathResult::STRING_TYPE, getter_AddRefs(result));
138
139 if (result)
140 result->GetStringValue(aValue);
141 else
142 aValue.Truncate();
143 }

mercurial