michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsXULTemplateResultRDF.h" michael@0: #include "nsXULContentUtils.h" michael@0: michael@0: // XXXndeakin for some reason, making this class have classinfo breaks trees. michael@0: //#include "nsIDOMClassInfo.h" michael@0: michael@0: NS_IMPL_CYCLE_COLLECTION(nsXULTemplateResultRDF, mQuery) michael@0: michael@0: NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXULTemplateResultRDF) michael@0: NS_INTERFACE_MAP_ENTRY(nsIXULTemplateResult) michael@0: NS_INTERFACE_MAP_ENTRY(nsISupports) michael@0: NS_INTERFACE_MAP_END michael@0: michael@0: NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXULTemplateResultRDF) michael@0: NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXULTemplateResultRDF) michael@0: michael@0: nsXULTemplateResultRDF::nsXULTemplateResultRDF(nsIRDFResource* aNode) michael@0: : mQuery(nullptr), michael@0: mNode(aNode) michael@0: { michael@0: } michael@0: michael@0: nsXULTemplateResultRDF::nsXULTemplateResultRDF(nsRDFQuery* aQuery, michael@0: const Instantiation& aInst, michael@0: nsIRDFResource *aNode) michael@0: : mQuery(aQuery), michael@0: mNode(aNode), michael@0: mInst(aInst) michael@0: { michael@0: } michael@0: michael@0: nsXULTemplateResultRDF::~nsXULTemplateResultRDF() michael@0: { michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsXULTemplateResultRDF::GetIsContainer(bool* aIsContainer) michael@0: { michael@0: *aIsContainer = false; michael@0: michael@0: if (mNode) { michael@0: nsXULTemplateQueryProcessorRDF* processor = GetProcessor(); michael@0: if (processor) michael@0: return processor->CheckContainer(mNode, aIsContainer); michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsXULTemplateResultRDF::GetIsEmpty(bool* aIsEmpty) michael@0: { michael@0: *aIsEmpty = true; michael@0: michael@0: if (mNode) { michael@0: nsXULTemplateQueryProcessorRDF* processor = GetProcessor(); michael@0: if (processor) michael@0: return processor->CheckEmpty(mNode, aIsEmpty); michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsXULTemplateResultRDF::GetMayProcessChildren(bool* aMayProcessChildren) michael@0: { michael@0: // RDF always allows recursion michael@0: *aMayProcessChildren = true; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsXULTemplateResultRDF::GetId(nsAString& aId) michael@0: { michael@0: if (! mNode) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: const char* uri; michael@0: mNode->GetValueConst(&uri); michael@0: michael@0: CopyUTF8toUTF16(uri, aId); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsXULTemplateResultRDF::GetResource(nsIRDFResource** aResource) michael@0: { michael@0: *aResource = mNode; michael@0: NS_IF_ADDREF(*aResource); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsXULTemplateResultRDF::GetType(nsAString& aType) michael@0: { michael@0: aType.Truncate(); michael@0: michael@0: nsresult rv = NS_OK; michael@0: michael@0: nsXULTemplateQueryProcessorRDF* processor = GetProcessor(); michael@0: if (processor) { michael@0: bool found; michael@0: rv = processor->CheckIsSeparator(mNode, &found); michael@0: if (NS_SUCCEEDED(rv) && found) michael@0: aType.AssignLiteral("separator"); michael@0: } michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsXULTemplateResultRDF::GetBindingFor(nsIAtom* aVar, nsAString& aValue) michael@0: { michael@0: nsCOMPtr val; michael@0: GetAssignment(aVar, getter_AddRefs(val)); michael@0: michael@0: return nsXULContentUtils::GetTextForNode(val, aValue); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsXULTemplateResultRDF::GetBindingObjectFor(nsIAtom* aVar, nsISupports** aValue) michael@0: { michael@0: GetAssignment(aVar, (nsIRDFNode **)aValue); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsXULTemplateResultRDF::RuleMatched(nsISupports* aQuery, nsIDOMNode* aRuleNode) michael@0: { michael@0: // when a rule matches, set the bindings that must be used. michael@0: nsXULTemplateQueryProcessorRDF* processor = GetProcessor(); michael@0: if (processor) { michael@0: RDFBindingSet* bindings = processor->GetBindingsForRule(aRuleNode); michael@0: if (bindings) { michael@0: nsresult rv = mBindingValues.SetBindingSet(bindings); michael@0: if (NS_FAILED(rv)) michael@0: return rv; michael@0: michael@0: bindings->AddDependencies(mNode, this); michael@0: } michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsXULTemplateResultRDF::HasBeenRemoved() michael@0: { michael@0: // when a result is no longer used, clean up the dependencies and michael@0: // memory elements that refer to it michael@0: mBindingValues.RemoveDependencies(mNode, this); michael@0: michael@0: nsXULTemplateQueryProcessorRDF* processor = GetProcessor(); michael@0: if (processor) michael@0: processor->RemoveMemoryElements(mInst, this); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: michael@0: void michael@0: nsXULTemplateResultRDF::GetAssignment(nsIAtom* aVar, nsIRDFNode** aValue) michael@0: { michael@0: // look up a variable in the assignments map michael@0: *aValue = nullptr; michael@0: mInst.mAssignments.GetAssignmentFor(aVar, aValue); michael@0: michael@0: // if not found, look up the variable in the bindings michael@0: if (! *aValue) michael@0: mBindingValues.GetAssignmentFor(this, aVar, aValue); michael@0: } michael@0: michael@0: michael@0: bool michael@0: nsXULTemplateResultRDF::SyncAssignments(nsIRDFResource* aSubject, michael@0: nsIRDFResource* aPredicate, michael@0: nsIRDFNode* aTarget) michael@0: { michael@0: // synchronize the bindings when an assertion is added or removed michael@0: RDFBindingSet* bindingset = mBindingValues.GetBindingSet(); michael@0: if (bindingset) { michael@0: return bindingset->SyncAssignments(aSubject, aPredicate, aTarget, michael@0: (aSubject == mNode) ? mQuery->GetMemberVariable() : nullptr, michael@0: this, mBindingValues); michael@0: } michael@0: michael@0: return false; michael@0: } michael@0: michael@0: bool michael@0: nsXULTemplateResultRDF::HasMemoryElement(const MemoryElement& aMemoryElement) michael@0: { michael@0: MemoryElementSet::ConstIterator last = mInst.mSupport.Last(); michael@0: for (MemoryElementSet::ConstIterator element = mInst.mSupport.First(); michael@0: element != last; ++element) { michael@0: if ((*element).Equals(aMemoryElement)) michael@0: return true; michael@0: } michael@0: michael@0: return false; michael@0: }