1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/xul/templates/src/nsXMLBinding.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,143 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "nsXULTemplateQueryProcessorXML.h" 1.10 +#include "nsXULTemplateResultXML.h" 1.11 +#include "nsXMLBinding.h" 1.12 + 1.13 +NS_IMPL_CYCLE_COLLECTING_NATIVE_ADDREF(nsXMLBindingSet) 1.14 +NS_IMPL_CYCLE_COLLECTING_NATIVE_RELEASE(nsXMLBindingSet) 1.15 + 1.16 +NS_IMPL_CYCLE_COLLECTION_CLASS(nsXMLBindingSet) 1.17 + 1.18 +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXMLBindingSet) 1.19 + nsXMLBinding* binding = tmp->mFirst; 1.20 + while (binding) { 1.21 + binding->mExpr = nullptr; 1.22 + binding = binding->mNext; 1.23 + } 1.24 +NS_IMPL_CYCLE_COLLECTION_UNLINK_END 1.25 + 1.26 +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXMLBindingSet) 1.27 + nsXMLBinding* binding = tmp->mFirst; 1.28 + while (binding) { 1.29 + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "nsXMLBinding::mExpr"); 1.30 + cb.NoteXPCOMChild(binding->mExpr); 1.31 + binding = binding->mNext; 1.32 + } 1.33 +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END 1.34 + 1.35 +NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsXMLBindingSet, AddRef) 1.36 +NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsXMLBindingSet, Release) 1.37 + 1.38 +nsresult 1.39 +nsXMLBindingSet::AddBinding(nsIAtom* aVar, nsIDOMXPathExpression* aExpr) 1.40 +{ 1.41 + nsAutoPtr<nsXMLBinding> newbinding(new nsXMLBinding(aVar, aExpr)); 1.42 + NS_ENSURE_TRUE(newbinding, NS_ERROR_OUT_OF_MEMORY); 1.43 + 1.44 + if (mFirst) { 1.45 + nsXMLBinding* binding = mFirst; 1.46 + 1.47 + while (binding) { 1.48 + // if the target variable is already used in a binding, ignore it 1.49 + // since it won't be useful for anything 1.50 + if (binding->mVar == aVar) 1.51 + return NS_OK; 1.52 + 1.53 + // add the binding at the end of the list 1.54 + if (!binding->mNext) { 1.55 + binding->mNext = newbinding; 1.56 + break; 1.57 + } 1.58 + 1.59 + binding = binding->mNext; 1.60 + } 1.61 + } 1.62 + else { 1.63 + mFirst = newbinding; 1.64 + } 1.65 + 1.66 + return NS_OK; 1.67 +} 1.68 + 1.69 +int32_t 1.70 +nsXMLBindingSet::LookupTargetIndex(nsIAtom* aTargetVariable, 1.71 + nsXMLBinding** aBinding) 1.72 +{ 1.73 + int32_t idx = 0; 1.74 + nsXMLBinding* binding = mFirst; 1.75 + 1.76 + while (binding) { 1.77 + if (binding->mVar == aTargetVariable) { 1.78 + *aBinding = binding; 1.79 + return idx; 1.80 + } 1.81 + idx++; 1.82 + binding = binding->mNext; 1.83 + } 1.84 + 1.85 + *aBinding = nullptr; 1.86 + return -1; 1.87 +} 1.88 + 1.89 +void 1.90 +nsXMLBindingValues::GetAssignmentFor(nsXULTemplateResultXML* aResult, 1.91 + nsXMLBinding* aBinding, 1.92 + int32_t aIndex, 1.93 + uint16_t aType, 1.94 + nsIDOMXPathResult** aValue) 1.95 +{ 1.96 + *aValue = mValues.SafeObjectAt(aIndex); 1.97 + 1.98 + if (!*aValue) { 1.99 + nsCOMPtr<nsIDOMNode> contextNode; 1.100 + aResult->GetNode(getter_AddRefs(contextNode)); 1.101 + if (contextNode) { 1.102 + nsCOMPtr<nsISupports> resultsupports; 1.103 + aBinding->mExpr->Evaluate(contextNode, aType, 1.104 + nullptr, getter_AddRefs(resultsupports)); 1.105 + 1.106 + nsCOMPtr<nsIDOMXPathResult> result = do_QueryInterface(resultsupports); 1.107 + if (result && mValues.ReplaceObjectAt(result, aIndex)) 1.108 + *aValue = result; 1.109 + } 1.110 + } 1.111 + 1.112 + NS_IF_ADDREF(*aValue); 1.113 +} 1.114 + 1.115 +void 1.116 +nsXMLBindingValues::GetNodeAssignmentFor(nsXULTemplateResultXML* aResult, 1.117 + nsXMLBinding* aBinding, 1.118 + int32_t aIndex, 1.119 + nsIDOMNode** aNode) 1.120 +{ 1.121 + nsCOMPtr<nsIDOMXPathResult> result; 1.122 + GetAssignmentFor(aResult, aBinding, aIndex, 1.123 + nsIDOMXPathResult::FIRST_ORDERED_NODE_TYPE, 1.124 + getter_AddRefs(result)); 1.125 + 1.126 + if (result) 1.127 + result->GetSingleNodeValue(aNode); 1.128 + else 1.129 + *aNode = nullptr; 1.130 +} 1.131 + 1.132 +void 1.133 +nsXMLBindingValues::GetStringAssignmentFor(nsXULTemplateResultXML* aResult, 1.134 + nsXMLBinding* aBinding, 1.135 + int32_t aIndex, 1.136 + nsAString& aValue) 1.137 +{ 1.138 + nsCOMPtr<nsIDOMXPathResult> result; 1.139 + GetAssignmentFor(aResult, aBinding, aIndex, 1.140 + nsIDOMXPathResult::STRING_TYPE, getter_AddRefs(result)); 1.141 + 1.142 + if (result) 1.143 + result->GetStringValue(aValue); 1.144 + else 1.145 + aValue.Truncate(); 1.146 +}