nsXULTemplateResultRDF.cpp 5.3 KB

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