dom/xslt/xpath/XPathEvaluator.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "mozilla/dom/XPathEvaluator.h"
michael@0 7 #include "nsCOMPtr.h"
michael@0 8 #include "nsIAtom.h"
michael@0 9 #include "nsXPathExpression.h"
michael@0 10 #include "nsXPathNSResolver.h"
michael@0 11 #include "nsXPathResult.h"
michael@0 12 #include "nsContentCID.h"
michael@0 13 #include "txExpr.h"
michael@0 14 #include "txExprParser.h"
michael@0 15 #include "nsError.h"
michael@0 16 #include "txURIUtils.h"
michael@0 17 #include "nsIDocument.h"
michael@0 18 #include "nsIDOMDocument.h"
michael@0 19 #include "nsDOMString.h"
michael@0 20 #include "nsNameSpaceManager.h"
michael@0 21 #include "nsContentUtils.h"
michael@0 22 #include "mozilla/dom/XPathEvaluatorBinding.h"
michael@0 23
michael@0 24 extern nsresult
michael@0 25 TX_ResolveFunctionCallXPCOM(const nsCString &aContractID, int32_t aNamespaceID,
michael@0 26 nsIAtom *aName, nsISupports *aState,
michael@0 27 FunctionCall **aFunction);
michael@0 28
michael@0 29 namespace mozilla {
michael@0 30 namespace dom {
michael@0 31
michael@0 32 // txIParseContext implementation
michael@0 33 class XPathEvaluatorParseContext : public txIParseContext
michael@0 34 {
michael@0 35 public:
michael@0 36 XPathEvaluatorParseContext(nsIDOMXPathNSResolver* aResolver,
michael@0 37 bool aIsCaseSensitive)
michael@0 38 : mResolver(aResolver),
michael@0 39 mLastError(NS_OK),
michael@0 40 mIsCaseSensitive(aIsCaseSensitive)
michael@0 41 {
michael@0 42 }
michael@0 43
michael@0 44 nsresult getError()
michael@0 45 {
michael@0 46 return mLastError;
michael@0 47 }
michael@0 48
michael@0 49 nsresult resolveNamespacePrefix(nsIAtom* aPrefix, int32_t& aID);
michael@0 50 nsresult resolveFunctionCall(nsIAtom* aName, int32_t aID,
michael@0 51 FunctionCall** aFunction);
michael@0 52 bool caseInsensitiveNameTests();
michael@0 53 void SetErrorOffset(uint32_t aOffset);
michael@0 54
michael@0 55 private:
michael@0 56 nsIDOMXPathNSResolver* mResolver;
michael@0 57 nsresult mLastError;
michael@0 58 bool mIsCaseSensitive;
michael@0 59 };
michael@0 60
michael@0 61 NS_IMPL_ISUPPORTS(XPathEvaluator, nsIDOMXPathEvaluator)
michael@0 62
michael@0 63 XPathEvaluator::XPathEvaluator(nsIDocument* aDocument)
michael@0 64 : mDocument(do_GetWeakReference(aDocument))
michael@0 65 {
michael@0 66 }
michael@0 67
michael@0 68 NS_IMETHODIMP
michael@0 69 XPathEvaluator::CreateNSResolver(nsIDOMNode *aNodeResolver,
michael@0 70 nsIDOMXPathNSResolver **aResult)
michael@0 71 {
michael@0 72 NS_ENSURE_ARG(aNodeResolver);
michael@0 73 if (!nsContentUtils::CanCallerAccess(aNodeResolver))
michael@0 74 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 75
michael@0 76 *aResult = new nsXPathNSResolver(aNodeResolver);
michael@0 77 NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
michael@0 78
michael@0 79 NS_ADDREF(*aResult);
michael@0 80 return NS_OK;
michael@0 81 }
michael@0 82
michael@0 83 NS_IMETHODIMP
michael@0 84 XPathEvaluator::Evaluate(const nsAString & aExpression,
michael@0 85 nsIDOMNode *aContextNode,
michael@0 86 nsIDOMXPathNSResolver *aResolver,
michael@0 87 uint16_t aType,
michael@0 88 nsISupports *aInResult,
michael@0 89 nsISupports **aResult)
michael@0 90 {
michael@0 91 nsCOMPtr<nsIDOMXPathExpression> expression;
michael@0 92 nsresult rv = CreateExpression(aExpression, aResolver,
michael@0 93 getter_AddRefs(expression));
michael@0 94 NS_ENSURE_SUCCESS(rv, rv);
michael@0 95
michael@0 96 return expression->Evaluate(aContextNode, aType, aInResult, aResult);
michael@0 97 }
michael@0 98
michael@0 99
michael@0 100 NS_IMETHODIMP
michael@0 101 XPathEvaluator::CreateExpression(const nsAString & aExpression,
michael@0 102 nsIDOMXPathNSResolver *aResolver,
michael@0 103 nsIDOMXPathExpression **aResult)
michael@0 104 {
michael@0 105 nsresult rv;
michael@0 106 if (!mRecycler) {
michael@0 107 nsRefPtr<txResultRecycler> recycler = new txResultRecycler;
michael@0 108 NS_ENSURE_TRUE(recycler, NS_ERROR_OUT_OF_MEMORY);
michael@0 109
michael@0 110 rv = recycler->init();
michael@0 111 NS_ENSURE_SUCCESS(rv, rv);
michael@0 112
michael@0 113 mRecycler = recycler;
michael@0 114 }
michael@0 115
michael@0 116 nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocument);
michael@0 117 XPathEvaluatorParseContext pContext(aResolver, !(doc && doc->IsHTML()));
michael@0 118
michael@0 119 nsAutoPtr<Expr> expression;
michael@0 120 rv = txExprParser::createExpr(PromiseFlatString(aExpression), &pContext,
michael@0 121 getter_Transfers(expression));
michael@0 122 if (NS_FAILED(rv)) {
michael@0 123 if (rv == NS_ERROR_DOM_NAMESPACE_ERR) {
michael@0 124 return NS_ERROR_DOM_NAMESPACE_ERR;
michael@0 125 }
michael@0 126
michael@0 127 return NS_ERROR_DOM_INVALID_EXPRESSION_ERR;
michael@0 128 }
michael@0 129
michael@0 130 nsCOMPtr<nsIDOMDocument> document = do_QueryReferent(mDocument);
michael@0 131
michael@0 132 *aResult = new nsXPathExpression(expression, mRecycler, document);
michael@0 133 if (!*aResult) {
michael@0 134 return NS_ERROR_OUT_OF_MEMORY;
michael@0 135 }
michael@0 136
michael@0 137 NS_ADDREF(*aResult);
michael@0 138 return NS_OK;
michael@0 139 }
michael@0 140
michael@0 141 JSObject*
michael@0 142 XPathEvaluator::WrapObject(JSContext* aCx)
michael@0 143 {
michael@0 144 return dom::XPathEvaluatorBinding::Wrap(aCx, this);
michael@0 145 }
michael@0 146
michael@0 147 /* static */
michael@0 148 already_AddRefed<XPathEvaluator>
michael@0 149 XPathEvaluator::Constructor(const GlobalObject& aGlobal,
michael@0 150 ErrorResult& rv)
michael@0 151 {
michael@0 152 nsRefPtr<XPathEvaluator> newObj = new XPathEvaluator(nullptr);
michael@0 153 return newObj.forget();
michael@0 154 }
michael@0 155
michael@0 156 already_AddRefed<nsIDOMXPathExpression>
michael@0 157 XPathEvaluator::CreateExpression(const nsAString& aExpression,
michael@0 158 nsIDOMXPathNSResolver* aResolver,
michael@0 159 ErrorResult& rv)
michael@0 160 {
michael@0 161 nsCOMPtr<nsIDOMXPathExpression> expr;
michael@0 162 rv = CreateExpression(aExpression, aResolver, getter_AddRefs(expr));
michael@0 163 return expr.forget();
michael@0 164 }
michael@0 165
michael@0 166 already_AddRefed<nsIDOMXPathNSResolver>
michael@0 167 XPathEvaluator::CreateNSResolver(nsINode* aNodeResolver,
michael@0 168 ErrorResult& rv)
michael@0 169 {
michael@0 170 nsCOMPtr<nsIDOMNode> nodeResolver = do_QueryInterface(aNodeResolver);
michael@0 171 nsCOMPtr<nsIDOMXPathNSResolver> res;
michael@0 172 rv = CreateNSResolver(nodeResolver, getter_AddRefs(res));
michael@0 173 return res.forget();
michael@0 174 }
michael@0 175
michael@0 176 already_AddRefed<nsISupports>
michael@0 177 XPathEvaluator::Evaluate(const nsAString& aExpression, nsINode* aContextNode,
michael@0 178 nsIDOMXPathNSResolver* aResolver, uint16_t aType,
michael@0 179 nsISupports* aResult, ErrorResult& rv)
michael@0 180 {
michael@0 181 nsCOMPtr<nsIDOMNode> contextNode = do_QueryInterface(aContextNode);
michael@0 182 nsCOMPtr<nsISupports> res;
michael@0 183 rv = Evaluate(aExpression, contextNode, aResolver, aType,
michael@0 184 aResult, getter_AddRefs(res));
michael@0 185 return res.forget();
michael@0 186 }
michael@0 187
michael@0 188
michael@0 189 /*
michael@0 190 * Implementation of txIParseContext private to XPathEvaluator, based on a
michael@0 191 * nsIDOMXPathNSResolver
michael@0 192 */
michael@0 193
michael@0 194 nsresult XPathEvaluatorParseContext::resolveNamespacePrefix
michael@0 195 (nsIAtom* aPrefix, int32_t& aID)
michael@0 196 {
michael@0 197 aID = kNameSpaceID_Unknown;
michael@0 198
michael@0 199 if (!mResolver) {
michael@0 200 return NS_ERROR_DOM_NAMESPACE_ERR;
michael@0 201 }
michael@0 202
michael@0 203 nsAutoString prefix;
michael@0 204 if (aPrefix) {
michael@0 205 aPrefix->ToString(prefix);
michael@0 206 }
michael@0 207
michael@0 208 nsVoidableString ns;
michael@0 209 nsresult rv = mResolver->LookupNamespaceURI(prefix, ns);
michael@0 210 NS_ENSURE_SUCCESS(rv, rv);
michael@0 211
michael@0 212 if (DOMStringIsNull(ns)) {
michael@0 213 return NS_ERROR_DOM_NAMESPACE_ERR;
michael@0 214 }
michael@0 215
michael@0 216 if (ns.IsEmpty()) {
michael@0 217 aID = kNameSpaceID_None;
michael@0 218
michael@0 219 return NS_OK;
michael@0 220 }
michael@0 221
michael@0 222 // get the namespaceID for the URI
michael@0 223 return nsContentUtils::NameSpaceManager()->RegisterNameSpace(ns, aID);
michael@0 224 }
michael@0 225
michael@0 226 nsresult
michael@0 227 XPathEvaluatorParseContext::resolveFunctionCall(nsIAtom* aName,
michael@0 228 int32_t aID,
michael@0 229 FunctionCall** aFn)
michael@0 230 {
michael@0 231 return NS_ERROR_XPATH_UNKNOWN_FUNCTION;
michael@0 232 }
michael@0 233
michael@0 234 bool XPathEvaluatorParseContext::caseInsensitiveNameTests()
michael@0 235 {
michael@0 236 return !mIsCaseSensitive;
michael@0 237 }
michael@0 238
michael@0 239 void
michael@0 240 XPathEvaluatorParseContext::SetErrorOffset(uint32_t aOffset)
michael@0 241 {
michael@0 242 }
michael@0 243
michael@0 244 } // namespace dom
michael@0 245 } // namespace mozilla

mercurial