michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 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 "nsXULTemplateQueryProcessorXML.h" michael@0: #include "nsXULTemplateResultXML.h" michael@0: #include "nsXMLBinding.h" michael@0: michael@0: NS_IMPL_CYCLE_COLLECTING_NATIVE_ADDREF(nsXMLBindingSet) michael@0: NS_IMPL_CYCLE_COLLECTING_NATIVE_RELEASE(nsXMLBindingSet) michael@0: michael@0: NS_IMPL_CYCLE_COLLECTION_CLASS(nsXMLBindingSet) michael@0: michael@0: NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXMLBindingSet) michael@0: nsXMLBinding* binding = tmp->mFirst; michael@0: while (binding) { michael@0: binding->mExpr = nullptr; michael@0: binding = binding->mNext; michael@0: } michael@0: NS_IMPL_CYCLE_COLLECTION_UNLINK_END michael@0: michael@0: NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXMLBindingSet) michael@0: nsXMLBinding* binding = tmp->mFirst; michael@0: while (binding) { michael@0: NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "nsXMLBinding::mExpr"); michael@0: cb.NoteXPCOMChild(binding->mExpr); michael@0: binding = binding->mNext; michael@0: } michael@0: NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END michael@0: michael@0: NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsXMLBindingSet, AddRef) michael@0: NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsXMLBindingSet, Release) michael@0: michael@0: nsresult michael@0: nsXMLBindingSet::AddBinding(nsIAtom* aVar, nsIDOMXPathExpression* aExpr) michael@0: { michael@0: nsAutoPtr newbinding(new nsXMLBinding(aVar, aExpr)); michael@0: NS_ENSURE_TRUE(newbinding, NS_ERROR_OUT_OF_MEMORY); michael@0: michael@0: if (mFirst) { michael@0: nsXMLBinding* binding = mFirst; michael@0: michael@0: while (binding) { michael@0: // if the target variable is already used in a binding, ignore it michael@0: // since it won't be useful for anything michael@0: if (binding->mVar == aVar) michael@0: return NS_OK; michael@0: michael@0: // add the binding at the end of the list michael@0: if (!binding->mNext) { michael@0: binding->mNext = newbinding; michael@0: break; michael@0: } michael@0: michael@0: binding = binding->mNext; michael@0: } michael@0: } michael@0: else { michael@0: mFirst = newbinding; michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: int32_t michael@0: nsXMLBindingSet::LookupTargetIndex(nsIAtom* aTargetVariable, michael@0: nsXMLBinding** aBinding) michael@0: { michael@0: int32_t idx = 0; michael@0: nsXMLBinding* binding = mFirst; michael@0: michael@0: while (binding) { michael@0: if (binding->mVar == aTargetVariable) { michael@0: *aBinding = binding; michael@0: return idx; michael@0: } michael@0: idx++; michael@0: binding = binding->mNext; michael@0: } michael@0: michael@0: *aBinding = nullptr; michael@0: return -1; michael@0: } michael@0: michael@0: void michael@0: nsXMLBindingValues::GetAssignmentFor(nsXULTemplateResultXML* aResult, michael@0: nsXMLBinding* aBinding, michael@0: int32_t aIndex, michael@0: uint16_t aType, michael@0: nsIDOMXPathResult** aValue) michael@0: { michael@0: *aValue = mValues.SafeObjectAt(aIndex); michael@0: michael@0: if (!*aValue) { michael@0: nsCOMPtr contextNode; michael@0: aResult->GetNode(getter_AddRefs(contextNode)); michael@0: if (contextNode) { michael@0: nsCOMPtr resultsupports; michael@0: aBinding->mExpr->Evaluate(contextNode, aType, michael@0: nullptr, getter_AddRefs(resultsupports)); michael@0: michael@0: nsCOMPtr result = do_QueryInterface(resultsupports); michael@0: if (result && mValues.ReplaceObjectAt(result, aIndex)) michael@0: *aValue = result; michael@0: } michael@0: } michael@0: michael@0: NS_IF_ADDREF(*aValue); michael@0: } michael@0: michael@0: void michael@0: nsXMLBindingValues::GetNodeAssignmentFor(nsXULTemplateResultXML* aResult, michael@0: nsXMLBinding* aBinding, michael@0: int32_t aIndex, michael@0: nsIDOMNode** aNode) michael@0: { michael@0: nsCOMPtr result; michael@0: GetAssignmentFor(aResult, aBinding, aIndex, michael@0: nsIDOMXPathResult::FIRST_ORDERED_NODE_TYPE, michael@0: getter_AddRefs(result)); michael@0: michael@0: if (result) michael@0: result->GetSingleNodeValue(aNode); michael@0: else michael@0: *aNode = nullptr; michael@0: } michael@0: michael@0: void michael@0: nsXMLBindingValues::GetStringAssignmentFor(nsXULTemplateResultXML* aResult, michael@0: nsXMLBinding* aBinding, michael@0: int32_t aIndex, michael@0: nsAString& aValue) michael@0: { michael@0: nsCOMPtr result; michael@0: GetAssignmentFor(aResult, aBinding, aIndex, michael@0: nsIDOMXPathResult::STRING_TYPE, getter_AddRefs(result)); michael@0: michael@0: if (result) michael@0: result->GetStringValue(aValue); michael@0: else michael@0: aValue.Truncate(); michael@0: }