1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/xul/templates/src/nsXULTemplateResultXML.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,204 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 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 "nsIServiceManager.h" 1.10 +#include "nsIDOMNode.h" 1.11 +#include "nsIDOMElement.h" 1.12 +#include "nsIContent.h" 1.13 + 1.14 +#include "nsIRDFService.h" 1.15 + 1.16 +#include "nsXULTemplateResultXML.h" 1.17 +#include "nsXMLBinding.h" 1.18 + 1.19 +static uint32_t sTemplateId = 0; 1.20 + 1.21 +NS_IMPL_ISUPPORTS(nsXULTemplateResultXML, nsIXULTemplateResult) 1.22 + 1.23 +nsXULTemplateResultXML::nsXULTemplateResultXML(nsXMLQuery* aQuery, 1.24 + nsIDOMNode* aNode, 1.25 + nsXMLBindingSet* aBindings) 1.26 + : mQuery(aQuery), mNode(aNode) 1.27 +{ 1.28 + nsCOMPtr<nsIContent> content = do_QueryInterface(mNode); 1.29 + 1.30 + // If the node has an id, create the uri from it. Otherwise, there isn't 1.31 + // anything to identify the node with so just use a somewhat random number. 1.32 + nsCOMPtr<nsIAtom> id = content->GetID(); 1.33 + if (id) { 1.34 + nsCOMPtr<nsIURI> uri = content->GetBaseURI(); 1.35 + nsAutoCString spec; 1.36 + uri->GetSpec(spec); 1.37 + 1.38 + mId = NS_ConvertUTF8toUTF16(spec); 1.39 + 1.40 + nsAutoString idstr; 1.41 + id->ToString(idstr); 1.42 + mId += NS_LITERAL_STRING("#") + idstr; 1.43 + } 1.44 + else { 1.45 + nsAutoString rowid(NS_LITERAL_STRING("row")); 1.46 + rowid.AppendInt(++sTemplateId); 1.47 + mId.Assign(rowid); 1.48 + } 1.49 + 1.50 + if (aBindings) 1.51 + mRequiredValues.SetBindingSet(aBindings); 1.52 +} 1.53 + 1.54 +NS_IMETHODIMP 1.55 +nsXULTemplateResultXML::GetIsContainer(bool* aIsContainer) 1.56 +{ 1.57 + // a node is considered a container if it has children 1.58 + if (mNode) 1.59 + mNode->HasChildNodes(aIsContainer); 1.60 + else 1.61 + *aIsContainer = false; 1.62 + return NS_OK; 1.63 +} 1.64 + 1.65 +NS_IMETHODIMP 1.66 +nsXULTemplateResultXML::GetIsEmpty(bool* aIsEmpty) 1.67 +{ 1.68 + // a node is considered empty if it has no elements as children 1.69 + nsCOMPtr<nsIContent> content = do_QueryInterface(mNode); 1.70 + if (content) { 1.71 + for (nsIContent* child = content->GetFirstChild(); 1.72 + child; 1.73 + child = child->GetNextSibling()) { 1.74 + if (child->IsElement()) { 1.75 + *aIsEmpty = false; 1.76 + return NS_OK; 1.77 + } 1.78 + } 1.79 + } 1.80 + 1.81 + *aIsEmpty = true; 1.82 + return NS_OK; 1.83 +} 1.84 + 1.85 +NS_IMETHODIMP 1.86 +nsXULTemplateResultXML::GetMayProcessChildren(bool* aMayProcessChildren) 1.87 +{ 1.88 + *aMayProcessChildren = true; 1.89 + return NS_OK; 1.90 +} 1.91 + 1.92 +NS_IMETHODIMP 1.93 +nsXULTemplateResultXML::GetId(nsAString& aId) 1.94 +{ 1.95 + aId = mId; 1.96 + return NS_OK; 1.97 +} 1.98 + 1.99 +NS_IMETHODIMP 1.100 +nsXULTemplateResultXML::GetResource(nsIRDFResource** aResource) 1.101 +{ 1.102 + *aResource = nullptr; 1.103 + return NS_OK; 1.104 +} 1.105 + 1.106 +NS_IMETHODIMP 1.107 +nsXULTemplateResultXML::GetType(nsAString& aType) 1.108 +{ 1.109 + aType.Truncate(); 1.110 + return NS_OK; 1.111 +} 1.112 + 1.113 +NS_IMETHODIMP 1.114 +nsXULTemplateResultXML::GetBindingFor(nsIAtom* aVar, nsAString& aValue) 1.115 +{ 1.116 + NS_ENSURE_ARG_POINTER(aVar); 1.117 + 1.118 + // get the position of the atom in the variables table 1.119 + nsXMLBinding* binding; 1.120 + 1.121 + int32_t idx = mRequiredValues.LookupTargetIndex(aVar, &binding); 1.122 + if (idx >= 0) { 1.123 + mRequiredValues.GetStringAssignmentFor(this, binding, idx, aValue); 1.124 + return NS_OK; 1.125 + } 1.126 + 1.127 + idx = mOptionalValues.LookupTargetIndex(aVar, &binding); 1.128 + if (idx >= 0) { 1.129 + mOptionalValues.GetStringAssignmentFor(this, binding, idx, aValue); 1.130 + return NS_OK; 1.131 + } 1.132 + 1.133 + // if the variable is not bound, just use the variable name as the name of 1.134 + // an attribute to retrieve 1.135 + nsAutoString attr; 1.136 + aVar->ToString(attr); 1.137 + 1.138 + if (attr.Length() > 1) { 1.139 + nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mNode); 1.140 + if (element) 1.141 + return element->GetAttribute(Substring(attr, 1), aValue); 1.142 + } 1.143 + 1.144 + aValue.Truncate(); 1.145 + return NS_OK; 1.146 +} 1.147 + 1.148 +NS_IMETHODIMP 1.149 +nsXULTemplateResultXML::GetBindingObjectFor(nsIAtom* aVar, nsISupports** aValue) 1.150 +{ 1.151 + NS_ENSURE_ARG_POINTER(aVar); 1.152 + 1.153 + nsXMLBinding* binding; 1.154 + nsCOMPtr<nsIDOMNode> node; 1.155 + 1.156 + if (mQuery && aVar == mQuery->GetMemberVariable()) { 1.157 + node = mNode; 1.158 + } 1.159 + else { 1.160 + int32_t idx = mRequiredValues.LookupTargetIndex(aVar, &binding); 1.161 + if (idx > 0) { 1.162 + mRequiredValues.GetNodeAssignmentFor(this, binding, idx, 1.163 + getter_AddRefs(node)); 1.164 + } 1.165 + else { 1.166 + idx = mOptionalValues.LookupTargetIndex(aVar, &binding); 1.167 + if (idx > 0) { 1.168 + mOptionalValues.GetNodeAssignmentFor(this, binding, idx, 1.169 + getter_AddRefs(node)); 1.170 + } 1.171 + } 1.172 + } 1.173 + 1.174 + *aValue = node; 1.175 + NS_IF_ADDREF(*aValue); 1.176 + return NS_OK; 1.177 +} 1.178 + 1.179 +NS_IMETHODIMP 1.180 +nsXULTemplateResultXML::RuleMatched(nsISupports* aQueryNode, 1.181 + nsIDOMNode* aRuleNode) 1.182 +{ 1.183 + // when a rule matches, set the bindings that must be used. 1.184 + nsXULTemplateQueryProcessorXML* processor = mQuery ? mQuery->Processor() : 1.185 + nullptr; 1.186 + if (processor) { 1.187 + nsXMLBindingSet* bindings = 1.188 + processor->GetOptionalBindingsForRule(aRuleNode); 1.189 + if (bindings) 1.190 + mOptionalValues.SetBindingSet(bindings); 1.191 + } 1.192 + 1.193 + return NS_OK; 1.194 +} 1.195 + 1.196 +NS_IMETHODIMP 1.197 +nsXULTemplateResultXML::HasBeenRemoved() 1.198 +{ 1.199 + return NS_OK; 1.200 +} 1.201 + 1.202 +void 1.203 +nsXULTemplateResultXML::GetNode(nsIDOMNode** aNode) 1.204 +{ 1.205 + *aNode = mNode; 1.206 + NS_IF_ADDREF(*aNode); 1.207 +}